Forum: Ruby on Rails How should I pick a random entry from the database?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Sean C. (Guest)
on 2006-04-03 11:49
Hi guys. Total newbie here. I've been doing web stuff since 1996 but
only began the foray into scripting last year. I haven't got my skull
completely 360 degrees around OOP yet. It's just me here (in Japan) and
there are no Ruby groups in my area (never mind any in English).

I've got a database table - real simple: question, answer, and id fields
- and I want to pick one question out randomly and output to the HTML
page. Right now I can't even get single entries out - all I can do is
copy and paste from the scaffolding, so it's every question or no
questions at this point. I'm not sure if you can put the value into a
variable, like '@question', and then print that, or if i have to do
something like make @question into an intermediary object, like
'question', and then do something like 'question.question' to make it
print out. Actually, if somebody could just tell me that, even if you
don't know how to do the random thing, it would be appreciated.

Thanks!
Agnieszka F. (Guest)
on 2006-04-03 14:29
sean colquhoun wrote:
> Hi guys. Total newbie here. I've been doing web stuff since 1996 but
> only began the foray into scripting last year. I haven't got my skull
> completely 360 degrees around OOP yet. It's just me here (in Japan) and
> there are no Ruby groups in my area (never mind any in English).
>
> I've got a database table - real simple: question, answer, and id fields
> - and I want to pick one question out randomly and output to the HTML
> page. Right now I can't even get single entries out - all I can do is
> copy and paste from the scaffolding, so it's every question or no
> questions at this point. I'm not sure if you can put the value into a
> variable, like '@question', and then print that, or if i have to do
> something like make @question into an intermediary object, like
> 'question', and then do something like 'question.question' to make it
> print out. Actually, if somebody could just tell me that, even if you
> don't know how to do the random thing, it would be appreciated.
>
> Thanks!

Hi,

To select a specific row you use Model.find(id), where model stands for
the class that represents your question-answer table. So you could try
this out by something like
@entry = YourModel.find(id_you_know_that_exists)
and in the view display the question like <%= @entry.question %>

To pick a random question you could try first retrieving all entries
from that table, then picking a random one from them, like
entries = YourModel.find(:all)
@entry = entries[rand(entries.size-1)]

However, if this table is going to be huge this approach would be very
inefficient, just giving you a hint for the easiest way to start with it
:)

--
Agnieszka
Juan Lupión (Guest)
on 2006-04-03 14:52
(Received via mailing list)
> However, if this table is going to be huge this approach would be very
> inefficient, just giving you a hint for the easiest way to start with it

So what would be the Rails Way of doing this for a huge table?
Storing the number
of available records in another table, or somewhere else?

--
Tim C. (Guest)
on 2006-04-03 15:11
(Received via mailing list)
I'm partial to the SQL approach:

 object.find(:all, :order => "Rand()")
Mikkel B. (Guest)
on 2006-04-03 15:52
(Received via mailing list)
size = Model.count

obj= Model.find(rand(size+))

Assuming the ID's are sequential...

On Monday, April 03, 2006, at 12:29 PM, Agnieszka F. wrote:
>> questions at this point. I'm not sure if you can put the value into a
>To select a specific row you use Model.find(id), where model stands for
>However, if this table is going to be huge this approach would be very
>removed_email_address@domain.invalid
>http://lists.rubyonrails.org/mailman/listinfo/rails


Mikkel B.

www.strongside.dk    - Football Portal(DK)
ting.minline.dk      - Buy Old Stuff!(DK)
Ben M. (Guest)
on 2006-04-03 19:28
(Received via mailing list)
Mikkel B. wrote:
>
> size = Model.count

> obj= Model.find(rand(size+))
>
> Assuming the ID's are sequential...

Yeah... if rows get deleted, the IDs won't be reused so there will be
gaps. This seems
problematic. Sucks to pull all rows, but Tim's approach might be safest.

b
Stef T. (Guest)
on 2006-04-03 19:46
(Received via mailing list)
Hello Everyone,
    Well, not really knowing rails that in depth yet, but, knowing sql,
you could always do something like;

    select name, random() from Model order by 2; (for postgresql)

    different database's will have different names for the random()
function (Sybase/MS-SQL would use rand() for example). However, this has
distinct advantages over returning the entire result set and doing the
randomization in rails (think large tables).

    I would be interested in seeing how to do this in rails - of course
;)
    Regards
    Stef
Sean C. (Guest)
on 2006-04-04 04:41
> To select a specific row you use Model.find(id), where model stands for
> the class that represents your question-answer table. So you could try
> this out by something like
> @entry = YourModel.find(id_you_know_that_exists)
> and in the view display the question like <%= @entry.question %>
>
> To pick a random question you could try first retrieving all entries
> from that table, then picking a random one from them, like
> entries = YourModel.find(:all)
> @entry = entries[rand(entries.size-1)]

> --
> Agnieszka

Thanks!
Sean C. (Guest)
on 2006-04-04 05:59
So sorry to keep bothering you guys with really basic stuff, but i can't
get it to work. Here's the function in my controller:

def ask
    all_questions = Question.find(:all)
    @question = all_questions[rand(all_questions.size-1)]
end

...and here's the code in my "ask.rhtml" file:

 <%= @question.question %>

The way I've got it figured out in my head is this: you put the data
from the database into a variable in the controller (@question). Only it
isn't really a variable, it's an object. But we talk about it like it's
a variable for some reason. Anyway, that object automatically takes the
column names of the DB as its methods. So if I type in
"@question.question", what I'm telling Rails is: put the contents of the
"question" column from the single row that I've loaded the @question
variable up with here.
Am i missing a piece somewhere? It looks like it should work, but Rails
keeps sending me 'nil' errors.
Daniel -. (Guest)
on 2006-04-04 06:13
(Received via mailing list)
It's probably not a good idea to have a column in your table called
question
since this is the name of your model.

Try calling the field a different name eg body
then @question.body

Hope it works for you
Sean C. (Guest)
on 2006-04-04 09:50
Daniel ----- wrote:
> It's probably not a good idea to have a column in your table called
> question
> since this is the name of your model.
>
> Try calling the field a different name eg body
> then @question.body
>
> Hope it works for you

Sorry. Didn't work, so i tried bringing it down to the simplest level
possible and working up from there, and I'm convinced that there's some
fundamental piece of information that i'm missing. Could somebody clue
me in? For example, here's the DEF in the controller. All i want it to
do is print my name to the HTML file:

def ask
    @booyah = 'sean'
end

...and in 'ask.rhtml':

<%= @booyah %>

That's it. It doesn't get any simpler and yet I still can't get it to
work. Please, somebody kick me.
Daniel -. (Guest)
on 2006-04-04 10:19
(Received via mailing list)
When you just point your browser to

http://localhost:3000
(assuming webrik on port 3000)

do you see anything?
Sean C. (Guest)
on 2006-04-04 10:38
Daniel ----- wrote:
> When you just point your browser to
>
> http://localhost:3000
> (assuming webrik on port 3000)
>
> do you see anything?

That's exactly which port I've got it on, and I see the standard "You've
got Rails running!" or something like that, so the server's OK. When I
go to /questions, which is the controller name, I get zero. Unless I put
in something invalid. Then I get an error message. So at least I know
that Rails is paying attention.

Do I need more pieces to the puzzle, maybe? I mean, all I've got is a
controller and a view. I'm not even using data; all I'm doing is putting
a value into a variable/object and then asking for it out again; so I
wouldn't think that I would need anything like that. I even tried
changing my variable names: @booyah, $booyah, and booyah all come up
with nothing. I even tried treating @booyah like an array and typing
@booyah[0], but I got a 'nil object' error.
Tom M. (Guest)
on 2006-04-04 10:56
(Received via mailing list)
On Apr 3, 2006, at 11:38 PM, sean colquhoun wrote:

> got Rails running!" or something like that, so the server's OK. When I
> changing my variable names: @booyah, $booyah, and booyah all come up
> with nothing. I even tried treating @booyah like an array and typing
> @booyah[0], but I got a 'nil object' error.

I think you need questions/ask

It's controller/action

--
-- Tom M.
Sean C. (Guest)
on 2006-04-04 11:30
> I think you need questions/ask
>
> It's controller/action
>
> --
> -- Tom M.

Awesome! That wasn't exactly the problem, but you got me looking in the
right place. You know what it was? I had 'ask' set up as my index
action. I did this just by modifying the scaffold, so what I got was:

  def index
    list
    render :action => 'ask'
  end

Anyway, when I was thinking about changing the index action back to list
so that I could access the thing with questions/ask, i noticed that the
2nd line said 'list' still. So I changed it to 'ask' and it worked!

Wait. I get it now. The 2nd line is the actual call; the 3rd line tells
Rails to render the call. I thought that the call to render was the
whole thing. Sorry to take your time, guys.
David M. (Guest)
on 2006-04-04 12:38
(Received via mailing list)
Problem here is that your controller renders your model, not the other
way around.  You want to call 'ask' in your controller, which will
then render ask.rhtml

If your controller is named 'asdf', you should hit
http://localhost:3000/asdf/ask to see what happens when you run the
ask method of the asdf controller.

Regards

Dave M.
This topic is locked and can not be replied to.