2

为了()子句的工作预先加载我使用这个查询来获取我的数据不与轨道

user = User.includes(:skills).order(user: :id) 

它工作正常。但是当我尝试显示由字母顺序排列的技能,如下面

user.skills.order(name: :asc) 

它显示了日志,它去在数据库中order()activerecord方法。看来eager loading在这里是失败的,因为无论如何它必须进入数据库,使用急切加载的意义何在。

任何人都可以引导我什么是一个很好的方法来做到这一点。

+0

就像一个建议,可以请你分享你的日志吗? –

回答

1

当你渴望负载相关的记录使用.includes,你应该是访问的关联。否则,如果添加更多查询条件,则会导致新的数据库查询。

有几种方法可以订购相关的预先加载的记录。

1.添加订单条件到关联。

在这种情况下,只要您访问关联,关联的记录将始终按名称排序。

class User < ActiveRecord::Base 
    has_many :skills, -> { order(:name) } 
end 

2.用于使用在此特定情况下创建具有适当的顺序另一个关联。

这对于避免skills关联中的不必要条件很有用。

class User < ActiveRecord::Base 
    has_many :skills_ordered_by_name, -> { order(:name) }, class_name: "Skill" 
end 

# usage 
users = User.includes(:skills_ordered_by_name) 

users.each do |user| 
    # access eager loaded association 
    user.skills_ordered_by_name 
end 

3.设置默认顺序为Skill模型。

这将导致条件不仅适用于关联,还适用于Skill模型。

class Skill < ActiveRecord::Base 
    default_scope { order(:name) } 
end 

4.排序渴望加载记录使用Ruby代码(不是ActiveRecord的查询方法)

时不会有太多的记录进行排序这种做法是合适的。

users = User.includes(:skills) 

users.each do |user| 
    # sorting with Ruby's 'sort_by' method 
    user.skills.sort_by(&:name) 

    # or something like 
    user.skills.sort { |one, another| one.name <=> another.name } 
end 

5.使用eager_load方法,并添加关联顺序条件主要查询

在这种情况下,它不会像include工作方法通常工作,使两个查询。一个查询将使用'LEFT OUTER JOIN'来获取相关记录。

users = User.eager_load(:skills).order("users.id, skills.name") 
+0

感谢您的详细解答。但除了eager_load没有任何工作。为什么 – ImranNaqvi

+0

一切都应该工作。是什么让你觉得有些东西不起作用:错误,额外的数据库查询,错误的顺序或其他什么? – chumakoff

+0

没有错误,但对结果没有影响。我实现了这些全部检查差异 – ImranNaqvi

0

您可以使用此:

user = User.includes(:skills).order(user: :id, name: :desc)