私が作っている宝石では、開発者が私が書いたクラスメソッドをinterceptor
モデルに追加できるようにしたいと思っています。
class User < ActiveRecord::Base
has_interceptor
end
これにより、 gemを介してデータベースにクエリを実行して魔法のようなことをUser.interceptor
行うオブジェクトを返すを呼び出すことができます。すべて良い。Interceptor
Squeel
ただし、開発者がインターセプターが実行するクエリのスコープを設定できるようにする適切な方法を最初に見つけたいと思います。これは、それからand チェーンを取り込めるようinterceptor
にすることで実現できます。それ以外の場合は、モデルにフォールバックします。この実装は次のように機能します。ActiveRecord::Relation
Squeel
# Builds on blank ARel from User:
User.interceptor.perform_magic
#=> "SELECT `users`.* FROM `users` WHERE interceptor magic"
# Build on scoped ARel from Relation:
User.interceptor( User.where('name LIKE (?)', 'chris') ).perform_magic
#=> "SELECT `users`.* FROM `users` WHERE `users`.`name` LIKE 'chris' AND interceptor magic"
これは効果的ですが、醜いです。私が本当に欲しいのは次のようなものです:
# Build on scoped ARel:
User.where('name LIKE (?)', 'chris').interceptor.perform_magic
#=> "SELECT `users`.* FROM `users` WHERE `users`.`name` LIKE 'chris' AND interceptor magic"
基本的に、私はActiveRecord::Relation
チェーンを「タップ」して ARel を盗み、それをInterceptor
オブジェクトに渡して、評価する前に変更したいと考えています。しかし、これを行うために考えられるすべての方法は、非常に恐ろしいコードを使用しているため、実装した場合、神が子猫を殺すことを知っています. 私は私の手にその血を必要としません。子猫を助けて?
問題:
私の複雑さに加えて、
class User < ActiveRecord::Base
has_interceptor :other_interceptor_name
end
を呼び出すUser.other_interceptor_name
ことができ、モデルは複数のインターセプターを持つことができます。それはうまく機能しますが、method_missing
通常よりもさらに悪いアイデアを使用します。