SitePoint Sponsor

User Tag List

Results 1 to 19 of 19
  1. #1
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Displaying random database records

    I am a total noob to RoR, I've only really followed ONLamp's Rolling with Ruby on Rails article and browsed through a few examples.

    I am trying to develop a webpage that will display a random "Joke of the day" whenever the page is loaded. How do I go about this using RoR?

    If anyone knows of a tutorial or can jot down the instructions I'd be most grateful
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  2. #2
    SitePoint Wizard samsm's Avatar
    Join Date
    Nov 2001
    Location
    Atlanta, GA, USA
    Posts
    5,011
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Now is this a different random joke each time the page is loaded, or a joke of the day where each day a joke is chosen randomly and is presented on each page load for that day?

    I'll assume the former.

    http://wiki.rubyonrails.org/rails/pa...tRandomRecords
    Using your unpaid time to add free content to SitePoint Pty Ltd's portfolio?

  3. #3
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Either would do, thanks for the link!
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  4. #4
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK next noob question:
    I have followed the instructions for extending ActiveRecord with a RandomSample module but how do I go about putting it to use in my index.html file?

    I have tried putting in Ruby code and renaming the file to index.rhtml but Apache doesn't parse the code.

    TIA
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  5. #5
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,236
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Create a controller for your homepage (or add a view to an existing controller) and use routes.rb to map the URL to your specified controller/action. It will look something like this:
    Code:
    map.connect '', :controller => 'homepage', :action => 'index'
    Then delete index.html from your public directory and try hitting /

  6. #6
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Mr G. I managed to get it working without needing to change the routes.rb file.

    I'm still missing the actual random joke though.

    If the code is:
    Code:
    module Enumerable
      def random_sample(n)
        sort_by { rand }.slice(0, n)
      end
    end
    
    module RandomSample
        def self.append_features(base)
            def base.random_sample(n = 1)
                r = find(find_by_sql("select #{primary_key} from #{table_name}").random_sample(n).map { |q| q.id })
            end
        end
    end
    where random_sample returns an array of records; how do I get it to display a random record on the page. Every time I try to call random_sample it says method undefined.

    Again, TIA
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  7. #7
    SitePoint Enthusiast
    Join Date
    Aug 2004
    Location
    FL
    Posts
    72
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you want to include that action in a template view, use render_component(), such as:
    Code:
    render_component(:controller => :controllername, :action => :random_sample)
    That should do it.
    Eric A.
    Founder and CEO, XMG Networks, Inc.
    XMG Services: Web 2.0 Photo Management and Sharing | Web Hosting
    Personal Blog: From Two 2 Twelve

  8. #8
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Octal
    how do I get it to display a random record on the page. Every time I try to call random_sample it says method undefined.
    It would looks something like this, in the controller:

    Code:
    @joke = MyModel.random_sample.first
    Then you can try this in your view to make sure it is working:

    Code:
    <%=h @joke.inspect %>
    hth,
    Douglas
    Hello World

  9. #9
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Doug.
    Returned "nil" even though there is one entry in the database

    Here's my code in the controller:
    Code:
    def random
        @random = RandomSample.random_sample.first
    end
    Then I used
    Code:
    <%=h @random.inspect %>
    in the view but as I said it returned nil

    I really should go back to learning more Ruby but any help is greatly appreciated
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  10. #10
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Octal
    Returned "nil" even though there is one entry in the database
    OK, so we know the whole thing doesn't work now. The next step is to try and narrow down what exactly doesn't work.

    Two things we can test easily:

    1) Does our addition to Enumerable work?

    Code:
    @sample = [1,2,3,4,5,6,7,8].random_sample(4)
    Code:
    <%=h @sample %>
    2) Are we connected to the database?

    Code:
    @all = RandomSample.find :all
    Code:
    <%=h @all.inspect %>
    Douglas
    Hello World

  11. #11
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The first test returned nothing unless I put @sample.inspect which returned "nil"

    The second test returned nil

    Just to be sure I browsed localhost/jokes/list and there is a joke listed.
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  12. #12
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, it looks like nothing is getting from your controller to the view, are you doing anything unusual with before and after filters?

    Does this work?

    Code:
    @message = "Hello World!"
    Code:
    <%=h @message %>
    Or even just this:

    Code:
    <%=h "escaping works" %>
    Douglas
    Hello World

  13. #13
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the continued support Doug.

    Escaping does actually work, the message test failed however. When you mentioned filters what exactly do you mean?

    Here is my jokes controller
    Code:
    class JokesController < ApplicationController
      def index
        render :action => 'home'
      end
     
      def random
        @random = RandomSample.random_sample.first
      end
     
      def message
        @message = "Hello World!"
      end
     
      def list
        @joke_pages, @jokes = paginate :jokes, :per_page => 10
      end
     
      def show
        @joke = Joke.find(params[:id])
      end
     
      def new
        @joke = Joke.new
      end
     
      def create
        @joke = Joke.new(params[:joke])
        if @joke.save
          flash[:notice] = 'Joke was successfully created.'
          redirect_to :action => 'list'
        else
          render :action => 'new'
        end
      end
     
      def edit
        @joke = Joke.find(params[:id])
      end
     
      def update
        @joke = Joke.find(params[:id])
        if @joke.update_attributes(params[:joke])
          flash[:notice] = 'Joke was successfully updated.'
          redirect_to :action => 'show', :id => @joke
        else
          render :action => 'edit'
        end
      end
     
      def destroy
        Joke.find(params[:id]).destroy
        redirect_to :action => 'list'
      end
    end
    Most of it is scaffold generated, I added the index, RandomSample and message parts. Everything works apart from RandomSample and message.
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  14. #14
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, that's a bit strange.

    What happens if you change the show action to this:

    Code:
      def show
        @joke = Joke.find(params[:id])
        @message = "Hello!"
      end
    And put this somewhere in your show template:

    Code:
    <%=h @message %>
    Also, are there any differences between your message.rhtml template, and your show.rhtml template?

    Douglas
    Hello World

  15. #15
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The @message was displayed correctly on localhost/jokes/show/1

    show.rhtml was automatically generated by scaffold, message.rhtml doesn't exist...which is where I have gone completely wrong isnt it?

    @random = RandomSample.random_sample.first should have been put in the def home block as that is the page I want to use it on.

    Anyway, doing that returns the following error
    undefined method `random_sample' for RandomSample:Module
    edit: Just tried putting @message = "Hello" into the index blockand it didn't get displayed with <%=h @message %>.

    I know I am a Ruby nuby but this is just wierd now
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  16. #16
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I also re-ran the other tests, putting the code inside the index block (rather than creating new ones) and here are the results:

    Enumerable test ([1,2,3,4,5,6,7,8].random_sample(4)) returned nothing

    Database test (RandomSample.find :all) returned method undefined error
    undefined method `find' for RandomSample:Module
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  17. #17
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've been going back over the RandomSaple instructions and it states that
    RandomSample adds a single method random_sample to all \ActiveRecord objects.
    So coming as I do from a Java background, in my code I would write ActiveRecord.random_sample() to call that method.

    Doing so in Ruby though returns a method undefined error; what am I doing wrong?
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee

  18. #18
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Octal
    I've been going back over the RandomSaple instructions and it states that


    So coming as I do from a Java background, in my code I would write ActiveRecord.random_sample() to call that method.

    Doing so in Ruby though returns a method undefined error; what am I doing wrong?
    First of all, random_sample() is an instance method so you would only call it on an instance of one of your ActiveRecord::Base objects (Base is a class inside the ActiveRecord module), not on the class itself. Secondly you only reall work with classes that extend ActiveRecord::Base i.e. your models:

    Code:
    class MyModel < ActiveRecord::Base; end;
    
    @foo = MyModel.new
    @foo.random_sample

  19. #19
    SitePoint Zealot Octal's Avatar
    Join Date
    Feb 2003
    Location
    UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the explanation Luke.
    Kind of makes sense though I'll have to re-read your explanation and go back over some Ruby tutorials to be crystal clear. In the meantime I found a workaround to my problem
    Code:
    def index
        @random = Joke.find(:first, order => 'RAND()')
        render :action => 'home'
    end
    Note the placement of render :action, if it came before the @random it returned nil, this way works

    Thanks for everyones patience and help
    Octal - All your base-8 belong to us
    "Knowing is not enough, we must apply.
    Willing is not enough, we must do." - Bruce Lee


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •