In this tutorial we will see how we can use pluck and select in rails active record queries.
Select is used to fetch records with specific attributes. It returns ActiveRecord::Relation object.
Project.select(:id)
Project Load (41.5ms) SELECT "projects"."id" FROM "projects"
=> #<ActiveRecord::Relation [#<Project id: 1> #<Project id: 2> #<Project id: 3>]>
select with multiple attributes:
Project.select(:id, :name)
Project Load (0.3ms) SELECT "projects"."id", "projects"."name" FROM "projects"
=> #<ActiveRecord::Relation [#<Project id: 1, name: "newproject">#<Project id: 2, name: "project2">#<Project id: 3, name: "project3">]>
Pluck can be used the same way select is used, however it returns array of selected attributes. It skips the overhead of building ActiveRecord models so the performance is faster than select. Pluck was introduced with Rails 3.2
Project.pluck(:id)
(0.3ms) SELECT "projects"."id" FROM "projects"
=> [1, 2, 3]
pluck with multiple attributes:
Project.pluck(:id, :name)
(0.4ms) SELECT "projects"."id", "projects"."name" FROM "projects"
=> [[1, "newproject"], [2, "project2"], [3, "project3"]]
NOTE: Select takes much time on building ActiveRecord models. On large dataset pluck is much faster than select. Pluck should be used when only column values are required. Select should be used when object is required. pluck is an eager method and it hits the database immediately when called.
Lets see the example below:
User.where(id: Project.distinct.pluck(:created_by))
(0.3ms) SELECT "projects"."created_by" FROM "projects"
User Load (26.2ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (2)
=> #<ActiveRecord::Relation [#<User id: 2, email: "ankur@xyz.com", role: "admin", password_digest: "$2a$10$XGnsqHk9llpwwuCH1W/M0.8rnWLgE1gwvJrsY/2yfWV...", created_at: "2016-04-13 06:56:31", updated_at: "2016-04-13 06:56:31">]>
2.2.1 :024 >
This query hits database twice. If we use select here the data will fetch in a single query. See the example below:
User.where(id: Project.distinct.select(:created_by))
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (SELECT "projects"."created_by" FROM "projects")
=> #<ActiveRecord::Relation [#<User id: 2, email: "ankur@xyz.com", role: "admin", password_digest: "$2a$10$XGnsqHk9llpwwuCH1W/M0.8rnWLgE1gwvJrsY/2yfWV...", created_at: "2016-04-13 06:56:31", updated_at: "2016-04-13 06:56:31">]>
2.2.1 :026 >
0 Comment(s)