named_scope 内で「find_by_sql」を使用する方法があるかどうか疑問に思っていました。カスタム SQL を named_scope として扱いたいので、既存の named_scopes にチェーンできます。また、頻繁に使用する SQL スニペットを最適化するのにも適しています。
3 に答える
任意の SQL を名前付きスコープの条件に入れることができますが、呼び出しfind_by_sql
た場合、「スコープ」は破棄されます。
与えられた:
class Item
# Anything you can put in an sql WHERE you can put here
named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
end
これは機能します(SQL文字列をそこに貼り付けるだけです-複数ある場合はANDで結合されます)
Item.mine.find :all
=> SELECT * FROM items WHERE ('user_id' = 887 and IS_A_NINJA() = 1)
ただし、これはそうではありません
Items.mine.find_by_sql 'select * from items limit 1'
=> select * from items limit 1
したがって、答えは「いいえ」です。舞台裏で何が起こらなければならないかを考えると、これは非常に理にかなっています。SQL レールを構築するには、それがどのように適合するかを知る必要があります。
通常のクエリを作成するとselect
、joins
、conditions
、 などはすべて個別の断片に分割されます。Railsは、他のすべてに影響を与えることなく条件に何かを追加できることを知っています(これは方法with_scope
とnamed_scope
機能です)。
ただし、レールにfind_by_sql
大きな文字列を与えるだけです。何がどこにあるのかわからないため、スコープが機能するために追加する必要があるものを追加するのは安全ではありません。
これはあなたが尋ねたことに正確には対応していませんが、「contruct_finder_sql」を調査することができます。名前付きスコープの SQL を取得できます。
named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1'
named_scope :additional {
:condtions => mine.send(:construct_finder_sql,{}) + " additional = 'foo'"
}
もちろん
:named_scope :conditions => [あなたのSQL]