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

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!

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

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.

On Feb 1, 10:36 am, skoggins [email protected] 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.