rails complex order_by with argument

时间:2015-11-26 01:30:14

标签: sql ruby-on-rails activerecord scope sql-order-by

我有一个rails应用程序。我想显示按照当前用户的常用任务数排序的用户配置文件。每个任务都有一个分配器和一个执行器。该数字应包括同一用户的executed_tasks和assigned_tasks。因此,例如,如果current_user将5个任务分配给User4,而User4将3个任务分配给current_user,则此数字将为8。

我的主要问题是我不知道如何使用给定用户作为计数的arg。我应该以某种方式在模型中或在控制器中设置实例变量(@users)吗?

task.rb

belongs_to :assigner, class_name: "User"
belongs_to :executor, class_name: "User"

scope :between, -> (assigner_id, executor_id) do
  where("(tasks.assigner_id = ? AND tasks.executor_id = ?) OR (tasks.assigner_id = ? AND tasks.executor_id = ?)", assigner_id, executor_id, executor_id, assigner_id)
end

user.rb

has_many :assigned_tasks, class_name: "Task", foreign_key: "assigner_id", dependent: :destroy
has_many :executed_tasks, class_name: "Task", foreign_key: "executor_id", dependent: :destroy

1 个答案:

答案 0 :(得分:1)

假设您希望使用单个SQL查询执行此操作以提高性能,您可以执行以下操作:

class User < ActiveRecord::Base
  def assigners
    Task.where(executor_id: id).select('assigner_id AS user_id')
  end

  def executors
    Task.where(assigner_id: id).select('executor_id AS user_id')
  end

  def relations_sql
    "((#{assigners.to_sql}) UNION ALL (#{executors.to_sql})) AS relations"
  end

  def ordered_relating_users
    User.joins("RIGHT OUTER JOIN #{relations_sql} ON relations.user_id = users.id")
      .group(:id)
      .order('COUNT(relations.user_id) DESC')
  end
end

由于评论要求考虑不相关的用户,并且限制为6,因为我们使用FULL_OUTER_JOIN,所以它有点棘手。编辑的函数将是:

def ordered_relating_users
  User.joins("FULL OUTER JOIN #{relations_sql} ON relations.user_id = users.id")
      .where.not(id: id)
      .group(:id)
      .order('COUNT(relations.user_id) DESC')
      .limit(6)
end