簡體   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