【问题标题】:rails complex order_by with argumentrails complex order_by with argument
【发布时间】:2016-02-28 23:51:06
【问题描述】:

我有一个 Rails 应用程序。我想显示按当前用户的常见任务数量排序的用户配置文件。每个任务都有一个分配者和一个执行者。该数字应包括同一用户的executed_tasks 和assigned_tasks。例如,如果 current_user 为 User4 分配了 5 个任务,而 User4 为 current_user 分配了 3 个任务,那么这个数字就是 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

用户.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

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • Hoang,如何在控制器或视图中调用它?
    • 拨打given_user.ordered_relating_users
    • 黄,它的工作!谢谢。您能否建议我一些可以阅读有关此主题的资源?我不完全明白,所以我会做一些阅读,但很难找到好的文章。
    • 黄,还有一个问题。这只考虑到 sby 已经有至少一项任务的用户。因此,如果有一个新用户,他将什么也看不到。对于他们,我想向其他用户展示。我目前将显示的用户限制为 6 个。如果给定用户有任务的用户超过 6 个,则此查询可以正常工作。如果给定用户有 0 个用户有任务,那么我可以使用 if else 语句。但是假设给定用户有 2 个用户有任务,我想向他展示 4 个额外的用户来填补空白。我怎么能这样做?
    • @SzilardMagyar:这只是我想到的简单的基于 sql 的解决方案,在 from 子句中使用了嵌套子查询,您可以参考这里:geeksengine.com/database/subquery/subquery-in-from-clause.php 首先,找到所有其他相关的用户 ID到特定用户 A 到视图,这意味着分配者(执行者是 A)和执行者(分配者是 A),由于列名不同,您需要对其进行规范化(例如 user_id)并使用 union all 将其连接在一起。然后将用户表与该视图连接(右外连接以保留所有关系记录)并按组数排序。
    猜你喜欢
    • 1970-01-01
    • 2013-03-26
    • 2018-12-06
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    相关资源
    最近更新 更多