Contact Us

A simple Q&A Rails 3 app using voteable_mongoid

Ruby on Rails | January 1, 1970

In this article we’re building a simple Q&A Rails3 app using the voteable_mongoid gem.

Create a new rails app, skip Unit Test, ActiveRecord and Prototype

rails new simple_qa -OTJ

For this app I’ll be using:

  • nifty-generators to quickly generate the site layout
  • Mongoid as the ORM instead of ActiveRecord
  • voteable_mongoid to make the questions & answers voteable
  • devise for user authenticating.

Change the Gemfile

source 'http://rubygems.org'

gem 'rails', '3.0.4'

gem 'mongoid', '2.0.0.rc.6'gem 'bson_ext', '~> 1.2'

gem 'nifty-generators'

gem 'voteable_mongoid'

gem 'devise'

Install gems

bundle install

Renerate mongoid configuration:

rails generate mongoid:config

Generate a simple layout using nifty-generators:

rails g nifty:layout
(note: don’t use nifty to generate a scaffold, nifty scaffold generator isn’t working with mongoid)

Using devise to generate the User model:
rails generate devise:install
rails g devise User

Generate the models:
rails g model Question title:string body:string
rails g model Answer content:string

Add models association:

  • In question.rb:
    references_many :answers
  • In answer.rb:
    referenced_in :question

Now let’s go to the interesting part of this tutorial: making Question & Answer voteable.
In this project, I want to have different voting strategies for Question and Answer:

  • Each vote on a question will increase (or decrease if voting down) the question’s point by 1.
  • Each up vote on an answer will increase its point by 1 and its question’s point by 2.
  • Each down vote on an answer will decrease its point by 2 and its question’s point by 1.

It’s deadly easy to do so with voteable_mongoid, just use the Votable.vote_point method to set voting strategy for your class.

class Question
include Mongoid::Document
include Mongoid::Voteable

field :title, :type => String
field :body, :type => String

references_many :answers

vote_point self, :up => +1, :down => -1
end


class Answer
  include Mongoid::Document
  include Mongoid::Voteable
  
  field :content, :type => String
  
  referenced_in :question
  
  vote_point self, :up => +1, :down => -2
  vote_point Question, :up => +2, :down => -1
end