36

モデルのプロフィールがあります。プロフィール has_one ユーザー。ユーザー モデルにはフィールド email があります。電話すると

Profile.some_scope.includes(:user)

それが呼ぶ

SELECT users.* FROM users WHERE users.id IN (some ids)

しかし、私の User モデルには、レンダリングで使用していない多くのフィールドがあります。ユーザーからのメールのみを読み込むことはできますか? したがって、SQLは次のようになります

SELECT users.email FROM users WHERE users.id IN (some ids)
4

6 に答える 6

45

Rails には、インクルードクエリのオプションを渡す機能がありません。しかし、これらのパラメーターをモデルの下の関連付け宣言で渡すことができます。

あなたのシナリオでは、以下のように、プロファイル モデルの下にユーザー モデルとの新しい関連付けを作成する必要があります。

belongs_to :user_only_fetch_email, :select => "users.id, users.email", :class_name => "User"

もう 1 つ関連付けを作成しましたが、それは User モデルのみを指しています。したがって、クエリは次のようになります。

Profile.includes(:user_only_fetch_email)

また

Profile.includes(:user_only_fetch_email).find(some_profile_ids)
于 2012-09-13T15:23:26.143 に答える
15

特定の属性を選択する場合は、joinsではなくを使用する必要がありますincludes

このasciicastから:

SELECTステートメントの最初の部分の生成方法を制御できないため、includeオプションはselectオプションでは実際には機能しません。SELECTのフィールドを制御する必要がある場合は、包含よりも結合を使用する必要があります。

使用joins

Profile.some_scope.joins(:users).select("users.email")
于 2012-09-13T09:32:19.570 に答える
2

自分でその機能が欲しかったので、使ってください。このメソッドをクラスに含めます

#ACCEPTS args in string format "ASSOCIATION_NAME:COLUMN_NAME-COLUMN_NAME"

def self.includes_with_select(*m)
    association_arr = []
    m.each do |part|
      parts = part.split(':')
      association = parts[0].to_sym
      select_columns = parts[1].split('-')
      association_macro = (self.reflect_on_association(association).macro)
      association_arr << association.to_sym
      class_name = self.reflect_on_association(association).class_name 
      self.send(association_macro, association, -> {select *select_columns}, class_name: "#{class_name.to_sym}")
    end
    self.includes(*association_arr)
  end

そして、 like: を呼び出すことができ、Contract.includes_with_select('user:id-name-status', 'confirmation:confirmed-id')指定された列を選択します。

于 2015-04-09T05:26:28.100 に答える
0

Mohanaj の例を使用すると、次のことができます。

belongs_to :user_only_fetch_email, -> { select [:id, :email] }, :class_name => "User"
于 2014-08-28T21:49:38.107 に答える