【问题标题】:Sort a Rails model by an attribute on its polymorphic associations按多态关联上的属性对 Rails 模型进行排序
【发布时间】:2014-07-08 23:08:29
【问题描述】:

我想这是一个重复的问题,但我还没有找到它,所以我想我会问。我有一个User 模型,它通过多态关联具有不同类型的Profile 模型。比如:

class User < ActiveRecord::Base
  belongs_to :profile, polymorphic: true
end

class Profile < ActiveRecord::Base
  has_one :user, as: :profile
end

class FacebookProfile < ActiveRecord::Base
  has_one :user, as: :profile
end

我想对 User 执行查询,返回按其个人资料对象的名字排序的用户。在没有任何多态关系之前,我可以通过在 :profile 上的 joins 开始来做到这一点,但我知道这不适用于多态性。

除了使用sortsort_by 之外,还有更好的方法吗:

User.all.sort_by {|user| user.profile.first_name }

【问题讨论】:

  • 请注意,如果 FacebookProfile 从 Profile 继承,这在您的示例中似乎是最合乎逻辑的结构,您不会有任何问题。话虽如此,您可以对 n 个表执行 n 个查询并混合结果。我看到的另一种方法是缓存您在 User 模型中使用的名称。

标签: ruby-on-rails postgresql polymorphic-associations active-record-query


【解决方案1】:

使用 SQL 是可行的。

SELECT users.*, COALESCE(profiles.first_name, facebook_profiles.first_name) AS c_first_name FROM users 
LEFT JOIN profiles ON users.profile_id=profiles.id AND users.profile_type="Profile" 
LEFT JOIN facebook_profiles ON users.profile_id=facebook_profiles.id AND users.profile_type="FacebookProfile" 
ORDER BY c_first_name ASC

您应该能够在 User 模型上使用此“手动”连接创建范围,因为您可以在两列上使用 COALESCE 来创建可以排序的别名。

试试这样的

class User < ActiveRecord::Base
  belongs_to :profile, polymorphic: true

  scope :sort_by_first_name, -> { select("users.*", "COALESCE(profiles.first_name, facebook_profiles.first_name) AS c_first_name").joins("LEFT JOIN profiles ON users.profile_id=profiles.id AND users.profile_type='Profile'").joins("LEFT JOIN facebook_profiles ON users.profile_id=facebook_profiles.id AND users.profile_type='FacebookProfile'").order("c_first_name ASC") }
end

我自己没有尝试过,但理论上它应该可以工作。

【讨论】:

  • 没有足够的导轨 :)
猜你喜欢
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2017-02-13
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
相关资源
最近更新 更多