【问题标题】:Rails preloading the associationRails 预加载关联
【发布时间】:2018-04-08 04:45:24
【问题描述】:

我在预加载 belongs_to 关联时遇到问题。

有问题的模型具有以下关联

class Order < ActiveRecord::Base
  belongs_to :user_name, -> { select(:id, :name) }, class_name: "User", :foreign_key => 'user_id'
end

上述关联工作正常并按预期解决。

我想返回 user.iduser.name 以及 order。 如何预加载关联user_name

我确实尝试了Order.includes(:user_name),但没有按预期工作。

【问题讨论】:

  • 这看起来很奇怪,你为什么不先belongs_to :user 然后Order.find(1).user.name
  • 你不应该选择关系。您可以在模型中添加范围
  • Order.includes(:user_name) 到底有什么问题?

标签: ruby-on-rails activerecord


【解决方案1】:

我会将关联更改为:

class Order < ActiveRecord::Base
  belongs_to :user
end

然后在别处选择users.idusers.name。它使您的代码更加灵活。


如何预加载关联

ActiveRecord 提供了几种方法:

  1. Preload。在单独的查询中加载关联数据。自从 preload 总是生成两个你不能使用 preloaded table 的 sql 在哪里条件。
  2. Includes。默认加载关联数据 一个单独的查询,就像预加载一样。但还有额外的references 调用它从使用两个单独的查询切换到创建一个 单LEFT OUTER JOIN。因此,您可以在 where 条件下使用关联表。
  3. Eager load。使用 LEFT OUTER JOIN 在单个查询中加载关联。

这里有一些有用的文章:

Preload, Eagerload, Includes and Joins

Making sense of ActiveRecord joins, includes, preload, and eager_load

【讨论】:

    【解决方案2】:

    尝试添加如下所示的范围

    scope : user_name_id, -> { joins(:user_name).select( 'user_names.id, user_names.name' ).collect{|c| [c.id, c.name]} }
    

    【讨论】:

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