Rails ActiveRecord如何通过自定义命名关联进行排序

时间:2014-12-19 17:30:51

标签: ruby-on-rails ruby rails-activerecord

好的,所以创建了2个模型User和Follow。其中User具有username属性,Following具有2个属性,即User关联:user_id,following_user_id。我已经在各自的模型中建立了这些关联,并且一切都很好。

class User < ActiveRecord::Base
  has_many :followings, dependent: :destroy
  has_many :followers, :class_name => 'Following', :foreign_key => 'following_user_id', dependent: :destroy
end

class Following < ActiveRecord::Base
  belongs_to :user
  belongs_to :following_user, :class_name => 'User', :foreign_key => 'following_user_id'
end

现在我需要在用户名进行ActiveRecord查询时对结果进行排序。我可以使用以下代码轻松地为直接用户关联(user_id)实现这一点,该代码将返回由属于user_id的关联的用户名排序的关注列表:

Following.where(:user_id => 47).includes(:user).order("users.username ASC")

问题是我无法通过其他关联(following_user_id)获得相同的排序结果。我已将关联添加到.includes调用但我收到错误,因为活动记录正在寻找名为following_users的表上的关联

Following.where(:user_id => 47).includes(:user => :followers).order("following_users.username ASC")

我尝试将.order调用中的关联名称更改为我在用户模型中设置的名称作为关注者,以下但没有工作,它仍在寻找包含这些标题的表。我也尝试了user.username,但是这将基于其他关联进行排序,例如在第一个示例中。

如何通过following_user.username?

订购ActiveRecord结果

1 个答案:

答案 0 :(得分:2)

这是因为SQL查询中没有following_users表。

您需要手动加入它:

Following.
joins("
  INNER JOIN users AS following_users ON
  following_users.id = followings.following_user_id
").
where(user_id: 47). # use "followings.user_id" if necessary
includes(user: :followers).
order("following_users.username ASC")

要获取没有Following的{​​{1}}行,只需使用following_user_id

或者,如果您能负担速度和内存成本,则可以在Ruby而不是SQL中执行此操作:

OUTER JOIN

仅供参考:如果Following. where(user_id: 47). # use "followings.user_id" if necessary includes(:following_user, {user: :followers}). sort_by{ |f| f.following_user.try(:username).to_s } 丢失try,则following_user确保比较字符串以进行排序。否则,to_snil相比会崩溃。