Skip to content

Commit

Permalink
Merge pull request #11 from andela-iamadi/ft-votes-resources
Browse files Browse the repository at this point in the history
Ft votes resources
  • Loading branch information
oojewale committed Feb 2, 2016
2 parents 5009145 + 67b46ad commit 4fc74de
Show file tree
Hide file tree
Showing 18 changed files with 179 additions and 19 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.2.3
20 changes: 10 additions & 10 deletions app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@ class CommentsController < ApplicationController
include Common

def index
question = Question.find_by(id: question_id) if comment_of_question
answer = Answer.find_by(id: answer_id) if comment_of_answer
question = Question.find_by(id: question_id) if action_on_question
answer = Answer.find_by(id: answer_id) if action_on_answer
comments = question.comments if question
comments = answer.comments if answer
render json: comments, status: 200 unless comments.nil?
render json: { error: false }, status: 404 if comments.nil?
end

def show
comments = Question.find_question_comment(question_id, id) if comment_of_question
comments = Answer.find_answer_comment(answer_id, id) if comment_of_answer
comments = Question.find_question_comment(question_id, id) if action_on_question
comments = Answer.find_answer_comment(answer_id, id) if action_on_answer
render json: comments , status: 200
rescue
render json: { error: false }, status: 404
end

def create
unless content.nil? || content == ""
if comment_of_question
if action_on_question
comments = Question.add_comment_to_question(question_id, user_id, content)
elsif comment_of_answer
elsif action_on_answer
comments = Answer.add_comment_to_answer(answer_id, user_id, content)
end
render json: comments, root: false
Expand All @@ -43,9 +43,9 @@ def update
end

def destroy
if comment_of_question
if action_on_question
deleted if Question.delete_question_comment(id, user_id, question_id)
elsif comment_of_answer
elsif action_on_answer
deleted if Answer.delete_answer_comment(id, user_id, answer_id)
end
rescue
Expand All @@ -67,9 +67,9 @@ def deleted
end

def update_subject(id, user_id, attribute, value = nil)
if comment_of_question
if action_on_question
comments = Question.update_question_comment(id, user_id, question_id, attribute, value)
elsif comment_of_answer
elsif action_on_answer
comments = Answer.update_answer_comment(id, user_id, answer_id, attribute, value)
end
end
Expand Down
14 changes: 8 additions & 6 deletions app/controllers/concerns/common.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
module Common

def set_vars(allowed = {})
@question_id = allowed[:question_id]
@answer_id = allowed[:answer_id]
@comment_id = allowed[:comment_id]
@id = allowed[:id]
@content = allowed[:content]
@downvote = allowed[:downvote]
@upvote = allowed[:upvote]
@user_id = current_user.try(:id)
@user_id = current_user.id if current_user
end

def comment_of_question
def action_on_question
question_id && answer_id.nil?
end

def comment_of_answer
def action_on_answer
answer_id && question_id.nil?
end

def action_on_comment
comment_id.present?
end
end


32 changes: 32 additions & 0 deletions app/controllers/votes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class VotesController < ApplicationController
before_action :current_user, :custom_initializer
attr_reader :user_id, :question_id, :answer_id, :comment_id, :id

include Common

def upvote
vote = Vote.act_on_vote("plus", Question, question_id, user_id) if action_on_question
vote = Vote.act_on_vote("plus", Answer, answer_id, user_id) if action_on_answer
vote = Vote.act_on_vote("plus", Comment, comment_id, user_id) if action_on_comment
render json: { response: vote }, status: 200 unless vote.nil?
render json: { error: "Invalid vote!" }, status: 403 if vote.nil?
end

def downvote
vote = Vote.act_on_vote("minus", Question, question_id, user_id) if action_on_question
vote = Vote.act_on_vote("minus", Answer, answer_id, user_id) if action_on_answer
vote = Vote.act_on_vote("minus", Comment, comment_id, user_id) if action_on_comment
render json: { response: vote }, status: 200 unless vote.nil?
render json: { error: "Invalid vote!" }, status: 403 if vote.nil?
end

private

def vote_params
params.permit(:question_id, :answer_id, :comment_id, :id)
end

def custom_initializer
set_vars(vote_params)
end
end
1 change: 1 addition & 0 deletions app/models/answer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Answer < ActiveRecord::Base
has_many :comments, as: :comment_on
has_many :votes, as: :voteable
belongs_to :user
belongs_to :question

Expand Down
1 change: 1 addition & 0 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Comment < ActiveRecord::Base
has_many :votes, as: :voteable
belongs_to :comment_on, polymorphic: true
belongs_to :user
validates :content, presence: true
Expand Down
1 change: 1 addition & 0 deletions app/models/question.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Question < ActiveRecord::Base
has_many :comments, as: :comment_on
has_many :votes, as: :voteable
has_many :tags, as: :subscriber
has_many :answers
belongs_to :user
Expand Down
48 changes: 48 additions & 0 deletions app/models/vote.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class Vote < ActiveRecord::Base
belongs_to :voteable, polymorphic: true
validates :user_id, presence: true

class << self

def act_on_vote(operation, subject, subject_id, user_id)
value = 1 if operation == "plus"
value = -1 if operation == "minus"
process_vote(subject, subject_id, user_id, value)
end

def process_vote(subject, subject_id, user_id, value)
if subject_exists?(subject, subject_id)
store_vote(subject, subject_id, user_id, value)
return total_votes(subject, subject_id)
end
end

def store_vote(subject, subject_id, user_id, value)
if voted?(subject, subject_id, user_id, value) || voted?(subject, subject_id, user_id)
subject_of_vote(subject, subject_id).votes.find_by(user_id: user_id).
update_attribute("value", value)
else
subject_of_vote(subject, subject_id).votes.
create(user_id: user_id, value: value)
end
end

def voted?(subject, subject_id, user_id, value = nil)
return exists?(user_id: user_id, voteable_type: "#{subject}", voteable_id: subject_id) unless value
exists?(user_id: user_id, voteable_type: "#{subject}", voteable_id: subject_id, value: value)
end

def subject_exists?(subject, subject_id)
subject.exists?(id: subject_id)
end

def subject_of_vote(subject, subject_id)
subject.find_by(id: subject_id)
end

def total_votes(subject, subject_id)
subject_of_vote(subject, subject_id).votes.sum("value")
end
end

end
8 changes: 7 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
Rails.application.routes.draw do
post "questions/:question_id/upvote" => "votes#upvote"
post "answers/:answer_id/upvote" => "votes#upvote"
post "comments/:comment_id/upvote" => "votes#upvote"
post "questions/:question_id/downvote" => "votes#downvote"
post "answers/:answer_id/downvote" => "votes#downvote"
post "comments/:comment_id/downvote" => "votes#downvote"
post '/validate_token', to: 'tokens#validate'

resources :questions, except: [:new, :edit] do
Expand All @@ -8,6 +14,7 @@
resources :comments, except: [:new, :edit]
resources :answers, except: [:new, :edit]
end

get "top_questions" => "questions#top_questions"

resources :answers, except: [:index, :show, :create, :destroy, :update, :new, :edit] do
Expand All @@ -32,5 +39,4 @@

get 'auth/:provider/callback', to: 'users#authenticate', as: :authenticate
match "*path", to: 'application#resource_not_found', via: :all

end
11 changes: 11 additions & 0 deletions db/migrate/20160126230005_create_votes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateVotes < ActiveRecord::Migration
def change
create_table :votes do |t|
t.integer :user_id, index: true
t.integer :value
t.references :voteable, polymorphic: true, index: true

t.timestamps null: false
end
end
end
7 changes: 7 additions & 0 deletions db/migrate/20160126231052_remove_votes_from_other_tables.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class RemoveVotesFromOtherTables < ActiveRecord::Migration
def change
remove_column :questions, :votes, :integer
remove_column :answers, :votes, :integer
remove_column :comments, :votes, :integer
end
end
5 changes: 5 additions & 0 deletions db/migrate/20160128233820_remove_value_from_votes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class RemoveValueFromVotes < ActiveRecord::Migration
def change
remove_column :votes, :value, :integer
end
end
5 changes: 5 additions & 0 deletions db/migrate/20160201170223_add_value_to_votes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddValueToVotes < ActiveRecord::Migration
def change
add_column :votes, :value, :integer
end
end
14 changes: 13 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20160131205414) do

ActiveRecord::Schema.define(version: 20160201170223) do

create_table "answers", force: :cascade do |t|
t.integer "user_id"
Expand Down Expand Up @@ -91,4 +92,15 @@
t.boolean "active"
end

create_table "votes", force: :cascade do |t|
t.integer "user_id"
t.integer "voteable_id"
t.string "voteable_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "value"
end

add_index "votes", ["user_id"], name: "index_votes_on_user_id"
add_index "votes", ["voteable_type", "voteable_id"], name: "index_votes_on_voteable_type_and_voteable_id"
end
5 changes: 5 additions & 0 deletions spec/controllers/answers_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe AnswersController, type: :controller do

end
1 change: 0 additions & 1 deletion spec/controllers/comments_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,4 @@
expect(response).to have_http_status(:success)
end
end

end
19 changes: 19 additions & 0 deletions spec/controllers/votes_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'rails_helper'

RSpec.describe VotesController, type: :controller do

describe "GET #upvote" do
it "returns http success" do
get :upvote
expect(response).to have_http_status(:success)
end
end

describe "GET #downvote" do
it "returns http success" do
get :downvote
expect(response).to have_http_status(:success)
end
end

end
5 changes: 5 additions & 0 deletions spec/models/vote_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe Vote, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

0 comments on commit 4fc74de

Please sign in to comment.