繁体   English   中英

在与 ActiveRecord 的多对多关系上使用不同的方法

[英]Use distinct method with order on a many to many relation with ActiveRecord

我在 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

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

我的第一次尝试是基本的: 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)因此我添加了它: Developer.joins(:code_reviews).order('code_reviews.created_at': :asc) 这个有效,但里面有双打。 我需要一个开发人员在这个数组中只出现一次。

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

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

笔记

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 子查询的清晰示例,我找到了答案: 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

在我的情况下转换为 ruby​​:

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

暂无
暂无

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

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