Random

I am pretty much new at this ROR game and had what I think to be a
simple question.

I have a set of Sponsors that I would like to be able to select one at
random and display in the my html. I have already set up the DB,
scaffolded, set index controller and all is working smoothly.

I know that I can display them all by doing

<% for sponsor in @sponsors %>

<%= sponsor.name %>

<% end %>

How can I just select one of the sponsors to display each time someone
hits this page?

Can someone PLEASE help? Or guide me in the right direction?

I am assuming it would be best for the DRY process to set this up once
in my Controller/Model but I am at a complete loss on what the best way
to do this is.

THANKS!

there is a wonderful command for random uses, called, (surprisingly)
RAND().

so, if i am correct, you can go like this:

def anaction
@variable = MyModel.find(:first, :order => [“RAND()”]) and it should
bring forth
end # the first object it finds, in a random order.

or, another option i haven’t really thought through if you wanted to do
this in the view (which wouldn’t be mvc, but …) is to use the
array.SORT! { |o| block }
and specify the block to randomize the array.

either way, one of the two should work. (first choice is probably
preferable)
is it helping?

s

Shai, Thanks for your quick reply.

In my Sponsors controller i should put this:

def featured_sponsor
@featured = Sponsor.find(:first, :order => [“RAND()”])
end

Then how, in my html can I display a) sponsor.name b)
sponsor.website_url and c) sponsor.description?

I see now how to connect to the data, but how can i display it?

Thanks a million!

I guess it should rather be this in my controller.

def featured_sponsor
@sponsor = Sponsor.find(:first, :order => [“RAND()”])
end

right?

On 7/19/06, Mason K. [email protected] wrote:

end

Then how, in my html can I display

a) sponsor.name

<%=h sponsor.name %>

b)

sponsor.website_url

<%= link_to sponsor.name, sponsor.website_url %>

and c) sponsor.description?

<%=h sponsor.description

I see now how to connect to the data, but how can i display it?

there is a wonderful command for random uses, called, (surprisingly)
RAND().

so, if i am correct, you can go like this:

def anaction
@variable = MyModel.find(:first, :order => [“RAND()”]) and it should
bring forth
end # the first object it finds, in a random order.

RAND() is a pricey option though as it’s going to select every row in
your
table, assign it a random value, then sort it on that value. Then
return
the first record.

Might be a lot faster to find the maximum id, then use ruby to generate
a
random value between 1 and max_id, then so something like:

MyModel.find(:first, :conditions => [“id >= ?”, random_id])

Or something along those lines.

On my end_users table which has about 80,000 rows, the rand() takes
about
1.60 seconds. The second query takes 0.00… not super scientific, but
still…

mysql> explain select * from end_users order by rand() limit 1;
±—±------------±----------±-----±--------------±-----±--------±-----±------±--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len |
ref | rows | Extra |
±—±------------±----------±-----±--------------±-----±--------±-----±------±--------------------------------+
| 1 | SIMPLE | end_users | ALL | NULL | NULL | NULL |
NULL | 80525 | Using temporary; Using filesort |
±—±------------±----------±-----±--------------±-----±--------±-----±------±--------------------------------+
1 row in set (0.00 sec)

mysql> explain select * from end_users where id >= 12345 limit 1;
±—±------------±----------±------±--------------±--------±--------±-----±------±------------+
| id | select_type | table | type | possible_keys | key | key_len
| ref | rows | Extra |
±—±------------±----------±------±--------------±--------±--------±-----±------±------------+
| 1 | SIMPLE | end_users | range | PRIMARY | PRIMARY | 4
| NULL | 65667 | Using where |
±—±------------±----------±------±--------------±--------±--------±-----±------±------------+

I NOW HAVE THIS

class SponsorsController < ApplicationController

def index
@random_sponsors = Sponsor.find(:first, :order => [“RAND()”])
@sponsors = Sponsor.all_sponsors
@bands = Band.all_bands
end

end

AND THIS IN MY HTML

<%= random_sponsor.name %>

<%=h random_sponsor.description %>

AND THIS HAPPENS:

undefined local variable or method `random_sponsor’

I am sorry, I really am new to this game. I appreciate everyone’s input.
BTW, there will be near 12 sponsors for this project, but probably a
descent idea to code for the worst… It would be lovely if we had
80,000 sponsors though! :slight_smile:

Your second solution is more effecient, but it does make a few
assumptions.
We have no guarantee that all the ids between 0 and max_id actually
exist.
There could possibly be gaps. You could throw it in a loop and do it
over if
it doesn’t exist; so this isn’t a huge problem, but it is something to
take
into account.

is there something wrong with this??

(:first, :order => [“RAND()”])

How does it know to look for the :id???

And change “@random_sponsors” to “@random_sponsor

(no s)

Your second solution is more effecient, but it does make a few assumptions.
We have no guarantee that all the ids between 0 and max_id actually exist.
There could possibly be gaps. You could throw it in a loop and do it over if
it doesn’t exist; so this isn’t a huge problem, but it is something to take
into account.

True. That’s why I did the “>=”. That at least gaurantees you’ll find
something (unless random_id == max_id).

But you’re right, I’m assuming a fairly equal distribution of primary
ids… which may or may not be correct.

You could also get the number of records in the table, then do a OFFSET
random_id, LIMIT 1.

Although COUNT isn’t always fast for certain table types…

This brings back a full record (chosen at random), including its id.

        - dan


Dan K. mailto:[email protected]
http://www.dankohn.com/ tel:+1-415-233-1000

In your view, change both occurrences of random_sponsor to
@random_sponsor.

        - dan


Dan K. mailto:[email protected]
http://www.dankohn.com/ tel:+1-415-233-1000