Reg*_*ieB 8 ruby sql activerecord ruby-on-rails
我想显示计数中使用的SQL.但是,Model.count.to_sql无法工作,因为count返回没有to_sql方法的FixNum.我认为最简单的解决方案是这样做:
Model.where(nil).to_sql.sub(/SELECT.*FROM/, "SELECT COUNT(*) FROM")
这会创建Model.count与之相同的SQL ,但它是否会导致问题进一步发生?例如,如果我添加一个复杂的where子句和一些连接.
有没有更好的方法呢?
您可能想深入了解 Arel:
Model.select(Arel.star.count).to_sql
旁白:我发现我经常想要查找子计数,因此我将 count(*) 嵌入到另一个查询中:
child_counts = ChildModel.select(Arel.star.count)
                         .where(Model.arel_attribute(:id).eq(
                                ChildModel.arel_attribute(:model_id)))
Model.select(Arel.star).select(child_counts.as("child_count"))
     .order(:id).limit(10).to_sql
然后为您提供每个模型的所有子项计数:
SELECT  *,
        (
          SELECT COUNT(*)
          FROM "child_models"
          WHERE "models"."id" = "child_models"."model_id"
        ) child_count
FROM "models"
ORDER BY "models"."id" ASC
LIMIT 10
祝你好运
更新:
不确定您是否正在尝试以通用方式解决此问题。也不确定您在Model.
我们确实有一个方法,可以自动调用放入 ui 层的查询的计数。我发现 usingcount(:all)比 simple 更稳定count,但听起来这与您的用例不重叠。也许您可以使用except我们使用的子句改进您的解决方案:
SELECT  *,
        (
          SELECT COUNT(*)
          FROM "child_models"
          WHERE "models"."id" = "child_models"."model_id"
        ) child_count
FROM "models"
ORDER BY "models"."id" ASC
LIMIT 10
where 子句所需的子句where和连接对我们来说工作得很好。我们倾向于保留连接和 where 子句,因为它需要成为计数的一部分。虽然你肯定想删除includes(在我看来应该由rails自动删除),但是references(更棘手,特别是在它引用 ahas_many并需要一个不同的情况下)开始在那里抛出扳手。如果您需要使用引用,您可以将它们转换为left_join.
您可能需要仔细检查这些“连接”方法采用的参数。其中一些采用表名称,另一些采用关系名称。后来的 Rails 版本变得更好,并采用关系名称 - 确保您正在查看正确版本的 Rails 文档。
另外,在我们的例子中,我们花费更多的时间尝试获得具有更复杂关系的子选择,我们必须进行一些修改。看起来我们没有那么多处理 where 子句。 参考2