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