名前付きスコープを新しい名前付きスコープに結合する方法はありますか?
-
09-06-2019 - |
質問
私は持っている
class Foo < ActiveRecord::Base
named_scope :a, lambda { |a| :conditions => { :a => a } }
named_scope :b, lambda { |b| :conditions => { :b => b } }
end
私は…したい
class Foo < ActiveRecord::Base
named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
end
しかし、私はそれをDRY方法で行うことを好みます。を使用しても同じ効果が得られます
Foo.a(something).b(something_else)
でも特に素敵というわけではない。
解決
私はまだ Rails に慣れていないので、ここで何をしようとしているのか正確にはわかりませんが、コードを再利用したいだけなら、通常のクラス メソッドを使用してみてはいかがでしょうか。
def self.ab(a, b)
a(a).b(b)
end
a と b の代わりに *args を取り、どちらか一方をオプションにすることで、より柔軟にすることができます。named_scope に行き詰まっている場合、それを拡張してほぼ同じことを行うことはできないでしょうか?
あなたがやりたいことと完全に的外れだったら教えてください。
他のヒント
少なくとも 3.2 以降は、賢い解決策があります。
scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
これをクラス メソッドにすると、次のように関連付けプロキシにチェーンできなくなります。
@category.products.ab(x, y)
代替案が適用されています このパッチ named_scope の :through オプションを有効にするには:
named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
はい 別のnamed_scopeを定義するためのnamed_scopeの再利用
便宜のためにここにコピーします:
proxy_options を使用すると、あるnamed_scopeを別のnamed_scopeにリサイクルできます。
class Thing
#...
named_scope :billable_by, lambda{|user| {:conditions => {:billable_id => user.id } } }
named_scope :billable_by_tom, lambda{ self.billable_by(User.find_by_name('Tom').id).proxy_options }
#...
end
このようにして、他のnamed_scopesと連鎖させることができます。
これをコードで使用していますが、完璧に機能します。
お役に立てれば幸いです。
@パジャマ:ご存知のように、私はそれを検討しましたが、後でチェーンを接続することができないと思ったので却下しました。 三番目 名前付きスコープは次のようになります。
Foo.ab(x, y).c(z)
しかしそれ以来 ab(x, y)
何でも返します b(y)
戻ってくると、チェーンは機能すると思います。当たり前のことを改めて考えさせられる方法です!
チェックアウト:
http://github.com/binarylogic/searchlogic
印象的な!
具体的に言うと:
class Foo < ActiveRecord::Base
#named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
# alias_scope, returns a Scope defined procedurally
alias_scope :ab, lambda {
Foo.a.b
}
end