Imr*_*qvi 3 activerecord ruby-on-rails eager-loading ruby-on-rails-4 rails-activerecord
我正在使用此查询来获取我的数据
user = User.includes(:skills).order(user: :id)
Run Code Online (Sandbox Code Playgroud)
它工作正常。但是当我尝试按字母顺序显示技能时,如下所示
user.skills.order(name: :asc)
Run Code Online (Sandbox Code Playgroud)
它在日志中显示它作为order()一种activerecord方法进入数据库。这似乎eager loading失败了,因为无论如何必须将急切加载放入数据库中,这有什么用呢?
谁能指导我这样做的好方法是什么。
当您渴望使用加载关联记录时.includes,应按原样访问关联。否则,如果您向关联添加更多查询条件,则将导致新的数据库查询。
有几种方法可以订购相关的急切加载的记录。
1.将订单条件添加到主范围。
user = User.includes(:skills).order("users.id, skills.name ASC")
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它将无法像include默认情况下方法工作一样进行两次查询。将使用“ LEFT OUTER JOIN”执行一次查询以获取关联的记录。这等效于使用eager_load方法代替includes
user = User.eager_load(:skills).order("users.id, skills.name ASC")
Run Code Online (Sandbox Code Playgroud)
2.在定义关联时将订单条件添加到关联中。
在这种情况下,每当您访问关联时,关联的记录将始终按名称排序。
class User < ActiveRecord::Base
has_many :skills, -> { order(:name) }
end
Run Code Online (Sandbox Code Playgroud)
3.创建具有所需顺序的另一个关联,以仅在此特定情况下使用。
这样可以避免对主关联不必要的条件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
Run Code Online (Sandbox Code Playgroud)
4.设置关联模型的默认顺序。
这将导致该条件应用于与关联模型相关的每个关联和查询。
class Skill < ActiveRecord::Base
default_scope { order(:name) }
end
Run Code Online (Sandbox Code Playgroud)
5.使用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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1723 次 |
| 最近记录: |