【问题标题】:Polymorphic Query Containing All Polymorphic Records包含所有多态记录的多态查询
【发布时间】:2013-12-19 15:44:18
【问题描述】:

我有以下 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?

【问题讨论】:

  • 您能用伪代码拼出您希望查询指定的内容吗?如果您只想要所有这些,只需执行 *.all 并将结果添加到结果数组中。
  • @timpone 问题的关键是我想要一个 ActiveRecordRelation,而不是一个数组。
  • 你试过继承吗?二类
  • @SamD 尽可能避免 STI,但也许这是唯一的方法。
  • 很确定 *.all 在 R4 中返回一个 ActiveRecordRelation。也许只是合并结果?

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


【解决方案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 对象而只创建继承的模型,进行了一些验证:(有点使 Locatable 成为“假”抽象类)

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

【讨论】:

    【解决方案2】:

    模型 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找到更多关于多态关系以及如何使用它们的信息

    【讨论】:

    • 这给了我一个数组。正如我在问题中所说,我需要一个 ActiveRecordRelation。
    • 由于一、二和三在其他方面不相关,我认为如果没有复杂的 SQL 连接,您想要做的事情是不可能的。
    • 感谢@Pedr,我最近写了太多bash 示例。 ;)
    • 当我在两者之间来回切换时,我不会将 JS 花括号添加到某个 Ruby 类中。
    【解决方案3】:

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

    • 您无法直接在不同模型之间创建关系,除非通过 join 然后您拥有混合记录
    • 您通过多态可定位引用创建的任何关系都将仅限于那些被引用的记录并且实际上不会包含记录,仅包含对它们的引用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 2014-06-27
      • 2016-02-19
      • 2019-06-29
      • 1970-01-01
      相关资源
      最近更新 更多