Sometimes, we need to remove selected columns and select new columns for the query being done. Rails 6 introduces reselect on ActiveRecord#Relation on query methods. This lets us easily select new columns.
Consider, Post schema as given below.
class Post < ApplicationRecord {
:id => :integer,
:user_id => :integer,
:title => :string,
:description => :text,
:status => :string,
:created_at => :datetime,
:updated_at => :datetime
}
Now let’s say, we need to show post ID, title and description for all the posts on UI of user with ID = 5. In order to get these attributes, we will query as given below with ActiveRecord.
posts = Post.where(user_id: 5).select(:id, :user_id, :title, :description)
This will create SQL as given below.
SELECT "posts"."id", "posts"."title", "posts"."description" FROM "posts" WHERE "posts"."user_id" = $1 ORDER BY "posts"."id" [["user_id", 5]
Now let\’s say, we have a change in the requirement and we want to know statuses of all the post published by user with ID = 5.
Without reselect
We will have to unscope current selected arguments and the again apply select with new columns. This can be achieved as given below.
posts = posts.unscope(:select).select(:status)
With reselect
Instead of unscope and select operation, this can be achieve using reselect as given below.
posts = post.reselect(:status)
Both versions mentioned above will create a SQL statement as given below.
SELECT "posts"."status" FROM "posts" WHERE "posts"."user_id" = $1 [["user_id", 5]]
Thus reselect just a short-hand for unscope and then select operation. Here is the source code for reference.
# File activerecord/lib/active_record/relation/query_methods.rb, line 284
def reselect(*args)
check_if_method_has_arguments!(:reselect, args)
spawn.reselect!(*args)
end