2011-09-08 26 views
0

我有一个城市模型和一个商业模型。 Business belogs_to:city如何找到所有有孩子的城市?

现在我想定义一个视图,列出只有那些有孩子的城市(在这种情况下是商业)。不应该考虑空城市(意味着仍然没有业务的城市)。如果可能的话,清单应该按照大多数企业位居前列的方式进行排序。

我发现了这样一个解决方案:

@cities = City.find :all, 
     :joins => "INNER JOIN businesses ON businesses.city_id = cities.id", 
     :select => "cities.*, count(businesses.id) businesses_count", 
     :group => "businesses.city_id HAVING businesses_count > 0", 
     :order => "businesses_count desc" 

这工作正常(排序尚未完成),但据我了解,这将不使用Rails 3.1和3.2的工作(我用3.0现在) 。请参阅http://m.onkey.org/active-record-query-interface

任何人都可以让我知道如何以Rails 3.1和3.2的方式定义我的@cities吗?

谢谢!

@KandadaBoggu:

太好了,我非常喜欢你的答案2),谢谢!

只是评论:

我 轨道迁移产生迁移add_businesses_count_to_cities businesses_count:整数

然后我需要编辑的迁移:

class AddBusinessesCountToCities < ActiveRecord::Migration 
    def self.up 
    add_column :cities, :businesses_count, :integer, :default => 0 

    City.reset_column_information 

    City.all.each do |c| 
     c.update_attribute :businesses_count, c.businesses.count 
    end 
    end 

    def self.down 
    remove_column :cities, :businesses_count 
    end 
end 

这是很重要的设置默认值为0,然后用当前的企业数量更新城市。

我还添加了counter_cache孩子(业务),如: belongs_to的:城市:counter_cache =>真

这样,它的伟大工程。

回答

3

1)在不排序:

City.joins(:businesses).select("DISTINCT cities.*") 

2)使用counter_cache

一个integer柱称为business_count添加到cities表。

class City < ActiveRecord::Base 
    has_many :businesses, :counter_cache => :business_count 
end 

现在你可以选择城市如下:

City.where("business_count > 0").order(:business_count) 

3)使用group by

City.joins(" 
    (SELECT a.id, COUNT(*) as business_count 
    FROM cities a, businesses b 
    WHERE a.id = b.city_id 
    GROUP BY a.id 
    ) c ON cities.id = c.id "). 
select("cities.*, c.business_count AS business_count"). 
order(:business_count) 
相关问题