Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何让这个复杂的查询与ActiveRecord一起工作?_Ruby On Rails_Ruby On Rails 3_Activerecord - Fatal编程技术网

Ruby on rails 如何让这个复杂的查询与ActiveRecord一起工作?

Ruby on rails 如何让这个复杂的查询与ActiveRecord一起工作?,ruby-on-rails,ruby-on-rails-3,activerecord,Ruby On Rails,Ruby On Rails 3,Activerecord,我有一个复杂的SQL查询,涉及3个模型,创建基于非时间操作的虚拟属性。。。理想情况下,我希望使用ActiveRecord arel方法来生成这个,这样会更好,但我不知道如何生成 find_by_sql <<--sql SELECT username, count(*) as records, AVG(time_taken) as time_taken FROM ( SELECT TIMESTAMPDIFF(HOUR, posts.created_at,

我有一个复杂的SQL查询,涉及3个模型,创建基于非时间操作的虚拟属性。。。理想情况下,我希望使用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是处理此类复杂内容的唯一方法吗?

除非它来自一个表,否则您将无法执行此类操作。您正在从一个子查询中获取数据,这远远超出了ActiveRecord的预期范围。ORM设计用于将对象映射到定义良好的表中的特定行


有时,您可以伪造它,这样无论您在做什么,它都可以通过使用SQL视图工作。如果可以像查询表一样查询视图,ActiveRecord将很乐意使用它。例如,如果它定义了一个id列作为某种主键,那么它应该可以工作。在您的情况下,您可以按users.id分组,并将users.id作为id以及users.username公开。

我认为这相当于您所做的:

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