3

我有四个型号的ActiveRecord验证:用的has_many模型,belongs_to的关联和STI

  • 用户
  • 徽章
  • 游戏周期

的关联如下:

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

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

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

有些规则需要注意:

的game_week_id FK可以是零为BadgeA,但不能是零的BadgeB。

这里是我的问题:

  1. 对于BadgeA,我怎么写一个验证,它只能被授予一次?也就是说,用户不能有多于一个 - 有史以来。
  2. 对于BadgeB,我该如何编写一个验证表明它每周只能获得一次奖励?

回答

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 

注:

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

+0

===是什么? – keruilin 2010-05-28 01:55:59

+0

这是Ruby中的case平等运算符。 您可以在[Object Ruby doc] [1]和[博客文章] [2]中看到更多详细信息。 [1]:http://ruby-doc.org/core/classes/Object.html#M000345 [2]:http://www.pluitsolutions.com/2006/10/09/comparing-equality- EQL相等和 - 区分平等合红宝石/ – 2010-05-28 07:13:13

相关问题