在我的部分代码中,我需要获取用户的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中返回
#<User::ActiveRecord_AssociationRelation:0x007fb0f9c64da8>
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 [#<User id: 144004, created_at: "2015-08-06 08:55:11", updated_at: "2015-08-06 08:55:11", email: "user_2@test.com", token: "rpf5fqf5bs1ofme6aq66fwtcz", reset_password_token: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, disabled: false, first_name: "John_2", last_name: "Rivers_4", is_owner: false, organisation_id: 235826, encrypted_password: "$2a$04$8ev1j...f6ICL.ezS....", reset_password_sent_at: nil, default_language: nil, uid: nil, api_key: "rmhh...noyn">]>
[144004]
[]
奇怪的是。我有id的用户。 map
可以获得它们。 pluck
没有。
我也不了解sql日志。如何在sql日志中没有任何选择的情况下获得map id
结果?缓存?
答案 0 :(得分:3)
pluck
无法在数组上运行,它适用于ActiveRecord::Relation
,其目标是避免进行完整查询以仅获取ID。
从db中检索完所有列后,您只需map
即可。
您在执行self.users -= users_to_remove
时创建数组,或者甚至在执行.present?
时创建数组,因为您应该使用.exists?
答案 1 :(得分:1)
这一行:
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不属于“自我”。不久之后(你之前就删除了它们),所以它们不会被退回。