如何在干净的 ruby ActiveRecord 中转换此 sql joins/count 语句

How to convert this sql joins/count statements in clean ruby ActiveRecord

我试图将我的 find_by_sql 语句转换为纯 ActiveRecord 查询,但没有成功。 它是:

Corner.find_by_sql('SELECT corners.id, corners.name, count(members.*) FROM corners LEFT JOIN places ON corners.id = places.ubicacion_id LEFT JOIN members ON places.id = members.place_id GROUP BY corners.id,corners.name ORDER BY corners.name;')

格式很好,sql 表达式将是:

SELECT corners.id,
       corners.name,
       count(members.*)
FROM corners
LEFT JOIN places ON corners.id = places.ubicacion_id
LEFT JOIN members ON places.id = members.place_id
GROUP BY corners.id,
         corners.name
ORDER BY corners.name;

在非常旧的 ActiveRecord 版本中,我的方法是使用 find :all 然后传递选项的散列,但这种方式已被弃用:

Corner.find( :all,
             :joins  => "LEFT JOIN places ON corners.id = places.ubicacion_id",
             :joins  => "LEFT JOIN members ON places.id = members.place_id",
             :group  => "corners.id,corners.name",
             :order  => "corners.name",
             :select => "corners.id, corners.name, count(members.*)"
           )

哪种方法是用 ActiveRecord 方式重写查询的最佳方法?最后一个片段效果很好,但与普通的 sql 相比,使用它没有任何区别:

Corner.joins("LEFT JOIN places ON corners.id = places.ubicacion_id").joins("LEFT JOIN members ON places.id = members.place_id").group("corners.id,corners.name").order("corners.name").select("corners.id, corners.name, count(members.*)")

非常感谢!

看起来您可能想要设置一些模型关系,使它更像 ActiveRecord。您可以在 Active Record Associations 文档中找到有关如何执行此操作的说明。

考虑这些关系:

class Member < ActiveRecord::Base
  belongs_to :place
end

class Place < ActiveRecord::Base
  belongs_to :corner
  has_many :members
end

class Corner < ActiveRecord::Base
  has_many :places, foreign_key: "ubicacion_id"
end

鉴于这些,你应该能够做这样的事情:

Corner.
  select("corners.id, corners.name, count(members.*)").
  joins(:places, :members).
  group("corners.id, corners.name").
  order("corners.name")

查询中链接的每个方法都将逐步优化查询,就像构建本机 SQL 语句一样。您可以在 Active Record Query Interface

中找到这些方法的官方文档