Ruby on rails Rails:为什么Pulk方法返回uniq值?
我有一个Ruby on rails Rails:为什么Pulk方法返回uniq值?,ruby-on-rails,Ruby On Rails,我有一个帐户模型,其中有一列角色。 我想通过在日期创建的来选择不同的角色(例如2018年1月1日创建的所有不同角色等),并仅获取列角色的值。 选择不同的角色可以很好地作为一个查询,但是当涉及到获取值时,我会得到意想不到的结果 如果我只是对所有查询结果使用map函数,那么一切正常,SQL查询看起来也不错 Account.where(id: 1..10).select(:created_at, :role).distinct.map(&:role) Account Load (1.0ms)
帐户
模型,其中有一列角色
。
我想通过在日期创建的来选择不同的角色(例如2018年1月1日创建的所有不同角色等),并仅获取列角色
的值。
选择不同的角色可以很好地作为一个查询,但是当涉及到获取值时,我会得到意想不到的结果
如果我只是对所有查询结果使用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)
更改为.pulk(:role)
,这在定义上是相同的,pulk
方法首先删除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"]
在编写的pulk
文档中,只有当代码看起来像.pulk('distinct role')
为什么我的情况是这样?这是一些未记录的功能吗 对于你的问题“为什么在我的情况下它是这样工作的?”的简短回答是因为它应该是这样工作的。你说:
在Pull文档中。这样写的话,只有当代码看起来像.pull('distinct role')
这是不准确的。您引用的文档显示了这样一个示例,作为使用DISTINCT
进行提取的一种方法,但没有说明这是应用DISTINCT
SQL修饰符的唯一方法。由于已将.distinct
添加到ActiveRecord
关系中,因此生成的查询将是选择distinct
。这会提示SQL为您提供唯一的值,而不是pull
方法Pull
只返回DB给它的确切内容
对于在
处创建的和角色的不同组合使用Pull后实现目标的方法,您可以使用组:
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_at
和role
为您提供唯一的行组合(如果同一role
与多个created_at
值关联,则该角色可能会多次出现)。然后,.pull(:role)
将只获取角色的值
我不明白为什么需要使用select,您可以使用where
和pull
获取和筛选数据,而where
优于select
,因为select
从数据库
中获取了您指定的所有数据,并对它们进行迭代,以在ruby级别过滤数据,但使用where
可在数据库
级别过滤掉这些数据。使用pull时,请删除select,你会得到同样的结果。在使用Pulk时,AR似乎以任何方式改进了查询以添加特定属性,这种方式如果将foo和bar传递给Pulk,您将得到不同的model.foo,model.bar。注意:如果您使用AR,并且需要作为结果的数组,您不需要映射,它可以工作,但这是Pulk的场景。使用时,选择(:created_at,:role).distinct
它通过这两个属性进行distinct,在任何情况下,如果添加PULLC,它将覆盖第一个distinct并使用PULLC方法中指定的属性。请记住,如果以那种方式使用Pull,您不需要选择。where.select(:created_at,:role)。distinct.pull(:role)
=where.distinct.pull(:role)
“将.map(&:role)更改为.pull(:role),它们定义相同”-noop,它们不相同,甚至不相近<代码>映射是一种通用转换Pulk
是ActiveRecord查询生成器中的一个修饰符。哦,关于分组依据的评论真好!我通过使用map
解决了我的问题,但是groupby
在速度方面看起来更合适。