votes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/*
19
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in votes.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Alexander Logunov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ # Votes
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'votes'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install votes
18
+
19
+ ## Usage
20
+ используемые методы которые нужно реализовать:
21
+ current_user
22
+ authorize!
23
+
24
+ в поля моделей base_rating и rating
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin my-new-feature`)
32
+ 5. Create new Pull Request
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,23 @@
1
+ class VotesController < ApplicationController
2
+ respond_to :json
3
+
4
+ def create
5
+ unless params[:voteable_type].blank? and params[:voteable_id].blank?
6
+ voteable_class = params[:voteable_type].constantize
7
+ voteable = voteable_class.find(params[:voteable_id])
8
+ else
9
+ voteable = nil
10
+ end
11
+
12
+ authorize! :vote, voteable
13
+
14
+ vote = voteable.vote_by_current_visitor(current_user, session[:id]) || Vote.create!(
15
+ :voteable => voteable,
16
+ :session_key => session[:id],
17
+ :user => current_user,
18
+ :tone => params[:tone].to_i
19
+ )
20
+
21
+ render nothing: true
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ class Vote < ActiveRecord::Base
2
+ attr_accessor :dont_update_rating
3
+
4
+ belongs_to :user
5
+ belongs_to :voteable, :polymorphic => true
6
+
7
+ before_validation do
8
+ self.session_key = "user#{self.user.id}" if self.session_key.nil? and self.user.present?
9
+ self.tone = 1 unless self.tone
10
+ end
11
+
12
+ before_save do
13
+ self.power = if self.user
14
+ self.user.power_of_vote
15
+ else
16
+ 1
17
+ end
18
+ self.points = self.power * self.tone
19
+ end
20
+
21
+ validates_presence_of :voteable_type, :voteable_id, :tone, :session_key
22
+
23
+ validates_uniqueness_of :user_id, :scope => [:voteable_type, :voteable_id], :if => lambda { |r| r.user_id }
24
+ validates_uniqueness_of :session_key, :scope => [:voteable_type, :voteable_id]
25
+
26
+ after_create :update_rating
27
+
28
+ private
29
+
30
+ def update_rating
31
+ voteable.update_rating(self) unless dont_update_rating
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ require "votes/version"
2
+ require "active_record"
3
+
4
+ require 'votes/active_record_ext'
5
+ ActiveRecord::Base.extend Votes::ActiveRecordExt
6
+
7
+ require 'votes/engine' if defined? Rails
@@ -0,0 +1,51 @@
1
+ module Votes::ActiveRecordExt
2
+ def be_voteable
3
+ has_many :votes, :as => :voteable, :dependent => :destroy
4
+ include VoteableInstanceMethods
5
+ end
6
+
7
+ def be_voter args={power:1}
8
+ @voter_power_of_vote = args[:power]
9
+ has_many :voter_votes, :class_name => 'Vote', :foreign_key => :user_id, :dependent => :destroy
10
+ include VoterInstanceMethods
11
+ end
12
+
13
+ module VoterInstanceMethods
14
+ def power_of_vote
15
+ voter_power_of_vote = self.class.instance_variable_get(:@voter_power_of_vote)
16
+ if voter_power_of_vote.is_a?(Numeric)
17
+ voter_power_of_vote
18
+ elsif voter_power_of_vote.is_a?(Proc)
19
+ self.instance_exec(&voter_power_of_vote)
20
+ else
21
+ self.send(voter_power_of_vote)
22
+ end
23
+ end
24
+ end
25
+
26
+ module VoteableInstanceMethods
27
+ def vote_by_current_visitor current_user, session
28
+ if current_user
29
+ vote_by_user(current_user)
30
+ else
31
+ vote_by_session_key(session)
32
+ end
33
+ end
34
+
35
+ def vote_by_user user
36
+ self.votes.find_by_user_id(user.id)
37
+ end
38
+
39
+ def vote_by_session_key session_key
40
+ self.votes.find_by_session_key(session_key)
41
+ end
42
+
43
+ def update_rating(vote)
44
+ self.update_attribute(:rating, self.rating + vote.points)
45
+ end
46
+
47
+ def recalculate_rating
48
+ self.update_attribute(:rating, self.base_rating + self.votes.map(&:points).sum)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,6 @@
1
+ module Votes
2
+ class Engine < Rails::Engine
3
+ paths["app/controllers"] << "lib/controllers"
4
+ paths["app/models"] << "lib/models"
5
+ end
6
+ end
@@ -0,0 +1,23 @@
1
+ module Votes::Migration
2
+ def create_votes_table
3
+ create_table :votes do |t|
4
+ t.references :voteable, :polymorphic => true, :null => false
5
+ t.integer :points, :null => false, :default => 0
6
+ t.integer :power
7
+ t.integer :tone
8
+ t.integer :user_id, :null => false
9
+
10
+ t.timestamps
11
+
12
+ yield(t) if block_given?
13
+ end
14
+
15
+ add_index :votes, [:voteable_id, :voteable_type, :user_id], :unique => true
16
+ add_index :votes, [:user_id, :voteable_id, :voteable_type], :unique => true
17
+ end
18
+
19
+ def add_rating_columns(table_name)
20
+ add_column table_name, :base_rating, :decimal, :null => false, :default => 0
21
+ add_column table_name, :rating, :decimal, :null => false, :default => 0
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Votes
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ require "rspec"
2
+ require "votes"
3
+ require "models/vote"
4
+
5
+ RSpec.configure do |config|
6
+ config.color_enabled = true
7
+ config.formatter = 'documentation'
8
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
4
+
5
+ def setup_db
6
+ ActiveRecord::Schema.define(:version => 1) do
7
+ create_table "votes", :force => true do |t|
8
+ t.integer "voteable_id", :null => false
9
+ t.string "voteable_type", :null => false
10
+ t.integer "points", :default => 0, :null => false
11
+ t.integer "user_id"
12
+ t.datetime "created_at"
13
+ t.datetime "updated_at"
14
+ t.string "session_key", :null => false
15
+ t.integer "power"
16
+ t.integer "tone"
17
+ end
18
+
19
+ add_index "votes", ["voteable_id", "voteable_type", "session_key"], :name => "index_rates_on_rateable_id_and_rateable_type_and_session_key", :unique => true
20
+ add_index "votes", ["voteable_id", "voteable_type", "user_id"], :name => "index_rates_on_rateable_id_and_rateable_type_and_user_id"
21
+
22
+ create_table "users", :force => true do |t|
23
+ t.string "login", :limit => 50, :null => false
24
+ t.decimal "base_rating", :precision => 10, :scale => 0, :default => 0, :null => false
25
+ t.decimal "rating", :precision => 10, :scale => 0, :default => 0, :null => false
26
+ end
27
+ end
28
+
29
+ User.create(:login=>'test_login')
30
+ end
31
+
32
+ class User < ActiveRecord::Base
33
+ be_voteable
34
+ be_voter
35
+ end
36
+
37
+ # drop all tables
38
+ def teardown_db
39
+ ActiveRecord::Base.connection.tables.each do |table|
40
+ ActiveRecord::Base.connection.drop_table(table)
41
+ end
42
+ end
43
+
44
+
45
+ describe 'Voting' do
46
+ before do
47
+ setup_db
48
+ end
49
+
50
+ after do
51
+ teardown_db
52
+ end
53
+
54
+ it "should count vote" do
55
+ user = User.first
56
+ user.votes.all
57
+ user.votes.create(:tone => -1, :user => user)
58
+ user.reload.rating.should be -1
59
+ end
60
+
61
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'votes/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "votes"
8
+ gem.version = Votes::VERSION
9
+ gem.authors = ["Danil Pismenny", "Alexander Logunov"]
10
+ gem.email = ["danil@orionet.ru", "unlovedru@gmail.com"]
11
+ gem.description = "Simple voting system"
12
+ gem.summary = "Simple voting system"
13
+ gem.homepage = "https://github.com/BrandyMint/votes"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency "rspec"
21
+ gem.add_development_dependency "sqlite3"
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: votes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Danil Pismenny
9
+ - Alexander Logunov
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-10-24 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: sqlite3
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ description: Simple voting system
48
+ email:
49
+ - danil@orionet.ru
50
+ - unlovedru@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - LICENSE.txt
58
+ - README.md
59
+ - Rakefile
60
+ - lib/controllers/votes_controller.rb
61
+ - lib/models/vote.rb
62
+ - lib/votes.rb
63
+ - lib/votes/active_record_ext.rb
64
+ - lib/votes/engine.rb
65
+ - lib/votes/migration.rb
66
+ - lib/votes/version.rb
67
+ - spec/spec_helper.rb
68
+ - spec/votes_spec.rb
69
+ - votes.gemspec
70
+ homepage: https://github.com/BrandyMint/votes
71
+ licenses: []
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.24
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Simple voting system
94
+ test_files:
95
+ - spec/spec_helper.rb
96
+ - spec/votes_spec.rb
97
+ has_rdoc: