Rails使用SQL提前排序

问题描述 投票:2回答:2

我有User模型,它有一些属性,如is_admin,is_verified,并且还与其他模型(如徽章和活动)相关联。

我在HTML中有表格设计,默认情况下,用户将按is_verified,然后是is_admin,然后是徽章数量,然后是活动数量。但我不知道如何创建一个。

我试过像这样的示例代码:

users = User.all.limit(10)
users.order(is_verified: :true).order(is_admin: :true).order(users.map{|user| user.badges.count}).order(users.map{|user| user.activites.count})

但这不起作用,因为订单只接受:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]

你有任何新方法可以做到这一点,我是新来的查询?非常感谢您的帮助。

我有这样的样本设计:enter image description here

sql ruby-on-rails postgresql sqlite
2个回答
0
投票

order接受多个args,因此您可以使用以下内容:

users.order(is_verified: :desc, is_admin: :desc)
     .order('badges_count DESC', 'activities_count DESC')

对于boolean列,它们通常存储在数据库中作为1true0false,因此desc方向。如果你没有将这些列默认为一个或另一个(大概是false),你可能想要调整到(即)order("is_verified DESC NULLS LAST", ...)

这需要一些重构才能有效运行,依靠counter_caches进行徽章和活动。如果你要定期查询,我强烈建议加入这个。有一个很好的指导here

所需要的只是:

  • activities_countbadges_count的新专栏
  • counter_cache: true在协会的belongs_to一侧设置
  • 使用this method重新计数的计数器,即User.reset_counters(:badges, :activities)

否则,您可以使用:

User.left_joins(:badges, :activities)
    .order(is_verified: :desc, is_admin: :desc)
    .group("badges.id", "activities.id")
    .order('COUNT(badges.id) DESC', 'COUNT(activities.id) DESC')

如果您对它的输出很好奇,可以调用to_sql来查找它实际上是如何从数据库中调用数据的。

快来了,让我知道你是怎么过的 - 如果你有任何问题,很乐意提供帮助!


0
投票

您可以尝试使用数据库本身进行排序,这比在加载的记录数组上执行排序更快。默认情况下,如果按降序排序任何布尔字段,则所有布尔值为true的记录将首先出现。最终查询可能看起来像,

User.order(is_verified: :desc).order(is_admin: :desc).
  left_joins(:badges).
  group(:id).
  order("count(badges.id) desc")
  left_joins(:activities)
  group(:id).
  order("count(activities.id) desc")

左连接(左外连接)包括具有零个或多个关联记录的文档。你可以在the documentation page找到细节。

希望能帮助到你 !

© www.soinside.com 2019 - 2024. All rights reserved.