i'm desperate with one problem.
i want to register custom callback :after_something and then use that callback into 开发者_StackOverflowobserver.
I have try with define_callbacks, set_callbacks but observer never trigger that callback.
I know that i can use AR callbacks, but i just prefer in some situation to use my own callbacks.
Thanks
Here is a solution if someone looking for:
in your model call this:
notify_observers(:after_my_custom_callback)
In your observer just define method:
def after_my_custom_callback(record)
#do things
end
Observer use standard AR callbacks so it will not trigger your default one.
I think rather that inventing new callback (and monkeypatch default behaviour of AR) maybe you should use AR's. It is difficult to say what do you want. Can you give some use case?
try maybe something like
before_save MyCallbacks.new, :if => :some_condiditons_meet?
class MyCallbacks
def before_save(object)
sophistcated_use(object) if object.valid?
damn_have_it?
end
end
it actually covers behaviour of observer at some level
<--update-->
The entire callback chain of a save, save!, or destroy call runs within a transaction. That includes after_* hooks. If everything goes fine a COMMIT is executed once the chain has been completed.
I think the whole Idea of SINGLE observer is not best solution. After more dependencies will arrive your logic will be very complicated. Defining own transaction wrappers is good, but do you really need it? Maybe you can rearrange model for achieve it without writing up own transaction case.
For instance
class Friendship < ActiveRecord::Base
belongs_to :user
has_many :users, :through => :groups
after_validation :save_my_records
def save_my_records
user.friend.history.save
user.history.save
end
end
Where friend is object => has got own observer where history is object => has got own observer
It is very abstract, but without your code I had no idea how to give some constructive example also after_validation is not best place to saving anything I think.
also notify_observer sound like hack to me :-)
Thanks to Alex's answer I could solve this problem by defining a define_model_callbacks_for_observers
method that should be called instead of define_model_callbacks
(you might want to put this into a module):
def define_model_callbacks_for_observers(*args)
types = Array.wrap(args.extract_options![:only] || [:before, :around, :after])
callbacks = define_model_callbacks(*args)
callbacks.each do |callback|
types.each do |filter|
set_callback(callback, filter) do
notify_observers :"#{filter}_#{callback}"
true
end
end
end
end
精彩评论