# Ad rotation: Calling an action each time a layout is display

**URL:** <https://www.ruby-forum.com/t/ad-rotation-calling-an-action-each-time-a-layout-is-display/225940>\
**Category:** Rails\
**Created:** [February 1, 2007, 12:36am UTC](https://www.ruby-forum.com/t/ad-rotation-calling-an-action-each-time-a-layout-is-display/225940 "2007-02-01T00:36:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![skoggins](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b9e5f3/32.png) [@skoggins](https://www.ruby-forum.com/u/skoggins)\
**Post date:** [February 1, 2007, 12:36am UTC](https://www.ruby-forum.com/t/ad-rotation-calling-an-action-each-time-a-layout-is-display/225940/1 "2007-02-01T00:36:31Z")

</div>

Hi all,

I coded a method named “place\_ads” that I have in my Ad Controller that  
I would like to call each time my “ads.rhtml” or “user.rhtml” layout is  
displayed but not when my “admin.rhtml” is displayed.

Should I put the method in the Application Controller and use a before  
filter? Is there a way to exclude the views in the Admin Controller  
from calling the method then. Or would I be better off leaving the code  
in the Ad controller and somehow calling it from the layout?

Here is my code (haven’t got around to writing a function yet):

class AdController \< ApplicationController  
layout “ads”

def place\_ads

```
#Creates an ordered array

```

@ads = Ad.find(:all, :order =\> “rank”, :conditions =\> “locked\_slot =  
0”)

@slot1 = Ad.find(:first, :conditions =\> “locked\_slot = 1”)  
if @slot1  
@ad1 = @slot1  
else  
@ad1 = @ads.shift  
@ads.push(@ad1)  
end  
@ad1.times\_displayed = @ad1.times\_displayed + 1  
@ad1.save

@slot2 = Ad.find(:first, :conditions =\> “locked\_slot = 2”)  
if @slot2  
@ad2 = @slot2  
else  
@ad2 = @ads.shift  
@ads.push(@ad2)  
end  
@ad2.times\_displayed = @ad2.times\_displayed + 1  
@ad2.save

@slot3 = Ad.find(:first, :conditions =\> “locked\_slot = 3”)  
if @slot3  
@ad3 = @slot3  
else  
@ad3 = @ads.shift  
@ads.push(@ad3)  
end  
@ad3.times\_displayed = @ad3.times\_displayed + 1  
@ad3.save

@slot4 = Ad.find(:first, :conditions =\> “locked\_slot = 4”)  
if @slot4  
@ad4 = @slot4  
else  
@ad4 = @ads.shift  
@ads.push(@ad4)  
end  
@ad4.times\_displayed = @ad4.times\_displayed + 1  
@ad4.save

@slot5 = Ad.find(:first, :conditions =\> “locked\_slot = 5”)  
if @slot5  
@ad5 = @slot5  
else  
@ad5 = @ads.shift  
@ads.push(@ad5)  
end  
@ad5.times\_displayed = @ad5.times\_displayed + 1  
@ad5.save

i = 1  
@ads.each do |ad|  
ad.rank = i  
i = i + 1  
ad.save  
end

end

Thanks!

---

<div class="post-metadata">

**Author:** ![skoggins](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b9e5f3/32.png) [@skoggins](https://www.ruby-forum.com/u/skoggins)\
**Post date:** [February 1, 2007, 3:16am UTC](https://www.ruby-forum.com/t/ad-rotation-calling-an-action-each-time-a-layout-is-display/225940/2 "2007-02-01T03:16:35Z")

</div>

I don’t entirely understand your question, but maybe this would help:

[http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html](http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html)

Check out “Filter Chain Skipping”.

Don’t put stuff in your ApplicationController unless more than one  
Controller needs those methods, as a general rule of thumb.

Also, I’m no Ruby/Rails expert, but that code is very, very repetitive.  
I’m am almost sure there’s a way to slim that down dramatically. I  
mean, look at it this way. Let’s say you make one change to the first  
chunk of code… Now you’d have to change all four other chunks by  
hand. That would suck.

---

<div class="post-metadata">

**Author:** ![skoggins](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b9e5f3/32.png) [@skoggins](https://www.ruby-forum.com/u/skoggins)\
**Post date:** [February 1, 2007, 6:34am UTC](https://www.ruby-forum.com/t/ad-rotation-calling-an-action-each-time-a-layout-is-display/225940/3 "2007-02-01T06:34:40Z")

</div>

On Feb 1, 10:36 am, skoggins [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi all,
> 
> I coded a method named “place\_ads” that I have in my Ad Controller that  
> I would like to call each time my “ads.rhtml” or “user.rhtml” layout is  
> displayed but not when my “admin.rhtml” is displayed.
> 
> Should I put the method in the Application Controller and use a before  
> filter? Is there a way to exclude the views in the Admin Controller  
> from calling the method then. Or would I be better off leaving the code  
> in the Ad controller and somehow calling it from the layout?

INARD (I am not a Rails Developer, ahh… yet), but couldn’t you put  
in your view:

\<%= render :partial =\> “ads/place\_ad.rhtml” if !@user.admin? %\>

This would also require a “admin?” method on the user, but that should  
be easy.

> 0")

This code repeats a lot (as the previous poster said) - why not  
convert the @slots to an array and loop/inject over @ads to populate  
it?  
This would also require refactoring of the view - I would suggest  
passing the @slots to a partial as a collection.
