【问题标题】:Rails/Arel: select case sum along with modelRails / Arel:选择案例总和以及模型
【发布时间】:2021-10-14 16:02:30
【问题描述】:

我有一个名为 Post(表 posts)的模型,它与名为 User(表 users)的模型有关系,在 Post 模型中被称为“上传者”(posts 表有一个列称为uploader_id,这是表用户的id)。一个用户可以有许多帖子,其中一些可以删除(通过posts 中的is_deleted 布尔列标记)。

如何获取包含帖子总数和已删除帖子数的用户列表?

::Post
  .select(
    Arel.star.count.as("total"),
    Arel::Nodes::Case.new.when(Post.arel_table[:is_deleted]).then(1).sum.as("deleted_count"),
    :uploader
   )
  .joins(:uploader)
  .group(:uploader)
  .order(:total, :deleted_count)
  .limit(20)

这不起作用。我需要将用户作为模型返回,uploader_id 不够。

我已经尝试过很多次尝试,但无论我做什么,我都无法弄清楚。它要么尝试将“#<:nodes::count:0x0000565... sql nil>

让我非常沮丧的是,如果我只想要帖子总数和用户,这反而可行:

::Post
  .joins(:uploader)
  .group(:uploader)
  .order(Arel.sql("count(*) desc"))
  .limit(20)
  .count

我只是不知道如何添加条件案例总和,我是 Rails 的新手,文档没有帮助。

【问题讨论】:

    标签: ruby-on-rails ruby arel


    【解决方案1】:

    “我如何获得包含帖子总数和已删除帖子数量的用户列表?” 看来您的方向是错误的。 最好从 User 开始,因为您希望返回 User 对象。

    另外Post.arel_table[:is_deleted] 不是一个条件,它应该是Post.arel_table[:is_deleted].eq(1) 或数据库中的任何“真”。

    请尝试以下方法:

    User.left_joins(:posts)
      .select(
         User.arel_table[Arel.star],
         Post.arel_table[Arel.star].count.as('total_posts'),
         Arel::Nodes::Case.new 
           .when(Post.arel_table[:is_deleted].eq(1)).then(1)
           .else(0).sum.as('deleted_count'))
      .group(:id)
      .order(
        Post.arel_table[Arel.star].count, 
        Arel::Nodes::Case.new 
          .when(Post.arel_table[:is_deleted].eq(1)).then(1)
          .else(0).sum)
      .limit(20)
    

    【讨论】:

    • 好答案。如果您使用的是 Postgres,则可以使用 count(posts.*) filter where is_deleted 而不是 case 语句。
    • @max 非常好。不幸的是,Arel 的其中一个地方不足。虽然我现在还没有费心去尝试(尽管在某些时候我可能会尝试),但我无法想象通过 Arel 对象编写的表达式看起来会多么令人费解。
    猜你喜欢
    • 1970-01-01
    • 2011-04-03
    • 2017-01-22
    • 1970-01-01
    • 2014-05-09
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多