3

私は4つのモデルを持っています:

  • ユーザー
  • アワード
  • バッジ
  • ゲームウィーク

協会は次のとおりです。

  • ユーザーは多くの賞を受賞しています。
  • 特典はユーザーのものです。
  • バッジには多くの賞があります。
  • 賞はバッジに属します。
  • ユーザーには多くの game_weeks があります。
  • GameWeek はユーザーに属します。
  • GameWeek には多くの賞があります。
  • 賞はgame_weekに属します。

したがって、user_id、badge_id、および game_week_id は、賞テーブルの外部キーです。

Badge は STI モデルを実装します。次のサブクラスがあるとしましょう: BadgeA と BadgeB。

注意すべきいくつかのルール:

game_week_id fk は、BadgeA では nil にすることができますが、BadgeB では nil にすることはできません。

ここに私の質問があります:

  1. BadgeA の場合、1 回しか付与できないという検証をどのように記述すればよいですか? つまり、ユーザーは複数持つことはできません。
  2. BadgeB の場合、ゲームの週に 1 回しか授与できないという検証をどのように記述すればよいですか?
4

1 に答える 1

1

データ・モデル:

私の理解では、これがあなたのデータモデルです(クリックして拡大):

データモデル http://yuml.me/6afcad62

移行:

移行により、移行レベルで 2 番目の要件を満たすことができます。

class CreateAwards < ActiveRecord::Migration
  def self.up
    create_table :awards do |t|
      # custom attributes here
      t.string     :name
      t.text       :description
      t.references :user,       :null => false
      t.references :game_week#,  :null => false
      t.references :badge,      :null => false
      t.timestamps
    end
    # a user can be awarded no more than a badge per week
    add_index :awards, [:user_id, :badge_id, :game_week_id], :unique => true
    # a user can be awarded no more than a badge for ever
    #add_index :awards, [:user_id, :badge_id], :unique => true
  end

  def self.down
    drop_table :awards
  end
end

モデル:

モデルを使用すると、モデル レベルで次の両方の要件を満たすことができます。

class Award < ActiveRecord::Base
  validate_uniqueness_of :user, :badge,
    :if => Proc.new { |award| award.badge === BadgeA }
  validate_uniqueness_of :user, :badge, game_week,
    :unless => Proc.new { |award| award.badge === BadgeA }
  #validate_uniqueness_of :user, :badge, game_week,
  #  :if => Proc.new { |award| award.badge === BadgeB }
end

ノート:

私はこれらのスニペットを試しませんでしたが、アイデアはここにあると思います:)

于 2010-05-27T16:01:51.590 に答える