How should one have several different controller' actions set a common instance variable for use in templates but after the action runs.
In other words, I want this to work in my application_controller.
class ApplicationController < ActionController::Base
after_filter :set_something_common
def set_something_common
# All controllers' actions have queried the DB and set @foo for me...
@bar = some_calculation_on(@foo)
# ... and all templates expect @bar to bet set.
end
end
This does not work because after_filter
runs after rendering. Fine. But what is the correct pattern?
Again, it is important that set_something_common
runs after the action because those actions do case-specific things; but they all set @foo
.
None of my ideas seem ideal:
- Call
set_something_common()
towards the bottom of every action that needs it. Refactor all controllers' case-specific code into
case_specific_code()
and force them to run in order:before_filter :case_specific_code, :set_something_common
Subclass
application_controller
and redefine theindex
method.
Any thoughts? Thanks.
Edit: Matthew's response prompted me to clarify:
Several controlers' index() all do pagination, each taking parameters @offset
and @limit
(via a global before_filter
) to view data slices. Great. Now I want a common method to compute a RESTful URL for the "next slice" link. I was encouraged to see that url_for()
generates a URL returning to the same resource, so I tried:
def set_something_common # really called set_next_url, truth be told
@next_url = url_for(:offset => @offset + @limit, :limit => @limit)
end
I will try monkey patching Fixnum, so I can do something like @offset.next_url_for(self, @limit)
from the template, but I'm not sure if it will work. Come to think of it, if I am going to modify the templates, then I may as well set up an application helper. I'm still not sure what the best solution is.
Update: Accepted answer is "use a helper."
Thanks for the updates from everybody. I learned my lesson that helpers, like global variables, are there for a reason and not to be eschewed when they are plainly beneficial and succinct.