当您使用 .includes 急切加载关联记录时,您应该按原样访问关联。否则,如果向关联中添加更多查询条件,则会导致新的数据库查询。
您可以通过多种方式订购相关的预先加载的记录。
1.将订单条件添加到主范围。
user = User.includes(:skills).order("users.id, skills.name ASC")
在这种情况下,它不会像include 方法那样工作,默认情况下会进行两次查询。将使用“LEFT OUTER JOIN”执行一个查询以获取相关记录。这相当于使用eager_load 方法而不是includes
user = User.eager_load(:skills).order("users.id, skills.name ASC")
2。定义时将订单条件添加到关联中。
在这种情况下,每当您访问关联时,关联的记录将始终按名称排序。
class User < ActiveRecord::Base
has_many :skills, -> { order(:name) }
end
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
4.设置关联模型的默认顺序。
这将导致条件应用于与关联模型相关的每个关联和查询。
class Skill < ActiveRecord::Base
default_scope { order(:name) }
end
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