2013-01-14 65 views
1

是否有可能使用rails做这样的查询?SELECT ... AS ...与ActiveRecord

SELECT items.*, (select count(*) from ads where item_id = items.id) as adscount WHERE 1 

然后像这样访问这个字段?

@item.adscount 

例如,对于每个项目,都有大约100个广告。 而在项目索引视图中,我需要显示每个项目有多少广告。

现在我只发现了如何做一个唯一的查询为每个项目,例如:

select count(*) from ads where item_id = 1 
select count(*) from ads where item_id = 2 
select count(*) from ads where item_id = 3 
etc 

编辑:

提出一项反缓存列。

这给了我巨大的性能提升。

+0

控制器做到这一点我敢肯定,99.99% Item.ads.count将生成您需要的查询。 (其中广告belongs_to项目和项目has_many广告 – iced

+0

其实你只需要'item.rb'模型中的'has_many:ads'部分和'@ item.ads.count'就可以做到这一点(你只需要'belongs_to :项目',如果你打算通过广告访问该项目) –

+0

是的,@ item.ads.count会计算每个项目的广告,但如果我有100个项目 - 这是100个查询,这不是最好的。几乎觉得我应该为Items表制作一个Counter缓存列 – user1885058

回答

0

使用Rails的Counter Cachehttp://railscasts.com/episodes/23-counter-cache-column

然后你就可以像@item.ads.count那样使用它,这不会产生任何数据库查询。 而且除了(如果你真的想用它自己的方式),你可以创建一个模型方法

def adscount 
    self.ads.count 
end 
1

一个解决方案是使用Scopes。你可以拥有它是一种特殊的查询,像

class Item < ActiveRecord::Base 
    scope :with_adscount, select("items.*, (select count(*) from ads where item_id = items.id) as adscount") 
end 

然后在控制器,或任何你从查询,你可以使用它像这样:

@items = Item.with_adscount 
@items.each do |item| 
    item.adscount 
end 

或者,你可以把它作为使用default scope

class Item < ActiveRecord::Base 
    default_scope select("items.*, (select count(*) from ads where item_id = items.id) as adscount") 
end 
0

您可以在这样

a = MyModel.find_by_sql('SELECT *, (select count(*) from table) as adscount FROM table').first 
a.adscount #total 
a.column1 #value of a column 
a.column2 #value of another column