【问题标题】:How do I optimize a polymorphic news feed in rails?如何优化 Rails 中的多态新闻提要?
【发布时间】:2012-01-28 09:09:35
【问题描述】:

这是我的模型:

class User < ActiveRecord::Base
  has_many :activities
  has_many :requests

class Activity < ActiveRecord::Base
  belongs_to :user
  belongs_to :object, :polymorphic => true

我想获取所有用户的活动并显示它们

Activity.where(:user_id => current_user.id).include(:object)

问题是我不能急切加载对象模型,因为它是多态的 我该如何克服这个问题?

【问题讨论】:

  • 我可以使用具有类似多态关联的包含(Rails 3.1)。当你尝试时会发生什么?
  • 还有一点要注意:如果您在 Rails 控制台上测试它以查看生成的 sql(总结其不是急切加载),那么请确保您在 where 子句中使用对象的属性或您的选择子句。 Rails 可能不会急切加载作为对查询的优化(当不需要时,至少我认为它是一种优化)。

标签: ruby-on-rails optimization feed


【解决方案1】:

多态关联支持急切加载。您需要按照以下方式做一些事情:

Activity.find(:all, :include => :objectable, :conditions => {:user_id => current_user.id})

尽管您需要确保已在关联模型上正确定义了多态关系。

如需进一步帮助,请参阅: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Eager+loading+of+associations

多态部分位于“渴望加载关联”部分的末尾。

【讨论】:

    【解决方案2】:

    正如@Wahaj 所说,预加载仅适用于:includes 而不适用于:join

    以下是文档中的解释:

    Address.find(:all, :include => :addressable)

    这将执行一个查询以加载地址并加载可寻址对象,每个可寻址类型一个查询。例如,如果所有可寻址对象都是 Person 或 Company 类,则总共将执行 3 个查询。要加载的可寻址类型列表在加载地址的背面确定。如果 Active Record 必须回退到预先加载的先前实现并且会引发 ActiveRecord::EagerLoadPolymorphicError,则不支持此操作。原因是父模型的类型是列值,因此其对应的表名不能放在该查询的 FROM/JOIN 子句中。

    我想这就是你所追求的:

    current_user.activities.includes(:object)
    

    正如文档所说,每个关联都会有一个额外的查询。我不确定,但您可能需要为 rails 定义另一个方向的关联以知道要搜索哪些 AR 模型,例如:

    class Post < ActiveRecord::Base
      has_many :activities, :as => :object
    end
    

    如果您仍然收到错误,您可能使用的是尚未实现此功能的早期 Rails 版本。

    【讨论】:

      【解决方案3】:

      不可能对多态关系进行预加载...但是您可以对一种多态类型执行此操作,例如如果您有两个 polymorphic_type 然后过滤该类型上的记录,然后进行预加载它将起作用.. .. 不是完美的预加载,而是部分预加载

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-08
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多