Improve Votes#create code
[shapado:piglops-shapado.git] / app / controllers / votes_controller.rb
1 class VotesController < ApplicationController
2   before_filter :find_voteable
3   before_filter :check_permissions, :except => [:index]
4
5
6   def index
7     redirect_to(root_path)
8   end
9
10   # TODO: refactor
11   def create
12     vote = Vote.new(:user => current_user)
13     vote_type = ""
14     if params[:vote_up] || params['vote_up.x'] || params['vote_up.y']
15       vote_type = "vote_up"
16       vote.value = 1
17     elsif params[:vote_down] || params['vote_down.x'] || params['vote_down.y']
18       vote_type = "vote_down"
19       vote.value = -1
20     end
21
22     vote, vote_state = push_vote(vote)
23
24     if vote_state == :created && !vote.new?
25       if @voteable.class == Question
26         sweep_question(vote.voteable)
27
28         Jobs::Votes.async.on_vote_question(@voteable.id, vote.id).commit!
29       elsif @voteable.class == Answer
30         Jobs::Votes.async.on_vote_answer(@voteable.id, vote.id).commit!
31       end
32     end
33
34     respond_to do |format|
35       format.html{redirect_to params[:source]}
36
37       format.js do
38         if vote_state != :error
39           average = @voteable.reload.votes_average
40           render(:json => {:success => true,
41                            :message => flash[:notice],
42                            :vote_type => vote_type,
43                            :vote_state => vote_state,
44                            :average => average}.to_json)
45         else
46           render(:json => {:success => false, :message => flash[:error] }.to_json)
47         end
48       end
49
50       format.json do
51         if vote_state != :error
52           average = @voteable.reload.votes_average
53           render(:json => {:success => true,
54                            :message => flash[:notice],
55                            :vote_type => vote_type,
56                            :vote_state => vote_state,
57                            :average => average}.to_json)
58         else
59           render(:json => {:success => false, :message => flash[:error] }.to_json)
60         end
61       end
62     end
63   end
64
65   def destroy
66     @vote = Vote.find(params[:id])
67     voteable = @vote.voteable
68     value = @vote.value
69     if  @vote && current_user == @vote.user
70       @vote.destroy
71       if voteable.kind_of?(Question)
72         sweep_question(voteable)
73       end
74       voteable.remove_vote!(value, current_user)
75     end
76     respond_to do |format|
77       format.html { redirect_to params[:source] }
78       format.json  { head :ok }
79     end
80   end
81
82   protected
83   def find_voteable
84     if params[:answer_id]
85       @voteable = current_group.answers.find(params[:answer_id])
86     elsif params[:question_id]
87       @voteable = current_group.questions.find_by_slug_or_id(params[:question_id])
88     end
89
90     if params[:comment_id]
91       @voteable = @voteable.comments.find(params[:comment_id])
92     end
93   end
94
95   def check_permissions
96     unless logged_in?
97       flash[:error] = t(:unauthenticated, :scope => "votes.create")
98       respond_to do |format|
99         format.html do
100           flash[:error] += ", [#{t("global.please_login")}](#{new_user_session_path})"
101           redirect_to params[:source]
102         end
103         format.json do
104           flash[:error] = t("global.please_login")
105           render(:json => {:status => :unauthenticate, :success => false, :message => flash[:error] }.to_json)
106         end
107         format.js do
108           flash[:error] = t("global.please_login")
109           render(:json => {:status => :unauthenticate, :success => false, :message => flash[:error] }.to_json)
110         end
111       end
112     end
113   end
114
115   def push_vote(vote)
116     user_vote = current_user.vote_on(@voteable)
117     vote.voteable = @voteable
118     state = :error
119     if user_vote.nil?
120
121       if vote.valid?
122         vote.save
123         @voteable.add_vote!(vote.value, current_user)
124         flash[:notice] = t("votes.create.flash_notice")
125         state = :created
126       else
127         flash[:error] = vote.errors.full_messages.join(", ")
128       end
129     elsif(user_vote.valid?)
130       if(user_vote.value != vote.value)
131         @voteable.remove_vote!(user_vote.value, current_user)
132         @voteable.add_vote!(vote.value, current_user)
133
134         user_vote.value = vote.value
135         user_vote.save
136         flash[:notice] = t("votes.create.flash_notice")
137         state = :updated
138       else
139         value = vote.value
140         user_vote.destroy
141         @voteable.remove_vote!(value, current_user)
142         flash[:notice] = t("votes.destroy.flash_notice")
143         state = :deleted
144       end
145       vote = user_vote
146     else
147       flash[:error] = user_vote.errors.full_messages.join(", ")
148       state = :error
149     end
150
151     if @voteable.is_a?(Answer)
152       question = @voteable.question
153       sweep_question(question)
154
155       if vote.value == 1
156         question.override(:answered_with_id => @voteable.id) if !question.answered
157       elsif question.answered_with_id == @voteable.id && @voteable.votes_average <= 1
158         question.override(:answered_with_id => nil)
159       end
160     end
161
162     [vote, state]
163   end
164 end