さて、探しているものを達成するための 3 つの異なる方法を説明しましょう。
まず、includes
and joins
includes に違いがあり、関連付け用に指定されたすべての列との関連付けを熱心にロードします。両方のテーブルから複数の列をクエリまたは選択することはできません。それは何joins
をしますか。両方のテーブルにクエリを実行し、選択した列を選択できます。
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
句で指定Profiles
したすべての列を持つ関係が返されます。select
プロファイルオブジェクトと同じように取得できますe-g
@profiles_sidebar.first.user_email
は、このプロファイルのユーザー メールを提供します。
このアプローチは、複数のテーブルに対してクエリを実行する場合、または両方のテーブルから複数の列を選択する場合に最適です。
2.はじく
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 は、複数の関連付けから列を取得するためにのみ使用されますが、 の機能を使用することはできませんActiveRecord
。選択した列の配列を同じ順序で返すだけです。最初の例のように、プロファイル オブジェクトのユーザーを取得できますが@profiles_sidebar.first.user
、pluck では単純な配列であるため取得できません。そのため、ほとんどのソリューションでエラーが発生しますprofile.user is not defined
- 選択した列との関連付け。
これがオプション 3 です。最初のソリューションでは、両方のテーブルで複数の列を取得し、その機能を使用できますがActiveRecord
、関連付けを積極的にロードしません。したがって、返された結果の関連付けを次のようにループすると、N + 1 クエリのコストがかかります @profiles_sidebar.map(&:user)
したがって、使用includes
したいが選択した列を使用したい場合は、選択した列との新しい関連付けを作成し、その関連付けを呼び出す必要があります。例えばprofile.rb
belongs_to :user_with_selected_column,select: "users.email,users.id"
これで、上記のコードに含めることができます
def set_sidebar_users
@profiles_sidebar = Profile.order(created_at: :desc).includes(:user_with_selected_column).limit(3) if user_signed_in?
end
これでユーザーが熱心に読み込まれますが、ユーザーのメールと ID のみが選択されます。詳細については、
ActiveRecord のインクルードを参照してください。含まれる列を指定する
アップデート
プラックの長所について尋ねられたので、説明しましょう。ご存知pluck
のように、プレーン配列が返されます。そのため、ActiveRecord オブジェクトをインスタンス化せず、データベースから返されたデータを返すだけです。したがって、pluck は、ActiveRecord オブジェクトを必要とせず、返されたデータを表形式で表示する場合に使用するのが最適です。Select はリレーションを返すので、さらにクエリを実行したり、そのインスタンスでモデル メソッドを呼び出したりできます。つまり、要約すると
、モデル値の場合はプル、モデル オブジェクトの場合は選択と言うことができます
詳細については、 http: //gavinmiller.io/2013/getting-to-know-pluck-and-select/を参照してください。