Merge pull request #94 from AyuntamientoMadrid/vote_comments-25

refactors voting
This commit is contained in:
Juanjo Bazán
2015-08-05 14:37:51 +02:00
17 changed files with 277 additions and 124 deletions

View File

@@ -1,6 +1,6 @@
class CommentsController < ApplicationController class CommentsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_debate, :set_parent before_action :set_debate, :set_parent, only: :create
respond_to :html, :js respond_to :html, :js
def create def create
@@ -10,6 +10,12 @@ class CommentsController < ApplicationController
respond_with @comment respond_with @comment
end end
def vote
@comment = Comment.find(params[:id])
@comment.vote_by(voter: current_user, vote: params[:value])
respond_with @comment
end
private private
def comment_params def comment_params
params.require(:comments).permit(:commentable_type, :commentable_id, :body) params.require(:comments).permit(:commentable_type, :commentable_id, :body)

View File

@@ -1,7 +1,7 @@
class DebatesController < ApplicationController class DebatesController < ApplicationController
include RecaptchaHelper include RecaptchaHelper
before_action :set_debate, only: [:show, :edit, :update] before_action :set_debate, only: [:show, :edit, :update, :vote]
before_action :authenticate_user!, except: [:show, :index] before_action :authenticate_user!, except: [:index, :show]
before_action :validate_ownership, only: [:edit, :update] before_action :validate_ownership, only: [:edit, :update]
def index def index
@@ -38,6 +38,10 @@ class DebatesController < ApplicationController
respond_with @debate respond_with @debate
end end
def vote
@debate.vote_by(voter: current_user, vote: params[:value])
end
private private
def set_debate def set_debate

View File

@@ -1,21 +0,0 @@
class VotesController < ApplicationController
before_action :set_debate
before_action :authenticate_user!
respond_to :html, :js
def create
register_vote
notice = @debate.vote_registered? ? I18n.t("votes.notice_thanks") : I18n.t("votes.notice_already_registered")
respond_with @debate
end
private
def set_debate
@debate = Debate.find(params[:debate_id])
end
def register_vote
@debate.vote_by voter: current_user, vote: params[:value]
end
end

View File

@@ -1,5 +1,6 @@
class Comment < ActiveRecord::Base class Comment < ActiveRecord::Base
acts_as_nested_set scope: [:commentable_id, :commentable_type] acts_as_nested_set scope: [:commentable_id, :commentable_type]
acts_as_votable
validates :body, presence: true validates :body, presence: true
validates :user, presence: true validates :user, presence: true

View File

@@ -8,6 +8,11 @@
<%= comment.user.name %>&nbsp;&bullet;&nbsp;<%= time_ago_in_words(comment.created_at) %> <%= comment.user.name %>&nbsp;&bullet;&nbsp;<%= time_ago_in_words(comment.created_at) %>
</span> </span>
<p><%= comment.body %></p> <p><%= comment.body %></p>
<span id="<%= dom_id(comment) %>_votes">
<%= render 'comments/votes', comment: comment %>
</span>
<p class="reply"><%= render 'comments/form', parent: comment %></p> <p class="reply"><%= render 'comments/form', parent: comment %></p>
</div> </div>

View File

@@ -0,0 +1,11 @@
<span class="in_favor">
<%= link_to "up", vote_comment_path(comment, value: 'yes'),
method: "post", remote: true %>
<%= comment.get_likes.size %>
</span>
<span class="against">
<%= link_to "down", vote_comment_path(comment, value: 'no'),
method: "post", remote: true %>
<%= comment.get_dislikes.size %>
</span>

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@comment) %>_votes").html('<%= j render("comments/votes", comment: @comment) %>');

View File

@@ -14,25 +14,11 @@
<%= render "shared/tags", debate: debate %> <%= render "shared/tags", debate: debate %>
</div> </div>
</div> </div>
<div class="small-12 medium-3 column">
<div class="text-center votes">
<%= link_to debate_votes_path(debate, value: 'yes'), class: "like inline-block", title: t('votes.agree'), method: "post" do %>
<i class="icon-like"></i>
<span><%= percentage('likes', debate) %></span>
<% end %>
<span class="divider"></span> <div id="<%= dom_id(debate) %>_votes" class="small-12 medium-3 column">
<%= render 'debates/votes_min', debate: debate %>
<%= link_to debate_votes_path(debate, value: 'no'), class: "unlike inline-block", title: t('votes.disagree'), method: "post" do %>
<i class="icon-unlike"></i>
<span><%= percentage('dislikes', debate) %></span>
<% end %>
<br>
<span class="total-votes">
<%= pluralize(debate.total_votes, t("debates.debate.vote"), t("debates.debate.votes")) %>
</span>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -16,22 +16,8 @@
</div> </div>
<div class="row votes"> <div class="row votes">
<div class="small-12 column"> <div id="<%= dom_id(featured_debate) %>_votes" class="small-12 column">
<%= link_to debate_votes_path(featured_debate, value: "yes"), class: "like", title: t('votes.agree'), method: "post" do %> <%= render 'debates/featured_debate_votes', debate: featured_debate %>
<i class="icon-like"></i>
<span><%= percentage('likes', featured_debate) %></span>
<% end %>
<span class="divider"></span>
<%= link_to debate_votes_path(featured_debate, value: "no"), class: "unlike", title: t('votes.disagree'), method: "post" do %>
<i class="icon-unlike"></i>
<span><%= percentage('dislikes', featured_debate) %></span>
<% end %>
<span class="total-votes right">
<%= pluralize(featured_debate.total_votes, t("debates.debate.vote"), t("debates.debate.votes")) %>
</span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,21 @@
<span id="in_favor">
<%= link_to vote_debate_path(debate, value: 'yes', partial: 'featured_debate_votes'),
class: "like", title: t('votes.agree'), method: "post", remote: true do %>
<i class="icon-like"></i>
<span><%= percentage('likes', debate) %></span>
<% end %>
</span>
<span class="divider"></span>
<span id="against">
<%= link_to vote_debate_path(debate, value: 'no', partial: 'featured_debate_votes'),
class: "unlike", title: t('votes.disagree'), method: "post", remote: true do %>
<i class="icon-unlike"></i>
<span><%= percentage('dislikes', debate) %></span>
<% end %>
</span>
<span class="total-votes right">
<%= pluralize(debate.total_votes, t("debates.debate.vote"), t("debates.debate.votes")) %>
</span>

View File

@@ -7,7 +7,8 @@
<div class="text-center"> <div class="text-center">
<div id="in_favor" class="inline-block"> <div id="in_favor" class="inline-block">
<%= link_to debate_votes_path(@debate, value: 'yes'), class: "like", title: t('votes.agree'), method: "post", remote: true do %> <%= link_to vote_debate_path(@debate, value: 'yes', partial: 'votes'),
class: "like", title: t('votes.agree'), method: "post", remote: true do %>
<i class="icon-like"></i> <i class="icon-like"></i>
<span><%= percentage('likes', @debate) %></span> <span><%= percentage('likes', @debate) %></span>
<% end %> <% end %>
@@ -16,7 +17,8 @@
<span class="divider"></span> <span class="divider"></span>
<div id="against" class="inline-block"> <div id="against" class="inline-block">
<%= link_to debate_votes_path(@debate, value: 'no'), class: "unlike", title: t('votes.disagree'), method: "post", remote: true do %> <%= link_to vote_debate_path(@debate, value: 'no', partial: 'votes'),
class: "unlike", title: t('votes.disagree'), method: "post", remote: true do %>
<i class="icon-unlike"></i> <i class="icon-unlike"></i>
<span><%= percentage('dislikes', @debate) %></span> <span><%= percentage('dislikes', @debate) %></span>
<% end %> <% end %>

View File

@@ -0,0 +1,22 @@
<div class="text-center votes">
<span id="in_favor">
<%= link_to vote_debate_path(debate, value: 'yes', partial: 'votes_min'),
class: "like inline-block", title: t('votes.agree'), method: "post", remote: true do %>
<i class="icon-like"></i>
<span><%= percentage('likes', debate) %></span>
<% end %>
</span>
<span class="divider"></span>
<span id="against">
<%= link_to vote_debate_path(debate, value: 'no', partial: 'votes_min'),
class: "unlike inline-block", title: t('votes.disagree'), method: "post", remote: true do %>
<i class="icon-unlike"></i>
<span><%= percentage('dislikes', debate) %></span>
<% end %>
</span>
<br>
<span class="total-votes">
<%= pluralize(debate.total_votes, t("debates.debate.vote"), t("debates.debate.votes")) %>
</span>
</div>

View File

@@ -10,8 +10,8 @@
<%= @debate.description %> <%= @debate.description %>
<p><%= render 'shared/tags', debate: @debate %></p> <p><%= render 'shared/tags', debate: @debate %></p>
</div> </div>
<div id="votes" class="small-12 medium-3 column votes"> <div id="<%= dom_id(@debate) %>_votes" class="votes small-12 medium-3 column">
<%= render 'votes/votes' %> <%= render 'debates/votes' %>
<div class="text-center"> <div class="text-center">
<%= link_to t("debates.show.leave_comment"), "#comments", class: "leave-comment" %> <%= link_to t("debates.show.leave_comment"), "#comments", class: "leave-comment" %>
</div> </div>

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@debate) %>_votes").html('<%= j render("debates/#{params[:partial]}", debate: @debate) %>');

View File

@@ -1 +0,0 @@
$("#votes").html("<%= j render('votes') %>");

View File

@@ -6,9 +6,18 @@ Rails.application.routes.draw do
# You can have the root of your site routed with "root" # You can have the root of your site routed with "root"
root 'debates#index' root 'debates#index'
resources :debates do resources :debates do
resources :votes, only: :create member do
resources :comments, only: :create post :vote
end
resources :comments, only: :create, shallow: true do
member do
post :vote
end
end
end end
resource :account, controller: "account", only: [:show, :update] resource :account, controller: "account", only: [:show, :update]

View File

@@ -2,74 +2,194 @@ require 'rails_helper'
feature 'Votes' do feature 'Votes' do
background do feature 'Debates' do
@manuela = create(:user)
@pablo = create(:user) background do
@debate = create(:debate) @manuela = create(:user)
@pablo = create(:user)
@debate = create(:debate)
login_as(@manuela)
visit debate_path(@debate)
end
scenario 'Show' do
vote = create(:vote, voter: @manuela, votable: @debate, vote_flag: true)
vote = create(:vote, voter: @pablo, votable: @debate, vote_flag: false)
visit debate_path(@debate)
expect(page).to have_content "2 votes"
within('#in_favor') do
expect(page).to have_content "50%"
end
within('#against') do
expect(page).to have_content "50%"
end
end
scenario 'Create from debate show', :js do
find('#in_favor a').click
within('#in_favor') do
expect(page).to have_content "100%"
end
within('#against') do
expect(page).to have_content "0%"
end
expect(page).to have_content "1 vote"
end
scenario 'Create from debate featured', :js do
visit debates_path
within("#featured-debates") do
find('#in_favor a').click
within('#in_favor') do
expect(page).to have_content "100%"
end
within('#against') do
expect(page).to have_content "0%"
end
expect(page).to have_content "1 vote"
end
expect(URI.parse(current_url).path).to eq(debates_path)
end
scenario 'Create from debate index', :js do
3.times { create(:debate) }
visit debates_path
within("#debates") do
expect(page).to have_css(".debate", count: 1)
find('#in_favor a').click
within('#in_favor') do
expect(page).to have_content "100%"
end
within('#against') do
expect(page).to have_content "0%"
end
expect(page).to have_content "1 vote"
end
expect(URI.parse(current_url).path).to eq(debates_path)
end
scenario 'Update', :js do
find('#in_favor a').click
find('#against a').click
within('#in_favor') do
expect(page).to have_content "0%"
end
within('#against') do
expect(page).to have_content "100%"
end
expect(page).to have_content "1 vote"
end
scenario 'Trying to vote multiple times', :js do
find('#in_favor a').click
find('#in_favor a').click
within('#in_favor') do
expect(page).to have_content "100%"
end
within('#against') do
expect(page).to have_content "0%"
end
expect(page).to have_content "1 vote"
end
login_as(@manuela)
visit debate_path(@debate)
end end
scenario 'Show' do
vote = create(:vote, voter: @manuela, votable: @debate, vote_flag: true)
vote = create(:vote, voter: @pablo, votable: @debate, vote_flag: false)
visit debate_path(@debate) feature 'Comments' do
expect(page).to have_content "2 votes" background do
@manuela = create(:user)
@pablo = create(:user)
@debate = create(:debate)
@comment = create(:comment, commentable: @debate)
within('#in_favor') do login_as(@manuela)
expect(page).to have_content "50%" visit debate_path(@debate)
end end
within('#against') do scenario 'Show' do
expect(page).to have_content "50%" vote = create(:vote, voter: @manuela, votable: @comment, vote_flag: true)
vote = create(:vote, voter: @pablo, votable: @comment, vote_flag: false)
visit debate_path(@debate)
within("#comment_#{@comment.id}_votes") do
within(".in_favor") do
expect(page).to have_content "1"
end
within(".against") do
expect(page).to have_content "1"
end
end
end end
scenario 'Create', :js do
within("#comment_#{@comment.id}_votes") do
find(".in_favor a").click
within(".in_favor") do
expect(page).to have_content "1"
end
within(".against") do
expect(page).to have_content "0"
end
end
end
scenario 'Update', :js do
within("#comment_#{@comment.id}_votes") do
find('.in_favor a').click
find('.against a').click
within('.in_favor') do
expect(page).to have_content "0"
end
within('.against') do
expect(page).to have_content "1"
end
end
end
scenario 'Trying to vote multiple times', :js do
within("#comment_#{@comment.id}_votes") do
find('.in_favor a').click
find('.in_favor a').click
within('.in_favor') do
expect(page).to have_content "1"
end
within('.against') do
expect(page).to have_content "0"
end
end
end
end end
scenario 'Create', :js do
find('#in_favor a').click
within('#in_favor') do
expect(page).to have_content "100%"
end
within('#against') do
expect(page).to have_content "0%"
end
expect(page).to have_content "1 vote"
end
scenario 'Update', :js do
find('#in_favor a').click
find('#against a').click
within('#in_favor') do
expect(page).to have_content "0%"
end
within('#against') do
expect(page).to have_content "100%"
end
expect(page).to have_content "1 vote"
end
scenario 'Trying to vote multiple times', :js do
find('#in_favor a').click
find('#in_favor a').click
within('#in_favor') do
expect(page).to have_content "100%"
end
within('#against') do
expect(page).to have_content "0%"
end
expect(page).to have_content "1 vote"
end
end end