从连接表中获取聚合信息(ActiveRecord)

时间:2014-10-25 17:13:52

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

class Foo < ActiveRecord::Base
  has_many :bars

class Bar < ActiveRecord::Base
   belongs_to :foo
   attr_accessible :awesome

您好。我是铁杆的新手。我需要让所有的Foos加入他们的棒数,这些棒很棒而且不棒。基本上这个SQL:

SELECT foo.*, SS1.ac as awesome_count, SS2.ac as lame_count
FROM foo 
JOIN (SELECT foo_id, count(*) AS ac FROM bar WHERE awesome = TRUE GROUP BY foo_id) AS SS1 ON SS1.foo_id = foo.id
JOIN (SELECT foo_id, count(*) AS ac FROM bar WHERE awesome = FALSE GROUP BY foo_id) AS SS2 ON SS2.foo_id = foo.id

我不确定如何通过ActiveRecord魔法(ala Foo.joins(:bar)等)来实现这一目标。

我确实尝试过使用find_by_sql,但我无法获得&#34; awesome_count&#34;和&#34; lame_count&#34;价值回归:

pry(main)> some_foo  = Foo.find_by_sql([ **THE ABOVE SQL** ])
pry(main)> some_foo.awesome_count
NoMethodError: undefined method `awesome_count' for #<Foo:0x007ad76450b70>

有没有办法通过ActiveRecord ORM魔术来做到这一点? 有没有办法用find_by_sql做到这一点?

1 个答案:

答案 0 :(得分:0)

在Sqlite数据库上尝试此查询:

Foo.find_by_sql("SELECT foos.*, ss1.ac as awesome_count, SS2.ac as lame_count from foos 
left outer join (select foo_id, count(*) as ac from bars where awesome = 't' group by 
foo_id) as SS1 on SS1.foo_id = foos.id left outer join (select foo_id, count(*) AS ac from    
bars where awesome = 'f' group by foo_id) as ss2 on ss2.foo_id = foos.id")

包含样本数据

<Foo id: 1, name: "foo 1", created_at: "2014-10-25 17:40:23", updated_at: "2014-10-25 17:40:23">,
<Foo id: 2, name: "foo 2", created_at: "2014-10-25 17:40:26", updated_at: "2014-10-25 17:40:26">,
<Foo id: 3, name: "foo 3", created_at: "2014-10-25 17:40:28", updated_at: "2014-10-25 17:40:28">,
<Foo id: 4, name: "foo 4", created_at: "2014-10-25 17:40:31", updated_at: "2014-10-25 17:40:31">]

[#<Bar id: 1, foo_id: 1, awesome: false, created_at: "2014-10-25 17:44:00", updated_at: "2014-10-25 18:00:14", address: "bla">,
<Bar id: 2, foo_id: 2, awesome: false, created_at: "2014-10-25 17:44:14", updated_at: "2014-10-25 18:00:22", address: "bla">,
<Bar id: 3, foo_id: 2, awesome: true, created_at: "2014-10-25 17:44:26", updated_at: "2014-10-25 17:44:26", address: nil>,
<Bar id: 4, foo_id: 3, awesome: true, created_at: "2014-10-25 17:44:31", updated_at: "2014-10-25 17:44:31", address: nil>,
<Bar id: 5, foo_id: 3, awesome: true, created_at: "2014-10-25 17:44:34", updated_at: "2014-10-25 17:44:34", address: nil>,
<Bar id: 6, foo_id: 3, awesome: false, created_at: "2014-10-25 17:44:38", updated_at: "2014-10-25 17:44:38", address: nil>,
<Bar id: 7, foo_id: 4, awesome: false, created_at: "2014-10-25 17:44:44", updated_at: "2014-10-25 17:44:44", address: nil>,
<Bar id: 8, foo_id: 4, awesome: false, created_at: "2014-10-25 17:44:46", updated_at: "2014-10-25 17:44:46", address: nil>] Foo id: 1, name: "foo 1", created_at: "2014-10-25 17:40:23", updated_at: "2014-10-25 17:40:23

我能得到:

result.first.awesome_count - &gt;零 result.first.lame_count - &gt; 1

result.second.awesome_count - &gt; 1 result.second.lame_count - &gt; 1