0

我有许多相关的模型:

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)

现在,我需要找到所有公司并按订单从高到低对它们进行排序。由于我有 groups_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"
)

任何帮助或推动正确的方向表示赞赏!谢谢。

4

2 回答 2

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")
于 2012-09-12T19:19:22.933 回答
0

好吧,这花了我长时间才弄清楚。我需要尽快拿起一本关于 SQL 的书。无论如何,这就是我想要的:

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

:joins 使 counter 作为公司的 column_name 工作;为什么 :includes 没有,我不知道,如果有人有一个很好的答案,我很想知道为什么。所以我可以写:

@companies.first.counter

并取回该公司的订单总数。

编辑

发现我几乎得到了我想要的结果,除了在某个日期范围内没有组/订单的客户。每个结果至少有 1 个用于计数器。

意识到rails join使用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]
)

我现在还记得 :includes 急切加载(不一定要加入),这可能是我不能使用它的原因。这在 Rails 3 中可能有所不同。请参见此处:Rails :include 与 :joins

于 2012-09-13T00:38:31.673 回答