Rails beginner
Rails beginner

Reputation: 14504

How to store the last two records in an array

I have a method that gets a random banner, but I do not want it to show the same banner twice in a row.

def random_banner
  @koder = @side.reklamers.all(:select => :id).collect(&:id)
  @koder.sample gets a random ID
  @reklame = Reklamer.find(@koder.sample)
  render :text => @reklame.kode 
end

What is the best solution?

TDGS solution: When I visit the action, it works well, but I have a blog that makes an ajax call to get the banner code, and there, the same banner appear twice in a row.

Upvotes: 0

Views: 76

Answers (3)

tdgs
tdgs

Reputation: 1096

Store the last used banner id in the session somewhere, say session[:banner_id]

Then, do the following:

@koder = @side.reklamers.pluck(:id).reject{|id| id == session[:banner_id}
@reklame = Reklamer.find(@koder.sample)
session[:banner_id] = @reklame.id

Upvotes: 1

tadman
tadman

Reputation: 211590

Things like this should be stored in the session and not in the database. Modifying the session is near zero cost, whereas modifying the database incurs at least a round-trip to the database engine and back, plus the overhead of creating a query and decoding the result.

Example:

loop do
 random_id = @koder.sample

 break if (random_id != session[:last_random_id]))
end

session[:last_random_id] = random_id

As James Mason points out, be sure to have at least two things that can be selected or this loop will run forever. Sometimes, as a failsafe, it's better to have either a loop of fixed length, like 10.times do, or a method that reliably emits random numbers by doing this internally, as @koder.sample(session) could test and update.

Upvotes: 1

James Mason
James Mason

Reputation: 4296

You could pass the previous ID to random_banner and reject the random ID if it matches. You'll need to make sure you don't get stuck in an infinite loop if there's only one banner to choose from, too.

Upvotes: 0

Related Questions