Skip to content

Commit

Permalink
Merge pull request #127 from cheshire137/add-event-voting
Browse files Browse the repository at this point in the history
Add event voting
  • Loading branch information
kentonh authored Oct 15, 2017
2 parents 02cb02e + 68b2b2c commit 1646647
Show file tree
Hide file tree
Showing 18 changed files with 226 additions and 13 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ gem 'omniauth-twitter'

# Misc
gem 'activeadmin', github: 'activeadmin/activeadmin'
gem 'acts_as_votable', '~> 0.11.0'

gem 'paperclip'
gem 'acts-as-taggable-on'
Expand Down
18 changes: 10 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
acts-as-taggable-on (4.0.0)
activerecord (>= 4.0)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
annotate (2.7.2)
activerecord (>= 3.2, < 6.0)
rake (>= 10.4, < 13.0)
arbre (1.1.1)
add-event-voting
acts-as-taggable-on (3.4.4)
activerecord (>= 3.2, < 5)
acts_as_votable (0.11.0)
addressable (2.3.8)
annotate (2.6.5)
activerecord (>= 2.3.0)
rake (>= 0.8.7)
arbre (1.0.2)
activesupport (>= 3.0.0)
arel (6.0.4)
ast (2.3.0)
Expand Down Expand Up @@ -382,6 +383,7 @@ DEPENDENCIES
active_record-acts_as
activeadmin!
acts-as-taggable-on
acts_as_votable (~> 0.11.0)
annotate
bootstrap-sass (~> 3.3.3)
bootstrap3-datetimepicker-rails (~> 4.14.30)
Expand Down
5 changes: 5 additions & 0 deletions app/assets/javascripts/votes.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$ ->
$('.vote-container').on 'ajax:success', 'form.vote-form', (event, data) ->
form = event.target
container = form.closest('.vote-container')
container.innerHTML = data
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@import "pages";
@import "people";
@import "scaffolds";
@import "votes";

.font-heading { font-family: $font-heading; }
.font-body { font-family: $font-body; }
Expand Down
8 changes: 8 additions & 0 deletions app/assets/stylesheets/votes.css.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.vote-header {
display: inline-block;
margin-right: 0.5em;
}

.vote-form {
display: inline-block;
}
42 changes: 42 additions & 0 deletions app/controllers/votes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class VotesController < ApplicationController
before_filter :authenticate_user!
before_filter :set_votable
before_filter :ensure_votable

def create
@votable.liked_by current_user

if @votable.vote_registered?
render partial: 'votes/form', locals: { votable: @votable }
else
head :unprocessable_entity
end
end

def destroy
if current_user.voted_for?(@votable)
@votable.unvote_by current_user
end

render partial: 'votes/form', locals: { votable: @votable }
end

private

def set_votable
model = if params[:votable_type] == "Event"
Event
end

if model
@votable = model.find_by_id(params[:votable_id])
end
end

def ensure_votable
return head(:not_found) unless @votable

# Disallow users to vote on their own items:
head :forbidden if can_edit?(@votable)
end
end
17 changes: 17 additions & 0 deletions app/helpers/votes_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module VotesHelper
def upvote_button_class(votable)
if current_user.voted_up_on?(votable)
"btn bg-orange"
else
"btn bg-grey"
end
end

def upvote_form_method(votable)
if current_user.voted_up_on?(votable)
:delete
else
:post
end
end
end
1 change: 1 addition & 0 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
class Event < ActiveRecord::Base
acts_as :topic
acts_as_taggable
acts_as_votable

has_and_belongs_to_many :people
has_many :indications, as: :questionable
Expand Down
2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class User < ActiveRecord::Base
has_one :person
has_many :topics
accepts_nested_attributes_for :person
acts_as_voter

scope :admins, -> { where('admin = ?', true).all }

Expand All @@ -53,5 +54,4 @@ def self.new_with_session(params, session)
end
end
end

end
7 changes: 6 additions & 1 deletion app/views/events/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<% end %>

<%= link_to indications_path(id: @event.id, type: :event), :method => :post, :class => "btn" do %>
<span class="glyphicon glyphicon-thumbs-down"></span> Flag For Spam
<span class="glyphicon glyphicon-ban-circle"></span> Flag For Spam
<% end %>
<% end %>
</div>
Expand Down Expand Up @@ -54,6 +54,11 @@
</div>
</div>
</div>
<% if user_signed_in? && !can_edit?(@event) %>
<div class="vote-container">
<%= render partial: "votes/form", locals: { votable: @event } %>
</div>
<% end %>
<%= render partial: 'topics/disqus' %>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/views/news/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<% end %>

<%= link_to indications_path(id: @news.id, type: :news), :method => :post, :class => "btn" do %>
<span class="glyphicon glyphicon-thumbs-down"></span> Flag For Spam
<span class="glyphicon glyphicon-ban-circle"></span> Flag For Spam
<% end %>
<% end %>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/views/resources/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<% end %>

<%= link_to indications_path(id: @resource.id, type: :resource), :method => :post, :class => "btn" do %>
<span class="glyphicon glyphicon-thumbs-down"></span> Flag For Spam
<span class="glyphicon glyphicon-ban-circle"></span> Flag For Spam
<% end %>
<% end %>
</div>
Expand Down
13 changes: 13 additions & 0 deletions app/views/votes/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<span class="vote-header">Would you recommend this?</span>
<%= form_tag votes_path, method: upvote_form_method(votable), class: "vote-form", "data-remote" => true do %>
<input type="hidden" name="votable_id" value="<%= votable.id %>">
<input type="hidden" name="votable_type" value="<%= votable.class.name %>">
<button type="submit" class="<%= upvote_button_class(votable) %>">
<span class="glyphicon glyphicon-thumbs-up"></span>
<% if current_user.voted_up_on?(votable) %>
Recommended
<% else %>
Recommend
<% end %>
</button>
<% end %>
6 changes: 6 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
resources :at_who
resources :indications, only: :create

resources :votes, only: [:create] do
collection do
delete :destroy
end
end

resources :people do
collection do
post :send_message
Expand Down
17 changes: 17 additions & 0 deletions db/migrate/20171014222022_create_votes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class CreateVotes < ActiveRecord::Migration
def change
create_table :votes do |t|
t.references :votable, polymorphic: true
t.references :voter, polymorphic: true

t.boolean :vote_flag
t.string :vote_scope
t.integer :vote_weight

t.timestamps
end

add_index :votes, [:voter_id, :voter_type, :vote_scope]
add_index :votes, [:votable_id, :votable_type, :vote_scope]
end
end
16 changes: 16 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

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

ActiveRecord::Schema.define(version: 20171009191656) do
create_table "events", force: true do |t|
Expand Down Expand Up @@ -174,4 +175,19 @@
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
add_index "users", ["uid"], name: "index_users_on_uid"

create_table "votes", force: true do |t|
t.integer "votable_id"
t.string "votable_type"
t.integer "voter_id"
t.string "voter_type"
t.boolean "vote_flag"
t.string "vote_scope"
t.integer "vote_weight"
t.datetime "created_at"
t.datetime "updated_at"
end

add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"

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

describe VotesController, type: :controller do
render_views
let(:votable_owner) { FactoryGirl.create(:user) }
let(:votable) { FactoryGirl.create(:event, user: votable_owner) }

context "authenticated" do
let(:user) { FactoryGirl.create(:user) }
let(:my_votable) { FactoryGirl.create(:event, user: user) }

before(:each) do
request.env["devise.mapping"] = Devise.mappings[:user]
sign_in user
end

describe "#create" do
it "upvotes item the current user cannot edit" do
expect(user.voted_up_on?(votable)).to eq(false)

post :create, votable_type: votable.class.name, votable_id: votable.id

expect(response).to have_http_status(:ok)
expect(user.voted_up_on?(votable)).to eq(true)
end

it "does not upvote item the current user can edit" do
expect(user.voted_up_on?(my_votable)).to eq(false)

post :create, votable_type: my_votable.class.name, votable_id: my_votable.id

expect(response).to have_http_status(:forbidden)
expect(user.voted_up_on?(my_votable)).to eq(false)
end

it "404s when invalid votable type is given" do
post :create, votable_type: user.class.name, votable_id: user.id

expect(response).to have_http_status(:not_found)
end

it "404s when invalid votable ID is given" do
post :create, votable_type: votable.class.name, votable_id: votable.id + 100

expect(response).to have_http_status(:not_found)
end
end

describe "#destroy" do
it "removes an upvote" do
votable.liked_by user
expect(user.voted_for?(votable)).to eq(true)

delete :destroy, votable_type: votable.class.name, votable_id: votable.id

expect(response).to have_http_status(:ok)
expect(user.voted_for?(votable)).to eq(false)
end
end
end

context "unauthenticated" do
describe "#create" do
it "redirects" do
post :create, votable_type: votable.class.name, votable_id: votable.id

expect(response).to have_http_status(:redirect)
end
end

describe "#destroy" do
it "redirects" do
delete :destroy, votable_type: votable.class.name, votable_id: votable.id

expect(response).to have_http_status(:redirect)
end
end
end
end
2 changes: 1 addition & 1 deletion spec/models/indication_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'rails_helper'
require 'spec_helper'

RSpec.describe Indication, :type => :model do
pending "add some examples to (or delete) #{__FILE__}"
Expand Down

0 comments on commit 1646647

Please sign in to comment.