假设我有一个User
,它有一个字段name
,并且有_many teams
,还有一个Team
属于用户
,属于运动
。 Sport
有一个字段 name
和 has_many teams
。
我想遍历运动
,做一些事情,并收集按 name
排序的 teams
数组 用户
。
result = []
Sport.asc(:name).each do |spt|
# some other stuff not relevant to this question but that
# justifies my looping through each sport.
spt.teams.asc(:'user.name').each { |t| result << t }
end
这会运行,但是 sports
的排序符合预期,但是 result
中的团队顺序没有按照我的预期排序。
使用 Mongoid
按关系值对集合进行排序的正确方法是什么?
最佳答案
我不认为有一种方法可以用 Mongoid 做到这一点。如果您排序所依据的字段是嵌入文档的一部分,它可能会起作用,但在您使用引用文档的情况下则不行。
我想您在这里可能有两个选择,效率较低的方法是仅对 ruby 中的团队集合进行排序:
sport.teams.sort{|t1, t2| t1.user.name <=> t2.user.name}.each{ |team| result << team }
更好的、可以说是更“MongoDB-y”的解决方案是使用 before_save
回调在每个团队中缓存用户名,然后使用它对团队进行排序:
# app/models/team.rb
class Team
include Mongoid::Document
field :user_name, :type => String
before_save :update_user_name
protected
def update_user_name
self.user_name = self.user.name if self.user
end
end
然后你可以这样做:
spt.teams.asc(:user_name).each { |t| result << t }
显然,如果用户名字段是可变的,那么只要用户名字段发生更改,您就会触发它来保存每个子团队。
class User
after_save :update_teams_if_name_changed
def update_teams_if_name_changed
if self.name_changed?
self.teams.each { |team| team.save }
end
end
end
考虑到维护起来并不是非常简单,这可以说是使用观察者而不是回调的一个很好的候选者,但你明白了。
关于ruby - 如何使用 Mongoid 按嵌套字段值排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16452225/