with_scopeをprotectedにするということは
こんな感じになるということなんですかね?という試行錯誤。
悪くないとは思うんですが、慣れるまでは大変そう。
なんていいながら実はけっこうクラス内でwith_scopeするのは好きなんですけどね。
class Blog < ActiveRecord::Base has_many :entries end
class Entry < ActiveRecord::Base belongs_to :blog validates_presence_of :title, :body, :null => false class << self def find_with_deleted_flag_skip(*args) with_scope(:find=>{:conditions=>{:deleted=>false}}) do find_without_deleted_flag_skip(*args) end end alias_method_chain :find, :deleted_flag_skip end end
実際に試した結果。
Blog.find(1).entries.find(:all)
実行されるクエリ
SELECT * FROM blogs WHERE (blogs."id" = 1) SELECT * FROM entries WHERE (entries."deleted" = 'f') AND (entries.blog_id = 1)
オーケー。削除フラグをケアしてますね。
念のための補足しておくと、これはwith_scopeで以下のように書いたのと同じSQLを吐いてます。
Entry.with_scope(:find=>{:conditions=>{:deleted=>false}}) do Entry.find(:all, :conditions=>{:blog_id=>1}) end
ポイントは二つ。
まずfindをオーバーライド(じゃないけど、まぁそんなイメージで)してwith_scopeでの削除フラグ関連をモデル側に寄せたこと。
そしてHasManyAssociation#find()でもモデルクラスでオーバーライドされたfind()メソッドが使用されていること。HasManyAssociation#find()は親レコード側のIDをWHERE句にくっつけてくれるんですよね(entries.blog_id = 1の部分)。