【问题标题】:Rails postgresql left join using has_may order by created_atRails postgresql left join 使用 has_may order by created_at
【发布时间】:2021-09-17 20:34:59
【问题描述】:

我有两个模型,分别命名为“客户”和“会员”。客户可以拥有许多会员资格。我想按客户的最新会员资格取消日期的升序或降序显示客户。我的查询看起来像这样

@customers = Customer
  .joins('LEFT JOIN memberships on memberships.customer_id = customers.id')
  .includes(:partner, :affiliate, active_membership: :plan)
  .group('customers.id')
  .order('memberships.created_at DESC, memberships.cancelled_at DESC')
  .page(params[:page])
  .per(100)

【问题讨论】:

  • Rails 版本?您也可以执行以下操作.select(Customer.arel_table[Arel.star],Membership.arel_table[:created_at].maximum.as('most_recent_membership')).group(:id).order(Membership.arel_table[:created_at].maximum.public_send(direction)),其中方向是 :asc 或 :desc。为简洁起见,我省略了您的其余查询。如果您愿意,您仍然需要离开加入会员资格、添加分页和包含,这将只允许您按 MAX(memberships.created_at) 排序并有一个名为 Customer#most_recent_membership 的虚拟属性
  • Rails 6 @engineersmnky

标签: ruby-on-rails postgresql sql-order-by has-many


【解决方案1】:
class Customer
  has_many :memberships

  def self.order_by_latest_membership
     left_joins(:memberships) # no need to use a SQL string
       .group(:id) # you only need to group by customers.id
       .order(Membership.arel_table[:created_at].maximum.desc) # MAX(memberships.created_at) DESC
  end
end
Customer.order_by_latest_membership
        .includes(:partner, :affiliate, active_membership: :plan)
        .page(params[:page])

【讨论】:

  • 正如@engineersmnky 所暗示的,如果您想在结果集中获得MAX(memberships.created_at),也可以使用.select
  • left_joins 这样没有会员资格的用户就不会被排除在列表之外
猜你喜欢
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多