map(&:id)work但not pluck(:id)

在我的部分代码中,我需要获取用户的id,但是pluck不会抓住它们。 只有map(&:id)可以做到。 我想知道为什么。

我写了一个快速而又脏的代码块来查找发生了什么

  def remove_users user_ids p users_to_remove.class users_to_remove = self.users.where(id: user_ids) if users_to_remove.present? self.users -= users_to_remove self.save p users_to_remove.class p users_to_remove Rails::logger.info "\n#{users_to_remove}\n" users_to_remove_map = users_to_remove.map(&:id) p users_to_remove_map Rails::logger.info "\nmap id: #{users_to_remove_map}\n" users_to_remove_pluck = users_to_remove.pluck(:id) p users_to_remove_pluck Rails::logger.info "\npluck id: #{users_to_remove_pluck}\n" #... end self.user_ids end 

谁在我的test.log中返回

 # map id: [144004] (0.3ms) SELECT "users"."id" FROM "users" INNER JOIN "groups_users" ON "users"."id" = "groups_users"."user_id" WHERE "groups_users"."group_id" = $1 AND "users"."id" IN (144004, 144005) [["group_id", 235819]] pluck id: [] 

在我的测试中

 User::ActiveRecord_AssociationRelation User::ActiveRecord_AssociationRelation #<ActiveRecord::AssociationRelation [#]> [144004] [] 

奇怪的是。 我有id的用户。 map可以得到它们。 没有。

我也不懂sql日志。 如何在sql日志中没有任何选择的情况下获取map id结果? 缓存?

这一行:

 users_to_remove = self.users.where(id: user_ids) 

不立即触发SQL查询。 只要您需要这些用户的某些详细信息,它就会发送请求。 它将结果缓存在SQL缓存中(因此当相同的请求再次进入DB时,它会被Rails截获并且永远不会到达数据库)。

所以当你打电话时:

 users_to_remove.map(&:id) 

它使用缓存的结果。 但是当你使用的时候

 users_to_remove.pluck(:id) 

它重新获取结果,因为实际的SQL查询不同。 #mapSELECT * FROM ... ,而#pluckSELECT id FROM... 当查询到达数据库时,ID不再属于“self”(您之前就删除了它们),因此不会返回它们。

pluck不适用于数组,它适用于ActiveRecord::Relation ,它的目标是避免进行完整查询以仅获取ID。

一旦从db中检索了所有列,就可以map所需的内容。

你做self.users -= users_to_remove ,或者甚至当你做.present?时创建数组.present? ,既然你应该使用.exists?