AnApprentice
AnApprentice

Reputation: 110950

how to build a Poll / Survey type app in rails

I'm trying to understand how to create a poll/survey app in rails.

Right now I have the following model:

Poll (id, question:string, answer_1:string, answer_2:string, answer_3:string, answer_4:string, answer_5:string)

How do I track PollVote per user? Also, how would I then build the form where it shows a poll, with the question and answer(s). And then queries across the PollVote model to see if the user has made any votes?

Ideas? Thanks

Upvotes: 4

Views: 4014

Answers (1)

Luke
Luke

Reputation: 4925

I'd model it something like the following for the most flexibility:

class Poll < ActiveRecord::Base
  has_many :questions
  has_many :responses, :through => :questions
end

class Question < ActiveRecord::Base
  belongs_to :poll
  has_many :answers
  has_many :responses, :through => :answers
end

class Answer < ActiveRecord::Base
  belongs_to :question
  has_many :responses
end

class Response < ActiveRecord::Base
  belongs_to :user
  belongs_to :answer
end

Then you could do things like:

Response.count(:conditions => "question_id = #{@question.id} AND answer_id = #{@answer.id}")

Edit:

Stretching the limits of my expertise, but here's some more code that should get you started with the rest. Not syntax-checked or tested in any way whatsoever. Meant for inspiration more than anything else.

class PollsController < ApplicationController
  ...
  def show
    @poll = Poll.find(params[:id], :includes => { :questions => { :answers => :responses } } )
    @responses = {}
    @poll.responses.each do |r|
      @responses[r.answer.question.id] = r if r.user == current_user
    end
  end
  ...
end


# in app/views/poll/show.html.haml

%ul
  - @poll.questions.each do |question|
    %li
      %p= question.text
      = form_for (@responses[question.id] || Response.new) do |f|
        - question.answers.each do |ans|
          = f.radio_button :answer, ans.id
          = f.label( ('answer_' << ans.id).to_sym, ans.text )

Keep in mind the is probably the easiest but least efficient way to do this. You'll want to move a lot of this processing to the database if you're dealing with a large number of responses.

Also, look at this question for dealing with response uniqueness. My code is designed to keep users to one vote per question, but it doesn't actually validate that.

Upvotes: 7

Related Questions