如何让这个复杂的查询与ActiveRecord一起使用?

时间:2012-03-06 20:22:00

标签: ruby-on-rails ruby-on-rails-3 activerecord

我有一个涉及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是做这样复杂的东西的唯一方法吗?

2 个答案:

答案 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")