我觉得我有一个简单的要求:我想根据子类的属性对父类进行排序。
class owner
has_many :tasks
end
class task
belongs_to :owner
end
现在我想根据任务的截止日期对所有者进行排序,以便具有“最接近”截止日期的任务的所有者是第一个,等等
我可以使用数组排序在Ruby中执行此操作,但我的记录集非常庞大,我需要使用AR / DBMS执行此操作..
更新
正如我在思考这个问题时,解决方案的一部分发生在我身上,虽然我不知道如何在AR中实现。
要根据所有者的任务对所有者进行排序,只有一个任务(每个所有者)是相关的,即具有最接近截止日期的任务。
我如何使用AR向我提取所有所有者,按其最接近的截止日期排序?
更新2:
Task.order("due_date DESC").maximum("due_date", :group => 'owner')
实际上会给我所有者对象,按照正确的顺序排序,作为有序哈希的一部分([owner] =>“due_date”)。万岁!现在唯一的问题是,如何告诉AR使用所有者对象eager_load所有相关任务。因为此时它每次调用时都会触发查询
owner.tasks.each do |t|
在我看来。
任何帮助表示赞赏,我对此(简单?)问题感到困惑,
欧文
答案 0 :(得分:2)
好的,最后我自己想出来了。
Owner.includes(:tasks).joins(:tasks).order("tasks.due_date").group(:id)
将根据任务中最接近的截止日期对所有者进行排序,并急切加载所有任务,从而产生单个查询。
更新:添加生成的SQL以响应下面的Mladen评论。
SELECT `owners`.* FROM `owners`
INNER JOIN `tasks` ON `tasks`.`owner_id` = `owner`.`id`
GROUP BY owner.id ORDER BY tasks.due_date DESC
干杯。
答案 1 :(得分:0)
只能通过纯查询找到这个:
Owner.find_by_sql('SELECT `owners`.*,
(SELECT `tasks`.`due_date`
FROM `tasks`
WHERE `owners`.`id` = `tasks`.`owner_id`
ORDER BY `tasks`.`due_date` DESC LIMIT 1) AS `last_due_date`
FROM `owners`
GROUP BY `owners`.`id`
ORDER BY `last_due_date` DESC;')
如果需要访问last_due_date
,请添加到Owner
型号:
def last_due_date
if attributes['last_due_date']
attributes['last_due_date']
else
tasks.order(due_date: :desc).limit(1).first.due_date if tasks.length > 0
end
end