I don't think there is a way to do this with Mongoid. It might work if the field you were sorting by was part of an embedded document, but not in this case where you're using a referenced document.
I guess you probably have two options here, the less efficient way would be to just sort the collection of teams in ruby:
sport.teams.sort{|t1, t2| t1.user.name <=> t2.user.name}.each{ |team| result << team }
The better, and arguably more 'MongoDB-y' solution, would be to cache the user name inside each team, using a before_save
callback, and then use that to sort the teams:
# 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
Then you can just do:
spt.teams.asc(:user_name).each { |t| result << t }
Obviously, if the user's name field is mutable, then you'll to trigger it to save each child-team whenever the user's name field is changed.
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
Given that is not fantastically simple to maintain, this could arguably be a good candidate to use an observer, rather than callbacks, but you get the idea.