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查询不同。 #map
是SELECT * FROM ...
,而#pluck
是SELECT id FROM...
当查询到达数据库时,ID不再属于“self”(您之前就删除了它们),因此不会返回它们。
pluck
不适用于数组,它适用于ActiveRecord::Relation
,它的目标是避免进行完整查询以仅获取ID。
一旦从db中检索了所有列,就可以map
所需的内容。
你做self.users -= users_to_remove
,或者甚至当你做.present?
时创建数组.present?
,既然你应该使用.exists?