Ruby on rails 使用单表继承验证多个子类之间的唯一性

Ruby on rails 使用单表继承验证多个子类之间的唯一性,ruby-on-rails,single-table-inheritance,Ruby On Rails,Single Table Inheritance,我有一个有许多卡片集的卡片模型和一个通过会员模型有许多卡片的卡片集模型: class Card < ActiveRecord::Base has_many :memberships has_many :card_sets, :through => :memberships end class Membership < ActiveRecord::Base belongs_to :card belongs_to :card_set validates_un

我有一个有许多卡片集的卡片模型和一个通过会员模型有许多卡片的卡片集模型:

class Card < ActiveRecord::Base
  has_many :memberships
  has_many :card_sets, :through => :memberships
end

class Membership < ActiveRecord::Base
  belongs_to :card
  belongs_to :card_set

  validates_uniqueness_of :card_id, :scope => :card_set_id
end

class CardSet < ActiveRecord::Base
  has_many :memberships
  has_many :cards, :through => :memberships

  validates_presence_of :cards
end
但是,游戏集应该允许这种行为:

other_cards = FooCard.all( :limit => 10 )

first_set = GameSet.new
second_set = GameSet.new

first_set.cards = other_cards    # Valid
second_set.cards = other_cards   # Also valid
我猜某个地方需要一个validates\u university\u调用,但我不确定该放在哪里。有什么建议吗

更新1 我按照建议修改了扩展类:

class Expansion < CardSet 
  validate :validates_uniqueness_of_cards

  def validates_uniqueness_of_cards
    membership = Membership.find(
      :first,
      :include => :card_set,
      :conditions => [
        "card_id IN (?) AND card_sets.type = ?",
        self.cards.map(&:id), "Expansion"
      ]
    )
    errors.add_to_base("a Card can only belong to a single Expansion") unless membership.nil?
  end
end
我真的不确定,我只是在尝试,因为我不能在这里测试它。。。但也许下面这样的东西对你有用。如果有,请告诉我:]

class Expansion < Set 
   validate :validates_uniqueness_of_cards

   def validates_uniqueness_of_cards
      membership = Membership.find(:first, :include => :set,
         :conditions => ["card_id IN (?) AND set.type = ?",
            self.cards.map(&:id), "Expansion"])
      errors.add_to_base("Error message") unless membership.nil?
   end
end
类扩展:set,
:conditions=>[“卡片id在(?)和set.type=?”,
self.cards.map(&:id),“扩展”])
错误。将_添加到_库(“错误消息”),除非membership.nil?
结束
结束

很晚才参加这里的聚会,但假设您已经设置了STI,那么您现在可以验证作用域为STI类型的属性的唯一性

e、 g


验证:您的\u属性\u id,scope::type的唯一性\u我将在回家后测试向扩展类添加
验证:card\u id的唯一性\u
。会这么简单吗?(另一个不相关的注意事项是:尝试用iphone更新StackOverflow上的评论是一个糟糕的主意!他们真的需要为这个网站实现一个移动视图!)不。我的想法行不通。我现在已经可以使用Rails了,我会用你的想法来做一些实验。再次感谢你,J。我用我的最终验证方法更新了我的问题。我必须添加一个复选框,以便扩展在将来的
#update
s中忽略自身,但除此之外,您的解决方案是完美的。我完全忘记了这个
update
案例。但我很高兴我的回答对您有所帮助:]
other_cards = FooCard.all( :limit => 10 )

first_set = GameSet.new
second_set = GameSet.new

first_set.cards = other_cards    # Valid
second_set.cards = other_cards   # Also valid
class Expansion < CardSet 
  validate :validates_uniqueness_of_cards

  def validates_uniqueness_of_cards
    membership = Membership.find(
      :first,
      :include => :card_set,
      :conditions => [
        "card_id IN (?) AND card_sets.type = ?",
        self.cards.map(&:id), "Expansion"
      ]
    )
    errors.add_to_base("a Card can only belong to a single Expansion") unless membership.nil?
  end
end
class Expansion < CardSet
  validate :validates_uniqueness_of_cards

  def validates_uniqueness_of_cards
    sql_string = "card_id IN (?) AND card_sets.type = ?"
    sql_params = [self.cards.map(&:id), "Expansion"]

    unless new_record?
      sql_string << " AND card_set_id <> ?"
      sql_params << self.id
    end

    membership = Membership.find(
                   :first,
                   :include => :card_set,
                   :conditions => [sql_string, *sql_params]
                 )

    errors.add_to_base("a Card can only belong to a single Expansion") unless membership.nil?
end
class Expansion < Set 
   validate :validates_uniqueness_of_cards

   def validates_uniqueness_of_cards
      membership = Membership.find(:first, :include => :set,
         :conditions => ["card_id IN (?) AND set.type = ?",
            self.cards.map(&:id), "Expansion"])
      errors.add_to_base("Error message") unless membership.nil?
   end
end