Rails:为什么pluck方法返回uniq值?

时间:2018-02-07 00:42:23

标签: ruby-on-rails

我有一个Account模型,其中包含role列。 我希望按created_at日期选择不同的角色(例如,在01.01.2018等创建的所有不同角色等)并仅获取列role的值。 选择不同的角色可以很好地作为查询,但是当获取值时,我会得到意想不到的结果。

如果我只是在所有查询结果上使用map函数,那么一切正常并且SQL查询看起来很好。

Account.where(id: 1..10).select(:created_at, :role).distinct.map(&:role)
Account Load (1.0ms)  SELECT DISTINCT "accounts"."created_at", "accounts"."role" FROM "accounts" WHERE ("accounts"."id" BETWEEN $1 AND $2)  [["id", 1], ["id", 10]]
=> ["admin", "manager", "manager", "manager", "manager", "manager", "manager", "manager", "manager"]

但是,如果我想将.map(&:role)更改为.pluck(:role),根据定义,pluck方法会删除第一个distinct条件并仅保留distinct我们可以在查询开头看到角色。

Account.where(id: 1..10).select(:created_at, :role).distinct.pluck(:role)
(0.7ms)  SELECT DISTINCT "accounts"."role" FROM "accounts" WHERE ("accounts"."id" BETWEEN $1 AND $2)  [["id", 1], ["id", 10]]
=> ["admin", "manager"]

pluck文档(apidock)中,只有当代码看起来像.pluck('distinct role')

时才会使用distinct

为什么它在我的情况下是这样的?这是一些无证的功能吗?

1 个答案:

答案 0 :(得分:2)

对你的问题的简短回答"为什么它在我的案例中是这样的?"是因为它应该像这样工作。你说:

  

在pluck文档中。 。 。它的编写,只有当代码看起来像.pluck('distinct role')

时,pluck才会使用distinct

这不准确。您引用的文档显示了一个这样的示例,作为采用DISTINCT的方法,但并未说明这是唯一的方式来应用DISTINCT SQL修饰符。由于您已将.distinct添加到ActiveRecord关系中,因此生成的查询将为SELECT DISTINCT。这会提示SQL为您提供唯一值,而不是pluck方法; pluck只会返回您的数据库所提供的内容。

要了解pluck使用created_atrole的不同组合后实现目标的方法,您可以改为使用group

Account.where(id: 1..10).group(:created_at, :role).pluck(:role)
# => SELECT "accounts"."role" FROM "accounts" WHERE ("accounts"."id" BETWEEN $1 AND $2) GROUP BY "accounts"."created_at", "accounts"."role"  [["id", 1], ["id", 10]]

.group(:created_at, :role)调用(添加GROUP BY SQL子句)将根据created_atrole为您提供独特的行组合(相同的role如果它与多个created_at值相关联,则可能会多次出现。然后,.pluck(:role)将仅采用role的值。