I have a classic many to many relationship defined like this in 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
and I basically want to have a Developer
array sorted by code_review.created_at
without doubles.
My first attempt was the basic one: Developer.order('code_reviews.created_at': :asc)
which triggers this error: ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'code_reviews.created' in 'order clause
.
After a few googling I understood the join was not automatically performed by ActiveRecord so I added it: Developer.joins(:code_reviews).order('code_reviews.created_at': :asc)
. This one works but has doubles inside. I need to have a developer to appear only once in this array.
If I try to create a distinct on that query, ActiveRecord/MySQL complains that the ORDER BY
is not performed on a column that is in the SELECT. How can I solve this problem?
I googled it quite a lot I can't find anything.
NOTE
The MYSQL query which works but with doubles looks like this:
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
and I'd like to have a distinct on the developers.
I found the answer thanks to this clear example on MySQL sub queries: http://www.mysqltutorial.org/mysql-subquery/
With this example, I understood that I needed a sub query looking like this:
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
Translated to ruby in my case:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.