Hi, input please!
I’m trying to dynamically serve js/css based on the active
controller+action, e.g.:
<link href="/stylesheets/*people/update*.css" />
<script src="/javascripts/*people/update*.js"></script>
In application_helper.rb, I’m using the following method to create the
dynamic bits of the asset URLs:
def asset_path_fragment
"*#{controller.controller_name}/#{controller.action_name}*"
end
Then I realized a flaw in my logic:
def update
if @something_goes_wrong
render :edit # render the #edit’s view but erroneously serve the
#update’s css/js
end
end
So … what should I do?
Well, I see I can do this, but it seems like a pretty bad idea.
def update
if @something_goes_wrong
self.acion_name = ‘edit’
render :edit
end
end
Anyone?
Sounds like a job for content_for. You need a snippet like this in your
view template:
update.html.erb:
<% content_for :assets do %>
<%= stylesheet_link_tag “people/update” %>
<%= javascript_include_tag “people/update” %>
<% end %>
And in your layout:
…
<%= yield :assets $>
…
Hmm, maybe I’m confused. Even if I used your solution verbatim I think
I’m
still stuck with the problem as update.html.erb would not be used
(edit.html.erb would).
To recap, what you’re suggesting is essentially what I’m doing – except
instead of hard-coding “people/update” I’m using a helper method that
uses
controller.controller_name + “/” + controller.action_name to generate
that
part of the path.
So far so good, but when I use “render :edit” in the “update” action,
I’ve
got my problem (I’m requesting the wrong action’s assets).
No, in the solution I suggested the decision about which assets to use
is
made in the template and can’t depend on the controller name/action.
There’s no way that I know of to determine the template name in the
same
way via a helper function.
The only other option that might be useful for you would be to have
combined
CSS/JS files for some actions where this type of thing can occur like
with
update/edit and set the ID or class of the tag based on the
template
rendered. You could then target selectors in your assets to ensure the
correct behavior, but this might end up being more effort than a simpler
solution.
Just to add my two cents, the body approach works well as long as you
work
with classes, not a single id, not with the id. Something like
action_youractionname and controller_yourcontrollername. Modernizr has a
similar approach to specify what features are available.
Thanks. The 2nd option you’re suggesting (body IDs) is what I
originally
had in mind until this debate broke out against using the ID attribute
on
the body tag http://dailyjs.com/2010/04/27/unobtrusive-js/ (which I
kind
of ended up liking).
But, for the sake of pragmatism, I might have to again revisit my
approach
thanks to this new twist.
Cool, I’ll check it out - thanks again.
This may look like a quick and dirty way to do this, but might work with
minimal effort.
Also, this will work only in the scenario where create and update never
have
their own views - this would be the case most often, but just wanted to
highlight it
def asset_path_fragment
css_action = case controller.action_name
when “create”
“new”
when “update”
“edit”
else
controller.action_name
end
“#{controller.controller_name}/#{css_action}”
end
Here is my code:
%body{ :class => “controller_#{controller.controller_name}
#{defined?(@page_cssclass) ? @page_cssclass : ‘’}” }
I am using a custom page_css class set in the controller action method
here
instead of an action name, but I would use an action name instead these
days
Chris Braddock wrote in post #1008081:
…
the body tag <http://dailyjs.com/2010/04/27/unobtrusive-js/ > (which I
…
UJS is “not a fad” but a way of life of “living, breathing tree
structures of DOM objects, events, and styles” and their creators. Did I
get him right?
I better shut up…