【问题标题】:Use distinct method with order on a many to many relation with ActiveRecord在与 ActiveRecord 的多对多关系上使用具有顺序的 distinct 方法
【发布时间】:2019-11-29 11:20:11
【问题描述】:

我在 ActiveRecord 中定义了一个经典的多对多关系:

class Developer < ApplicationRecord
  has_many :developers_code_reviews
  has_many :code_reviews, through: :developers_code_reviews
end

class DevelopersCodeReview < ApplicationRecord
  belongs_to :code_review
  belongs_to :developer
end

class CodeReview < ApplicationRecord
  has_many :developers_code_reviews
  has_many :developers, through: :developers_code_reviews
end

我基本上想要一个Developer 数组,按code_review.created_at 排序,没有双精度数。

我的第一次尝试是基本的:Developer.order('code_reviews.created_at': :asc),它触发了这个错误:ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'code_reviews.created' in 'order clause

经过几次谷歌搜索后,我了解到 ActiveRecord 不会自动执行连接,所以我添加了它:Developer.joins(:code_reviews).order('code_reviews.created_at': :asc)。这个有效,但里面有双打。我需要一个开发者在这个数组中只出现一次。

如果我尝试在该查询上创建不同的,ActiveRecord/MySQL 会抱怨 ORDER BY 未在 SELECT 中的列上执行。我该如何解决这个问题?

我用谷歌搜索了很多,我找不到任何东西。

注意

有效但 with 双打的 MYSQL 查询如下所示:

SELECT `developers`.*
FROM `developers`
INNER JOIN `developers_code_reviews` ON `developers_code_reviews`.`developer_id` = `developers`.`id`
INNER JOIN `code_reviews` ON `code_reviews`.`id` = `developers_code_reviews`.`code_review_id` 
ORDER BY `code_reviews`.`created_at` ASC

我想对开发人员有所了解。

【问题讨论】:

    标签: mysql ruby-on-rails activerecord sql-order-by distinct


    【解决方案1】:

    感谢这个关于 MySQL 子查询的清晰示例,我找到了答案:http://www.mysqltutorial.org/mysql-subquery/

    通过这个示例,我了解到我需要一个如下所示的子查询:

    SELECT *
    FROM developers
    LEFT OUTER JOIN (
      SELECT developer_id, max(updated_at) max_updated_at
      FROM developers_code_reviews
      GROUP BY developer_id
    ) dcr
    ON developers.id = dcr.developer_id
    ORDER BY maxupdt
    

    在我的例子中翻译成红宝石:

    class DevelopersCodeReview < ApplicationRecord
      belongs_to :code_review
      belongs_to :developer
    
      class << self
        def developer_queue
          select('developer_id, max(updated_at) max_updated_at').
          group(:developer_id)
        end
      end
    end
    
    class Developer < ApplicationRecord
      belongs_to :slack_workspace
      belongs_to :project, optional: true
    
      class << self
        def queue
          developer_queue = DevelopersCodeReview.developer_queue.to_sql
    
          joins("LEFT OUTER JOIN (#{developer_queue}) dcr ON id = dcr.developer_id").
          order(max_updated_at: :asc)
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 2014-11-19
      • 2014-05-16
      • 2020-11-16
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多