我有很多相关的模型:
Company has_many :clients (which belongs_to :company)
Client has_many :groups (which belongs_to :client)
Group has_many :orders (which belongs_to :group, :counter_cache => true)
现在,我需要找到所有公司并根据他们的订单对其进行排序,从最高到最低。由于我有群组orders_count列,我很确定我可以通过groups.orders_count订购。然后我需要迭代公司,显示总的订单。
我一直试图想出一个这样的发现。我有一个MySQL数据库,如果它归结为find_by_sql或其他什么。
companies = Company.find(
:all,
:include => { :clients => :groups },
:select => "companies.*, groups.orders_count",
:group => "companies.id",
:order => "groups.orders_count"
)
任何帮助或推动正确的方向赞赏!感谢。
答案 0 :(得分:0)
使用groups.orders_count
可能是一个问题。如果一个公司有两个客户,每个客户有一个组,你在哪个group.orders_count排序?如果我错了,请纠正我。
这不利用counter_cache但它应该可以工作(我的Rails 2.x有点生锈):
companies = Company.all(
:select => "companies.*",
:include => { :clients => [ :groups => :orders ] },
:group => "companies.id",
:order => "count(orders.*) DESC")
答案 1 :(得分:0)
好的,这让我方式太长时间无法理解。我需要一本关于SQL ASAP的书。无论如何,这就是我想要的:
sql = "groups.created_at BETWEEN :start_date AND :end_date"
options = { :start_date => 1.month.ago, :end_date => Date.today }
@companies = Company.all(
:select => 'companies.*, count(orders.id) as counter',
:joins => { :clients => { :groups => :orders } },
:group => 'companies.id',
:order => 'counter DESC',
:conditions => [sql, options]
)
:join将counter作为公司的column_name工作;为什么:包括不,我不知道,如果有人有一个很好的答案,我很想知道为什么。所以我可以写:
@companies.first.counter
并取回该公司的订单总数。
修改强>
发现我得到了几乎我想要的结果,除了在日期范围内没有组/订单的客户。每个结果至少有1个用于反击。
意识到rails连接使用INNER JOIN; LEFT JOIN将返回没有相应子节点的对象。所以我改为:
@companies = Company.all(
:select => 'companies.*, count(orders.id) as counter',
:joins => "LEFT JOIN clients ON clients.company_id = companies.id
LEFT JOIN groups ON groups.client_id = clients.id LEFT JOIN orders ON orders.group_id = groups.id",
:group => 'companies.id',
:order => order_by,
:conditions => [sql, options]
)
我现在也记得:包括急切的加载(不一定是连接),这可能是我无法使用它的原因。这在Rails 3中可能有所不同。请参见此处:Rails :include vs. :joins