Reputation: 14504
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
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
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
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