0

ActiveRecordのオプションは、たとえば次のような無料のアソシエーションcustom_finder拡張機能を利用できることを意味しているという印象を受けました。.where.order

class Dog < ActiveRecord::Base
  has_many :fleas, class_name: 'Flea', 
           finder_sql: "select fleas.* from fleas where pet_type = 'dog'"
end

'finder_sql'は非常に些細なことですが、要点を示しているため、これは良い例ではありません。

生成されたSQL

私は次のことを期待します

@dog = Dog.find(5)
@dog.fleas.where('num_legs > 2')

引き起こす

"select fleas.* from fleas where pet_type = 'dog' AND num_legs > 2

つまり、カスタムfinder_sql+where句

ただし、実際に生成されるのは

"SELECT "base_posts".* FROM "fleas" WHERE "fleas"."dog_id" = 5 AND (num_legs > 2)

つまり、習慣を完全に無視しfinder_sql、ノミを現在の犬に参加させようとします。

カスタムfinder_sqlがアソシエーション拡張機能にそれを尊重させない場合、その中のポイントは何ですか-それは単にオブジェクトのメソッドである可能性があります...

4

1 に答える 1

0

これは本当です。カスタムファインダーは、Railsの前世代のファインダー(Arel && AR :: Relationshipより前)の遺産であり、今日のアソシエーションでの存在は、下位互換性(imho)のためだけだと思います。とにかく、それはAR :: Relation(拡張機能)のイデオロギーに適合しません。

ここまでで、.find_by_sql()があり、関連付けのオプションとして:finder_sqlがあります。

実際、現在、アソシエーションに:finder_sqlオプションがある場合、これはレコード収集の形成にのみ使用されます(.find_by_sqlを使用)。アソシエーションはAR::Relationshipオブジェクトを作成し、コレクション(.target)をロードし、AR :: Relationメソッド呼び出しをリレーションオブジェクトに委任します。ただし、カスタムSQLステートメントを認識せず、プライマリSQL式のみを認識します。これが理由です:

@dog.fleas.class
#=> Array
@dog.fleas.to_sql # delegated to AR::Relation

一次式「SELECT"base_posts"。*FROM...」を返します。

@dog.fleas.where("...") # delegated to AR::Relation

カスタムファインダーがないかのように新しい条件を課します。

一方、.find_by_sqlは常に配列を返すため、Arrayのメソッドを使用して新しい条件を課すことが可能である可能性があります。

 @dog.fleas.select {|r| ... } # delegated to Array
于 2012-12-27T01:47:59.087 に答える