Suppose I have some logic in a base controller to pass information to the view to build something like a breadcrumb:
class ContextAwareController < ApplicationController
after_filter :build_breadcrumb
def build_breadcumb
#...
end
end
I want this build_breadcrumb method to run after the main controller logic, but before the view is rendered.
The above code runs too late, but a before_filter would be too early.
Can anybody suggest a way to accomplish this without explicitly calling build_breadcumb at the end of each of the actions in the child controllers?
Thanks
I had the same problem and solved it like this:
class ApplicationController < ActionController::Base
def render *args
add_breadcrumbs
super
end
end
There are also some gems to achieve this. One of them is rails3_before_render. It works similarly to filters, for example:
class PostsController < ApplicationController
before_render :ping, :except => [:destroy]
def index; end
def new; end
def show; end
def destroy; end
private
def ping
Rails.logger.info "Ping-Pong actions"
end
end
(code snipped copied from gem documentation)
I believe rendering starts when render is called, and there's no default way to defer it. Here's one thing you could do:
filters are applied in the same order declared. So make a second after-filter that calls render with an array args stored in a class variable. Then anywhere you would normally call render, set the variable.
If we're overriding render
, we're not really using the filter chain at all, so it might be simpler to determine which action we're in using the @_action_name
.
StuffController < ApplicationController
def my_filter
# Do the stuff
end
def render(*args)
my_filter if @_action_name == "show"
super
end
end
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