私は、少なくともscope
方法を使用して、動的スコープを定義する方法のか分かりません。
scope
メソッドの代わりに、私が知っている限り同じことを達成するクラスメソッドを定義しています。言い換えれば
、
scope("All"){|scope| scope.order("created_at desc")}
あなたは動的にこのメソッドを使用してクラスのメソッドを作成することができます
# in a Class
class << self
def All
order("created_at desc")
end
end
と同じである(ruby-defining-class-methodsから撮影:
class Object
def meta_def name, &blk
(class << self; self; end).instance_eval { define_method name.to_s, &blk }
end
end
私はよ次のコードを使用して、生成されたクラスメソッドを削除します。
class Object
def meta_undef name
(class << self; self; end).class_eval { remove_method name.to_sym }
end
end
これらの方法はすなわち、あなたのモデルにsave
とdestroy
フックから呼び出すことができます。:
# in a Model
def save(*args)
self.class.meta_def(name) do
joins(:cuisines).where("cuisines.id=?",c.id)
end
super(*args)
end
def destroy(*args)
self.class.meta_undef(name)
super(*args)
end
レコードが作成または削除されるたびに続いて、スコープが更新されます。このアプローチの長所と短所があります。メソッドをオンザフライで定義することは明らかですが、これはリモートコード実行に対して脆弱です。
個人的には、クラスメソッド(つまりスコープ)を動的に定義することを止め、引数を受け入れるようにしましょう。例:あなたのコメントに応答する
# This is with standard ActiveRecord, not sure about ActiveAdmin
class Restaurant < ActiveRecord::Base
def self.All
order("created_at desc")
end
end
class Cuisine < ActiveRecord::Base
def self.by_name(name)
Restaurant.all.joins(:cuisines).where("cuisines.name=?", name)
end
end
Cuisine.by_name("something")
Restaurant.all.All
Restaurant.All
編集は:
load(file)
ソースを再ロードします。あなたは次のことを試みることができるので:
# in a model
def save(*args)
load(Rails.root.join("app", "models", "THIS_MODEL_FILE.rb")
super
end
def destroy(*args)
load(Rails.root.join("app", "models", "THIS_MODEL_FILE.rb")
super
end
ボンネットの下に作成および更新の両方のために、save
が呼び出されます。オーバーライドして、destroy
はすべてのCRUD操作をカバーします。
私がこのアプローチを最初に推奨しなかったのは、私が個人的に使ったことがないからです。私はそれがどのように機能するか知りたいと思うだろう。
おかげで解決策を見つけた時はいつでも任意の料理の変更。 –
OK @ AsnadAtta、私は私の答えに応答を追加しました。投稿の最後にある編集をご覧ください。 –