Okay let's explain three different way to accomplish what you are looking for.
First of all there is a difference in includes
and joins
Includes just eager load the association with all of the specified columns for associations. It does not allow you to query or select multiple columns from both table. It what joins
do . It allow you to query both tables and select columns of your choice.
def set_sidebar_users
@profiles_sidebar = Profile.select("profiles.first_name,profiles.last_name,profiles.id,users.email as user_email,user_id").joins(:user).order("profile.created_at desc").limit(3) if user_signed_in?
end
It will return you the Profiles
relation which has all of the columns you provided in select
clause. You can get them just like you do for profile object e-g
@profiles_sidebar.first.user_email
will give you user email for this profile.
This approach is best if you want to query on multiple tables or wanna select multiple columns from both table.
2.Pluck
def set_sidebar_users
@profiles_sidebar = Profile.order(created_at: :desc).includes(:user).limit(3).pluck("users.email,profiles.first_name") if user_signed_in?
end
Pluck is just used to get columns from multiple associations but it does not allow you to use the power of ActiveRecord
. It simply returns you the array of selected columns in same order.
like in the first example you can get the user for profile object with @profiles_sidebar.first.user
But with pluck you cannot because it's just a plain array. So that's why your most of the solutions raise error profile.user is not defined
- Association with selected columns.
Now this is option three. In first solution you can get multiple columns on both tables and use the power of ActiveRecord
but it does not eager load the associations. So it will still cost you N+1 queries if you loop through the association on returned result like @profiles_sidebar.map(&:user)
So if you wanna use includes
but want to use selected columns then you should have new association with selected columns and call that association.
e-g
In profile.rb
belongs_to :user_with_selected_column,select: "users.email,users.id"
Now you can include it in above code
def set_sidebar_users
@profiles_sidebar = Profile.order(created_at: :desc).includes(:user_with_selected_column).limit(3) if user_signed_in?
end
Now this will eager load users but will select only email and id of user.
More information can be found on
ActiveRecord includes. Specify included columns
UPDATE
As you asked about the pros for pluck so let's explain it.
As you know pluck
returns you the plain array. So it does not instantiate ActiveRecord object it simply returns you the data returned from database.
So pluck is best to use where you don't need ActiveRecord Objects but just to show the returned data in tabular form.
Select returns you the relations so you can further query on it or call the model methods on it's instances.
So if we summaries it we can say
pluck for model values, select for model objects
More informations can be found at http://gavinmiller.io/2013/getting-to-know-pluck-and-select/