具有has_many,belongs_to关联和STI的模型的ActiveRecord验证

时间:2010-05-24 22:27:14

标签: ruby-on-rails validation activerecord single-table-inheritance

我有四种模式:

  • 用户
  • 奖励
  • 徽章
  • 游戏周期

协会如下:

  • 用户有很多奖项。
  • 奖励属于用户。
  • 徽章有很多奖项。
  • 奖项属于徽章。
  • 用户有很多game_weeks。
  • GameWeek属于用户。
  • GameWeek有很多奖项。
  • 奖项属于game_week。

因此,user_id,badge_id和game_week_id是奖励表中的外键。

徽章实现了STI模型。我们只说它有以下子类:BadgeA和BadgeB。

需要注意的一些规则:

对于BadgeA,game_week_id fk可以为零,但对BadgeB来说不能为零。

以下是我的问题:

  1. 对于BadgeA,我如何编写一个只能被授予一次的验证?也就是说,用户不能有多个 - 永远。
  2. 对于BadgeB,如何编写验证,每周游戏只能获得一次奖励?

1 个答案:

答案 0 :(得分:1)

数据模型:

根据我的理解,这是您的数据模型(点击放大):

Data model http://yuml.me/6afcad62

<强>迁移:

迁移可让您在迁移级别满足第二个要求:

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

注意:

我没有尝试这些片段,但我认为这个想法就在这里:)