简体   繁体   English

带有参数的Rails复杂order_by

[英]rails complex order_by with argument

I have a rails app. 我有一个Rails应用程序。 I would like to display user profiles ordered by the number of the common tasks they have with the current user. 我想显示按用户与当前用户的常见任务数量排序的用户个人资料。 Every task has one assigner and one executor. 每个任务都有一个分配器和一个执行器。 The number should include both the executed_tasks and assigned_tasks for the same user. 该数字应同时包含同一用户的executedtasks和assigned_tasks。 So for example if current_user assigned 5 tasks to User4 and User4 assigned 3 tasks to current_user then this number would be 8. 因此,例如,如果current_user为User4分配了5个任务,而User4为current_user分配了3个任务,那么该数字将为8。

My main problem is that I don't know how to use the given user as arg for the count. 我的主要问题是我不知道如何使用给定用户作为arg进行计数。 Should I do in the model somehow or when I set the instance variable (@users) in the controller? 我应该以某种方式还是在控制器中设置实例变量(@users)时在模型中进行操作?

task.rb 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 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

Assuming that you want to execute this with a single SQL query to improve performance, you could do something like: 假设您要使用单个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

As the comment requests for taking into account the unrelating users, and limit to 6, it's a little bit trickier, since we use FULL_OUTER_JOIN .The edited function would be: 由于注释要求考虑到不相关的用户,并且限制为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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM