ruby - 如何使用 Mongoid 按嵌套字段值排序?

标签 ruby sorting mongoid mongoid3 database-relations

假设我有一个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/

相关文章:

windows - Howto - 在 mongrel 上运行 Redmine 作为 Windows 上的服务

ruby - find_by_sql 等效于 mongoid?

ruby-on-rails-3 - 或者查询匹配 nil 或 ""与 Mongoid 仍然匹配 ""?

ruby-on-rails - 有没有办法让 resque 作业将生成的 pdf 直接推送到浏览器?

ruby-on-rails - ActiveAdmin - 如何删除所有对象(不仅仅是当前列表页面上的对象)(Rails ')

javascript - 从数组中相对选取 X 值

java - 对混合整数和字符串的 ArrayList 进行排序,同时保留字符串和整数的相对顺序

sorting - ansible中2个列表的所有组合

javascript - 如何从发送到 Mongo 的脚本中返回一个值?

ruby-on-rails - Ruby 中 do/end block 的一般用途是什么