58574

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

Question:

In part of my code I need to grab users's id but pluck doesn't grab them. Only map(&:id) can do it. I was wondering why.

I've wrote a quick and dirty block of code to find what's happen

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

Who return in my 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: []

And in my test

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] []

The strange thing is. I have user with id. map can get them. pluck not.

I don't understand sql log also. How can I get map id result without any select in sql log? Caching ?

Answer1:

This line:

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

Doesn't fire off SQL query immediately. It sends the request whenever you need some details of these users. And it caches the result in SQL cache (so when the same request goes to DB again, it intercepted by Rails and never reaches the database).

So when you call:

users_to_remove.map(&:id)

It uses that cached result. But when you use

users_to_remove.pluck(:id)

It re-fetches the result, because the actual SQL query differs. With #map it is SELECT * FROM ..., and with #pluck it's SELECT id FROM.... And when query reaches the database, IDs doesn't belong to 'self' any longer (you deleted them right before that), so they aren't returned.

Answer2:

pluck doesnt work on an array, it works on an ActiveRecord::Relation, it's goal is to avoid to make a full query to only get the ids.

Once you've retrieved all columns from db, you can just map what you need.

You create the array when you do self.users -= users_to_remove, or maybe even when you do .present?, since you should use .exists?

Recommend

  • How to assert that a text only exists 1 time in Mink
  • Datagridview Button Click event not firing
  • UWSGI logrotation
  • MySQL Create Trigger Insert Content into another table from the same database
  • Entity Framework and Mysql fail to insert
  • How to use ASP.NET Role and Membership in Winform and C# [closed]
  • How to get column and values dictionary in SQLAlchemy model?
  • How to set image path in linux command line?
  • Basic Authentication appears to have no security header
  • Go language, scanning embeded struct with sqlx.StructScan
  • Executing python script from php
  • How to execute java functions/script in PHP
  • map(&:id) work but not pluck(:id)
  • @Mock, NullPointerException
  • Flask-SQLAlchemy PyMySQL - Access Denied Error
  • Using Select and where statement in Criteria
  • How do I write an item to a DynamoDb with the AWS DynamoDB DocumentClient?
  • How to Add Polymorphic Comments to Feed?
  • User messaging system
  • Laravel: Getting Session ID oddly truncates when using foreach
  • D3 get axis values on zoom event
  • Jetty Server not starting: Unable to establish loopback connection
  • Django: Count of Group Elements
  • Getting last autonumber in access
  • How to make a tree having multiple type of nodes and each node can have multiple child nodes in java
  • How to check if every primary key value is being referenced as foreign key in another table
  • MySQL WHERE-condition in procedure ignored
  • How to handle AllServersUnavailable Exception
  • Display Images one by one with next and previous functionality
  • ORA-29908: missing primary invocation for ancillary operator
  • How to get next/previous record number?
  • How do you join a server to an Active Directory (domain)?
  • How does Linux kernel interrupt the application?