# serving only controller+action specific css/javascript

**URL:** <https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624>\
**Category:** rubyonrails-talk\
**Created:** [June 27, 2011, 5:06pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624 "2011-06-27T17:06:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chris\_Braddock](https://avatars.discourse-cdn.com/v4/letter/c/919ad9/32.png) [@Chris\_Braddock](https://discuss.rubyonrails.org/u/Chris_Braddock)\
**Post date:** [June 27, 2011, 5:06pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/1 "2011-06-27T17:06:36Z")

</div>

Hi, input please!

I’m trying to dynamically serve js/css based on the active controller+action, e.g.:

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?

---

<div class="post-metadata">

**Author:** ![Chris\_Braddock](https://avatars.discourse-cdn.com/v4/letter/c/919ad9/32.png) [@Chris\_Braddock](https://discuss.rubyonrails.org/u/Chris_Braddock)\
**Post date:** [June 28, 2011, 1:40pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/2 "2011-06-28T13:40:51Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Chris\_Kottom1](https://avatars.discourse-cdn.com/v4/letter/c/c77e96/32.png) [@Chris\_Kottom1](https://discuss.rubyonrails.org/u/Chris_Kottom1)\
**Post date:** [June 28, 2011, 2:37pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/3 "2011-06-28T14:37:03Z")

</div>

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 $\>

…

---

<div class="post-metadata">

**Author:** ![Chris\_Braddock](https://avatars.discourse-cdn.com/v4/letter/c/919ad9/32.png) [@Chris\_Braddock](https://discuss.rubyonrails.org/u/Chris_Braddock)\
**Post date:** [June 28, 2011, 2:52pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/4 "2011-06-28T14:52:09Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![Chris\_Kottom1](https://avatars.discourse-cdn.com/v4/letter/c/c77e96/32.png) [@Chris\_Kottom1](https://discuss.rubyonrails.org/u/Chris_Kottom1)\
**Post date:** [June 28, 2011, 3:21pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/5 "2011-06-28T15:21:23Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Chris\_Braddock](https://avatars.discourse-cdn.com/v4/letter/c/919ad9/32.png) [@Chris\_Braddock](https://discuss.rubyonrails.org/u/Chris_Braddock)\
**Post date:** [June 28, 2011, 3:29pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/6 "2011-06-28T15:29:31Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Martin\_Wawrusch](https://avatars.discourse-cdn.com/v4/letter/m/ba8739/32.png) [@Martin\_Wawrusch](https://discuss.rubyonrails.org/u/Martin_Wawrusch)\
**Post date:** [June 28, 2011, 3:32pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/7 "2011-06-28T15:32:09Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Chris\_Braddock](https://avatars.discourse-cdn.com/v4/letter/c/919ad9/32.png) [@Chris\_Braddock](https://discuss.rubyonrails.org/u/Chris_Braddock)\
**Post date:** [June 28, 2011, 3:34pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/8 "2011-06-28T15:34:45Z")

</div>

Cool, I’ll check it out - thanks again.

---

<div class="post-metadata">

**Author:** ![Martin\_Wawrusch](https://avatars.discourse-cdn.com/v4/letter/m/ba8739/32.png) [@Martin\_Wawrusch](https://discuss.rubyonrails.org/u/Martin_Wawrusch)\
**Post date:** [June 28, 2011, 3:38pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/9 "2011-06-28T15:38:38Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Chirag](https://avatars.discourse-cdn.com/v4/letter/c/ecccb3/32.png) [@Chirag](https://discuss.rubyonrails.org/u/Chirag)\
**Post date:** [June 28, 2011, 4:14pm UTC](https://discuss.rubyonrails.org/t/serving-only-controller-action-specific-css-javascript/59624/10 "2011-06-28T16:14:44Z")

</div>

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
