If highlighting a certain item on the front page can be random, I would suggest a much easier solution (assuming your using MySQL, don’t know if the other DBMS support this):
@featured_blog = Blog.find(:first, :order => “RAND()”)
@featured_book = Book.find(:first, :order => “RAND()”)
Add conditions if you want to limit the number of records, e.g. @featured_blog = Blog.find(:first, :conditions => [“updated_at > ?”, Date.today.last_month], :order => “RAND()”)
This basically translates to “SELECT * FROM blogs LIMIT 1 ORDER BY RAND()”, it tells MySQL to fetch 1 single random record out of the resultset.
Best regards
Peter De Berdt
Hi, Peter. This was a great solution! I've already implemented this as
an interim solution for the next couple of months since our site hasn't
officially launched and it'll be a couple/few months till we begin
getting a lot of traffic.
In the long run, I would like to give everyone precisely equal exposure.
Also, I wonder if there is a better solution for faster performance
using memory versus database calls.
But again, for now, thanks a ton for your help! I have all the
rotations working for now and it was very easy to implement since I
simply had to add the ":order => "RAND()" stuff since I was already
making :find(:first) calls.
Be careful using RAND() if your dataset is large. You don't want to
randomly order a million rows only to retrieve one of them. By doing the
above you're forcing the database to consider every row in the table every
time. If you have a lot of rows you may want to do this
- get total row count from db
- in ruby get a random number from 0 to the total row count
- fetch a row ordered by a primary key limit 1 offset that random number.
While two queries, it will lower the impact on the database a lot.
anyway, something to keep in mind in case your data gets big.