I need to access the current controller or flash a notice from an observer method.
class SomeObserver < ActiveRecord::Observer
observe :some_model
cattr_accessor :current_controller
def after_create(record)
...
current_controller.flash[:notice] = "Some message!"
end
end
class ApplicationController < ActionController::Base
before_filter do
SomeObserver.current_controller = self
end
...
end
As others have stated, accessing the controller from an observer somewhat violates the MVC principle. Also the given answers fit your specific use case.
But if you need a more general solution you might try to adapt the way Rails Sweepers are working.
Sweepers are ordinary observers, but they provide access to the controller, if the observer is called from a controller action.
This is achieved by using the sweeper as both observer and controller filter simultaneously, which is easily possible because observers are singletons (i.e. they include the Singleton module)
In a nutshell, you have to do this:
Add the singleton instance as around_filter
to your controller:
class ApplicationController < ActionController::Base
around_filter MyObserver.instance #, only: [...]
end
Add the methods for the filter to your observer:
attr_accessor :controller
def before(controller)
self.controller = controller
true #Don't forget this!
end
def after(controller)
self.controller = nil
end
Now you can access the controller from the observer callbacks. However controller
is nil
if the observer was triggered outside a controller action.
Accessing Controller from Observer violates MVC pattern. The way to do it without violating MVC is to assign flash[:notice]
from controller after calling SomeModel.create()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With