包含所有多态记录的多态查询

时间:2013-12-19 15:44:18

标签: ruby-on-rails ruby-on-rails-3 activerecord polymorphism

我有以下3个型号:

class One < ActiveRecord::Base
   has_many :locations, as: :locatable, dependent: :destroy
   has_many :countries, through: :locations, order: :name
end

class Two < ActiveRecord::Base
   has_many :locations, as: :locatable, dependent: :destroy
   has_many :countries, through: :locations, order: :name
end

class Three < ActiveRecord::Base
   has_many :locations, as: :locatable, dependent: :destroy
   has_many :countries, through: :locations, order: :name
end

如何构建包含所有三种模型的所有记录的ActiveRecordRelation?

3 个答案:

答案 0 :(得分:1)

您可以结合STI和多态关联:

class Locatable < ActiveRecord::Base
  has_many :locations, as: :locatable, dependent: :destroy
  has_many :countries, through: :locations, order: :name
end

class One < Locatable
end

class Two < Locatable
end

class Three < Locatable
end

然后你可以做到:

@locatables = Locatable.scoped # => returns all types of locatable objects

稍微验证以防止系统创建可定位对象但只创建继承模型:(有点使Locatable成为“假”抽象类)

class Locatable < ActiveRecord::Base
  ALLOWED_TYPES = %w( One Two Three )
  validates :locatable_type, inclusion: { in: self::ALLOWED_TYPES }

答案 1 :(得分:0)

模型OneTwoThree除非通过多态关系相互关联,因此您需要转到其中一个类以获得所需的结果

因此,如果所有记录都有location而您的locatable类称为Location;您应该能够使用以下内容获取所有记录:

Location.all.each do |location|
  location.locatable # <-- this would be an individual record from either One, Two, or Three
end

仅供参考,您可以在http://guides.rubyonrails.org/association_basics.html#polymorphic-associations找到有关多态关系以及如何使用它们的更多信息

答案 2 :(得分:0)

您无法创建包含所有三种模型的所有记录的关系,因为:

  • 您不能直接在不同的模型之间创建关系,除非通过join,然后您就拥有了记录的混合
  • 您通过多态Locatable引用创建的任何关系将仅限于那些引用并且实际上不包含记录的记录,只是对它们的引用