SitePoint Sponsor

User Tag List

Results 1 to 13 of 13

Hybrid View

  1. #1
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Rails starting questions

    I am trying to learn a bit more about Rails, and at the same time my daughter and I are working on a little project.

    We want to make a trivia site that will present questions to a user, and keep totals until they miss a questions, and have a "daily hall of fame" etc.

    I have been through the "cookbook" example with rails, but that is about it.

    I think you would want to have a Question model. I assume the Question class should
    has_many :Answers

    and we would have an Answer class as well. I think we could get as far as that on our own, but I want to validate a couple of questions agains folks who have used this more than me.

    Would we need some other controller to run the series of questions, perhaps a Quiz controller? It could then pull a random, not yet asked questions from the database and present it. I assume there is a rails equivalent of a session, would we tuck an array of already asked questions in there?

    With the Questions has_many :Answers, how would we designate the correct answer? Would the most rails friendly modeling of this be an attribute on the question or on the Answer?

    I am sure more questions will come as we progress, but hopefully someone can chip in on the things I have asked so far. Thanks!
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  2. #2
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sessions in Rails:

    Code:
    session[:answers] = your_answers
    and:

    Code:
    your_answers = session[:answers]
    I think the Answers table should have:
    Code:
    question_id integer
    correct tinyint|bool
    Then you can check it like this:

    Code:
    answer = Answer.find(params[:answer_id])
    
    if answer.correct?
        #correct
    else
        #incorrect
    end
    Or if your question has only one correct answer:

    model question:
    Code:
    belongs_to :correct_answer, :class_name => "Answer", :foreign_key => "correct_answer_id"
    table questions:
    Code:
    correct_answer_id integer
    Check:

    Code:
    answer = Answer.find(params[:id])
    if answer.question.correct_answer == answer
       #correct
    else
       #incorrect
    end

  3. #3
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Fenrir2,

    Thanks for those. Have not played with the session yet, that will be helpful.

    I think we will move the correctness down to the answer table so we can have multiple choice questions.

    I was hoping that scaffold would recognize the "has_many" and create an automatic entry for for the answers associated with the questions. It did not, is there some other bit of magic I need to put in there to perform that task?
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  4. #4
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If this is your action:

    Code:
    def ask
       @question = Question.find(params[:id])
    end
    And this is your view:

    Code:
    <ul>
    <% for answer in @question.answers %>
    <li><%= answer.text %></li>
    <% end %>
    </ul>
    You'll see a list of answers associated with the question:

    http://localhost/quiz/ask/10 <-- the question-ID

  5. #5
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for that example, I was going to write similar, though I wanted to scramble the answers before presenting them.

    Actually I was thinking from the administrative input side for the question controller, i.e. having the question new also display the answer input forms, perhaps allowing for multiple submits of the answers or usings some of the nifty AJAX stuff adding the answers to the question before submitting it.

    Something else that may just come with time, but how do you go about thinking of the design. Obviously RoR is "tuned" to CRUD, but take this exampe where the create for the question entails four creates for the answer model. What is the most natural flow for this? Can you have an "add answer" link which passes a HTTP request parameter to the answer/new actions to default the question id? How do you override the behavior of the add action to go back to the question edit rather than the answer list?

    Sorry for all the questions, but all of the basic intros don't seem to take the development this far into the real world usage. Are there any more "advanced" tutorials which cover these subjects, or do you just kind of have to plug at it and ask questions as best you can?
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  6. #6
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would start off with a form that lets you create a question (question/new) which posts to question/create then if the creation is successful automatically takes you to question/edit/id for the new question. This page displays the question and all of its answers (which is none to begin with). There is a form to add a new answer. This submits to answer/create/question_id (you can set up this kind of URL using routes) which in return redirects back to the question/edit/id by doing:

    Code:
    redirect_to :controller => 'question', :action => 'edit', :id => @params[:question_id]
    You can then improve the interface further by adding AJAX support to this form so there is no visible redirect between creating answers for questions...you create them and they appear.

  7. #7
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Luke,

    Thanks for the guidance. That is indeed the way I was thinking after playing with the problem for a little while.

    I think I am floundering a bit between knowing what parts of Rails you should rely on the code generation and what parts you are expected to be hand editing. I guess my requirements are different enough from the "standard CRUD" that I should just expected to be editing the controllers and the views? It looks like the generate scaffold makes a plural controller with much more code in it, the result of what the scaffold :model does I guess? Should I prefer to modify that as a starting point?

    You redirect goes at the end of the controller definition for new and edit? What happens if you want to do custom logic during the processing of a form, where does that go?
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  8. #8
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sweatje
    I think I am floundering a bit between knowing what parts of Rails you should rely on the code generation and what parts you are expected to be hand editing.
    I've only started working with rails, but my impression is that the scaffolding is meant to be used temporarily, and eventually replaced with your own code. The generator scripts are usefull as a starting point, but any but the simplest app is going to need to be hand edited.

  9. #9
    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 sweatje
    Hi Luke,

    Thanks for the guidance. That is indeed the way I was thinking after playing with the problem for a little while.

    I think I am floundering a bit between knowing what parts of Rails you should rely on the code generation and what parts you are expected to be hand editing. I guess my requirements are different enough from the "standard CRUD" that I should just expected to be editing the controllers and the views? It looks like the generate scaffold makes a plural controller with much more code in it, the result of what the scaffold :model does I guess? Should I prefer to modify that as a starting point?
    Personally, I hardly use the Rails scaffold feature at all. I prefer to create my controllers and actions from scratch. You can use scaffold as a starting point for CRUD but I think its value is pretty much limited to that.

    To me, Rails code generation equals things such as generators for creating boilerplate code such as new controller/model/view files, or view helpers for generating regularly used view code (HTML etc...). Scaffold essentially generates all the code needed for very basic CRUD functionality on a model but little else and a direct 1 - 1 relationship between a model and a controller with a set of CRUD actions is often not what you are going to be after.

    You redirect goes at the end of the controller definition for new and edit? What happens if you want to do custom logic during the processing of a form, where does that go?
    For example...

    Code:
    class ArticleController
      def create
        @article = Article.new(@params['article'])
        # other stuff here etc...
        redirect_to :something_else
      end
    end

  10. #10
    SitePoint Zealot Packetloss's Avatar
    Join Date
    Aug 2003
    Location
    Behind You
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Luke Redpath
    Personally, I hardly use the Rails scaffold feature at all. I prefer to create my controllers and actions from scratch. You can use scaffold as a starting point for CRUD but I think its value is pretty much limited to that.
    Is it just me or is the code generated by scaffold somewhat difficult to understand? I have no problem making some stuff from scratch, but once I start mingling in the scaffold generated code my head starts spinning.
    My links: [ Blog ] - [ deviantArt ]

  11. #11
    SitePoint Enthusiast pro-design1's Avatar
    Join Date
    Jan 2005
    Location
    North west england, UK
    Posts
    27
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smile Hi - this may help

    Hi - I notice you are using ruby , if you look at the top of this section there are some good resources to help you out & also at rubyforums.co.uk there are more good resources there - any way just thought it may help you , good luck with your project - oh yeah incedently Rubyforums.co.uk has a section you can showcase your project so others can see how it's done - I think the point of this is helping the community along - these forums are brand new but promising apparently.
    Hope i was of some use lol

  12. #12
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay, have the start of the application moving along. Does the following method seem sufficiently Rubyish to be a part of my Question model? The gist of it is that I wanted to have a class method to return an array of all the question id's for published questions, which I could pass in an array of already answered id's to exclude from the query. The controller would then select the next question to present by randomly picking an element from this array.

    Code:
      def Question.find_unanswered(exclude = nil)
            sql = "select id from #{Question.table_name} where published = 1 "
            sql = sql + "and id not in (#{exclude.join(',')})" if exclude.respond_to?(:join) &&  exclude.size > 0
            connection.select_all(sql).collect { |r| r['id'] }
      end
    Should I perhaps be using one of the Rails built in "find*" methods instead?
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  13. #13
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you can...I'd try and only use SQL for very complex queries or optimisation purposes


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
  •