我有一个涉及3个模型的复杂SQL查询,根据时间操作创建虚拟属性...理想情况下,我希望使用ActiveRecord arel方法生成它,以便它更好,但我不知道如何。
find_by_sql <<--sql
SELECT username, count(*) as records, AVG(time_taken) as time_taken
FROM (
SELECT TIMESTAMPDIFF(HOUR, posts.created_at, reports.created_at) as time_taken,
users.username as username
FROM reports, users, posts
WHERE reports.user_id = users.id AND
reports.post_id = posts.id
) AS dashboard_data # this name is unused, but apparently required
GROUP BY username
sql
有没有办法在ActiveRecord中做这样的事情?或者是原始的sql是做这样复杂的东西的唯一方法吗?
答案 0 :(得分:0)
除非它来自一张桌子,否则你会被困在这样的事情上。您从子查询中获取,这超出了ActiveRecord的范围。 ORM旨在将对象映射到明确定义的表中的特定行。
你有时可以假装它,这样你做的任何事情看起来都像桌子一样,它使用SQL视图。 ActiveRecord很乐意使用视图,如果它可以像表一样查询。例如,如果它定义了id
列作为某种主键,那么它应该起作用。在您的情况下,您可以GROUP BY users.id
公开users.id AS id
以及users.username
。
答案 1 :(得分:0)
我认为这相当于你正在做的事情:
User.joins({:reports=>:posts}).
group("users.username").
select("users.username,
count(*) as records,
avg(timestampdiff(hour, posts.created_at, reports.created_at)) as time_taken")