merit 1.7.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/Gemfile +7 -0
- data/README.md +31 -4
- data/app/models/merit/action.rb +2 -3
- data/app/models/merit/badge.rb +2 -2
- data/lib/generators/active_record/install_generator.rb +1 -1
- data/lib/generators/active_record/merit_generator.rb +2 -2
- data/lib/generators/active_record/remove_generator.rb +2 -2
- data/lib/generators/active_record/templates/create_badges_sashes.rb +1 -1
- data/lib/generators/active_record/templates/create_merit_actions.rb +3 -3
- data/lib/generators/active_record/templates/create_scores_and_points.rb +2 -2
- data/lib/generators/active_record/templates/remove_merit_tables.rb +1 -1
- data/lib/generators/merit/install_generator.rb +1 -1
- data/lib/generators/merit/merit_generator.rb +2 -3
- data/lib/generators/merit/remove_generator.rb +3 -3
- data/lib/generators/merit/templates/merit.rb +10 -4
- data/lib/merit.rb +43 -15
- data/lib/merit/base_target_finder.rb +1 -3
- data/lib/merit/judge.rb +26 -6
- data/lib/merit/model_additions.rb +10 -17
- data/lib/merit/models/active_record/merit/action.rb +1 -1
- data/lib/merit/models/active_record/merit/activity_log.rb +1 -0
- data/lib/merit/models/active_record/merit/badges_sash.rb +6 -10
- data/lib/merit/models/active_record/merit/sash.rb +2 -38
- data/lib/merit/models/active_record/merit/score.rb +6 -5
- data/lib/merit/models/base/merit/badges_sash.rb +15 -0
- data/lib/merit/models/base/merit/sash.rb +42 -0
- data/lib/merit/models/mongoid/merit/action.rb +8 -6
- data/lib/merit/models/mongoid/merit/activity_log.rb +11 -0
- data/lib/merit/models/mongoid/merit/badges_sash.rb +19 -0
- data/lib/merit/models/mongoid/merit/sash.rb +28 -0
- data/lib/merit/models/mongoid/merit/score.rb +41 -0
- data/lib/merit/reputation_change_observer.rb +11 -0
- data/lib/merit/rule.rb +1 -1
- data/lib/merit/rules_matcher.rb +0 -2
- data/lib/merit/rules_rank_methods.rb +1 -1
- data/lib/merit/target_finder.rb +1 -2
- data/merit.gemspec +2 -1
- data/test/dummy/app/models/comment.rb +16 -1
- data/test/dummy/app/models/dummy_observer.rb +3 -0
- data/test/dummy/app/models/user.rb +14 -1
- data/test/dummy/config/initializers/merit.rb +3 -4
- data/test/dummy/config/mongoid.yml +13 -0
- data/test/integration/navigation_test.rb +19 -2
- data/test/unit/merit_unit_test.rb +1 -1
- metadata +25 -56
- data/lib/merit/models/mongoid/sash.rb +0 -14
- data/lib/merit/observer.rb +0 -13
- data/test/dummy-mongoid/Rakefile +0 -7
- data/test/dummy-mongoid/app/controllers/application_controller.rb +0 -7
- data/test/dummy-mongoid/app/controllers/comments_controller.rb +0 -90
- data/test/dummy-mongoid/app/controllers/registrations_controller.rb +0 -15
- data/test/dummy-mongoid/app/controllers/users_controller.rb +0 -67
- data/test/dummy-mongoid/app/helpers/application_helper.rb +0 -2
- data/test/dummy-mongoid/app/models/comment.rb +0 -13
- data/test/dummy-mongoid/app/models/merit/badge_rules.rb +0 -49
- data/test/dummy-mongoid/app/models/merit/point_rules.rb +0 -20
- data/test/dummy-mongoid/app/models/merit/rank_rules.rb +0 -24
- data/test/dummy-mongoid/app/models/user.rb +0 -25
- data/test/dummy-mongoid/app/views/comments/_form.html.erb +0 -29
- data/test/dummy-mongoid/app/views/comments/edit.html.erb +0 -6
- data/test/dummy-mongoid/app/views/comments/index.html.erb +0 -35
- data/test/dummy-mongoid/app/views/comments/new.html.erb +0 -5
- data/test/dummy-mongoid/app/views/comments/show.html.erb +0 -23
- data/test/dummy-mongoid/app/views/layouts/application.html.erb +0 -24
- data/test/dummy-mongoid/app/views/users/_form.html.erb +0 -22
- data/test/dummy-mongoid/app/views/users/edit.html.erb +0 -6
- data/test/dummy-mongoid/app/views/users/index.html.erb +0 -26
- data/test/dummy-mongoid/app/views/users/new.html.erb +0 -5
- data/test/dummy-mongoid/app/views/users/show.html.erb +0 -18
- data/test/dummy-mongoid/config.ru +0 -4
- data/test/dummy-mongoid/config/application.rb +0 -22
- data/test/dummy-mongoid/config/boot.rb +0 -10
- data/test/dummy-mongoid/config/environment.rb +0 -5
- data/test/dummy-mongoid/config/environments/development.rb +0 -25
- data/test/dummy-mongoid/config/environments/production.rb +0 -49
- data/test/dummy-mongoid/config/environments/test.rb +0 -35
- data/test/dummy-mongoid/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy-mongoid/config/initializers/inflections.rb +0 -10
- data/test/dummy-mongoid/config/initializers/merit.rb +0 -37
- data/test/dummy-mongoid/config/initializers/mime_types.rb +0 -5
- data/test/dummy-mongoid/config/initializers/secret_token.rb +0 -7
- data/test/dummy-mongoid/config/initializers/session_store.rb +0 -8
- data/test/dummy-mongoid/config/locales/en.yml +0 -5
- data/test/dummy-mongoid/config/mongoid.yml +0 -14
- data/test/dummy-mongoid/config/routes.rb +0 -9
- data/test/dummy-mongoid/db/seeds.rb +0 -17
- data/test/dummy-mongoid/public/404.html +0 -26
- data/test/dummy-mongoid/public/422.html +0 -26
- data/test/dummy-mongoid/public/500.html +0 -26
- data/test/dummy-mongoid/public/favicon.ico +0 -0
- data/test/dummy-mongoid/public/javascripts/application.js +0 -2
- data/test/dummy-mongoid/public/javascripts/controls.js +0 -965
- data/test/dummy-mongoid/public/javascripts/dragdrop.js +0 -974
- data/test/dummy-mongoid/public/javascripts/effects.js +0 -1123
- data/test/dummy-mongoid/public/javascripts/prototype.js +0 -6001
- data/test/dummy-mongoid/public/javascripts/rails.js +0 -191
- data/test/dummy-mongoid/public/stylesheets/.gitkeep +0 -0
- data/test/dummy-mongoid/public/stylesheets/scaffold.css +0 -56
- data/test/dummy-mongoid/script/rails +0 -6
@@ -17,16 +17,18 @@ module Merit
|
|
17
17
|
|
18
18
|
# Delegate methods from meritable models to their sash
|
19
19
|
def _merit_delegate_methods_to_sash
|
20
|
-
methods = %w(badge_ids badges points
|
21
|
-
|
22
|
-
add_points substract_points subtract_points)
|
20
|
+
methods = %w(badge_ids badges points add_badge rm_badge
|
21
|
+
add_points substract_points subtract_points)
|
23
22
|
methods.each { |method| delegate method, to: :_sash }
|
24
23
|
end
|
25
24
|
|
26
25
|
def _merit_orm_specific_config
|
27
|
-
if Merit.orm == :
|
28
|
-
|
29
|
-
|
26
|
+
if Merit.orm == :mongo_mapper
|
27
|
+
plugin Merit
|
28
|
+
key :sash_id, String
|
29
|
+
key :points, Integer, default: 0
|
30
|
+
key :level, Integer, default: 0
|
31
|
+
elsif Merit.orm == :mongoid
|
30
32
|
field :level, type: Integer, default: 0
|
31
33
|
def find_by_id(id)
|
32
34
|
where(_id: id).first
|
@@ -45,18 +47,9 @@ module Merit
|
|
45
47
|
# http://blog.hasmanythrough.com/2012/1/20/modularized-association-methods-in-rails-3-2
|
46
48
|
def _merit_sash_initializer
|
47
49
|
define_method(:_sash) do
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
self.sash
|
50
|
+
sash || update_attribute(:sash_id, Sash.create.id)
|
51
|
+
sash
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
|
-
if Object.const_defined?('ActiveRecord')
|
58
|
-
ActiveRecord::Base.send :include, Merit
|
59
|
-
end
|
60
|
-
if Object.const_defined?('Mongoid')
|
61
|
-
Mongoid::Document.send :include, Merit
|
62
|
-
end
|
@@ -6,7 +6,7 @@ module Merit
|
|
6
6
|
|
7
7
|
if defined?(ProtectedAttributes) || !defined?(ActionController::StrongParameters)
|
8
8
|
attr_accessible :user_id, :action_method, :action_value, :had_errors,
|
9
|
-
|
9
|
+
:target_model, :target_id, :processed, :log
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -4,6 +4,7 @@ module Merit
|
|
4
4
|
|
5
5
|
belongs_to :action, class_name: Merit::Action
|
6
6
|
belongs_to :related_change, polymorphic: true
|
7
|
+
has_one :sash, through: :related_change
|
7
8
|
|
8
9
|
if defined?(ProtectedAttributes) || !defined?(ActionController::StrongParameters)
|
9
10
|
attr_accessible :action_id, :related_change, :description, :created_at
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Merit
|
2
2
|
class BadgesSash < ActiveRecord::Base
|
3
|
-
|
3
|
+
include Base::BadgesSash
|
4
4
|
has_many :activity_logs,
|
5
|
-
|
6
|
-
|
5
|
+
class_name: Merit::ActivityLog,
|
6
|
+
as: :related_change
|
7
7
|
|
8
8
|
if defined?(ProtectedAttributes) || !defined?(ActionController::StrongParameters)
|
9
9
|
attr_accessible :badge_id
|
@@ -12,13 +12,9 @@ module Merit
|
|
12
12
|
def self.last_granted(options = {})
|
13
13
|
options[:since_date] ||= 1.month.ago
|
14
14
|
options[:limit] ||= 10
|
15
|
-
where("created_at > '#{options[:since_date]}'")
|
16
|
-
limit(options[:limit])
|
17
|
-
map(&:badge)
|
18
|
-
end
|
19
|
-
|
20
|
-
def badge
|
21
|
-
Badge.find(badge_id)
|
15
|
+
where("created_at > '#{options[:since_date]}'")
|
16
|
+
.limit(options[:limit])
|
17
|
+
.map(&:badge)
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|
@@ -6,56 +6,20 @@ module Merit
|
|
6
6
|
# It's existence make join models like badges_users and scores_users
|
7
7
|
# unnecessary. It should be transparent at the application.
|
8
8
|
class Sash < ActiveRecord::Base
|
9
|
+
include Base::Sash
|
9
10
|
has_many :badges_sashes, dependent: :destroy
|
10
11
|
has_many :scores, dependent: :destroy, class_name: 'Merit::Score'
|
11
12
|
|
12
13
|
after_create :create_scores
|
13
14
|
|
14
|
-
def badges
|
15
|
-
badge_ids.map { |id| Badge.find id }
|
16
|
-
end
|
17
|
-
|
18
|
-
def badge_ids
|
19
|
-
badges_sashes.map(&:badge_id)
|
20
|
-
end
|
21
|
-
|
22
15
|
def add_badge(badge_id)
|
23
16
|
bs = BadgesSash.new(badge_id: badge_id)
|
24
|
-
|
17
|
+
badges_sashes << bs
|
25
18
|
bs
|
26
19
|
end
|
27
20
|
|
28
21
|
def rm_badge(badge_id)
|
29
22
|
badges_sashes.find_by_badge_id(badge_id).try(:destroy)
|
30
23
|
end
|
31
|
-
|
32
|
-
|
33
|
-
def points(category = 'default')
|
34
|
-
scores.where(category: category).first.points
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_points(num_points, log = 'Manually granted', category = 'default')
|
38
|
-
point = Merit::Score::Point.new
|
39
|
-
point.log = log
|
40
|
-
point.num_points = num_points
|
41
|
-
self.scores.where(category: category).first.score_points << point
|
42
|
-
point
|
43
|
-
end
|
44
|
-
|
45
|
-
# DEPRECATED: Please use <tt>subtract_points</tt> instead.
|
46
|
-
def substract_points(num_points, log = 'Manually granted', category = 'default')
|
47
|
-
warn "[DEPRECATION] `substract_points` is deprecated. Please use `subtract_points` instead."
|
48
|
-
subtract_points num_points, log, category
|
49
|
-
end
|
50
|
-
|
51
|
-
def subtract_points(num_points, log = 'Manually granted', category = 'default')
|
52
|
-
add_points -num_points, log, category
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def create_scores
|
58
|
-
self.scores << Merit::Score.create
|
59
|
-
end
|
60
24
|
end
|
61
25
|
end
|
@@ -3,8 +3,8 @@ module Merit
|
|
3
3
|
self.table_name = :merit_scores
|
4
4
|
belongs_to :sash
|
5
5
|
has_many :score_points,
|
6
|
-
|
7
|
-
|
6
|
+
dependent: :destroy,
|
7
|
+
class_name: 'Merit::Score::Point'
|
8
8
|
|
9
9
|
# Meant to display a leaderboard. Accepts options :table_name (users by
|
10
10
|
# default), :since_date (1.month.ago by default) and :limit (10 by
|
@@ -24,7 +24,7 @@ module Merit
|
|
24
24
|
sash_id_column = "#{options[:table_name]}.sash_id"
|
25
25
|
end
|
26
26
|
|
27
|
-
# MeritableModel
|
27
|
+
# MeritableModel - Sash -< Scores -< ScorePoints
|
28
28
|
sql_query = <<SQL
|
29
29
|
SELECT
|
30
30
|
#{options[:table_name]}.id AS #{alias_id_column},
|
@@ -50,9 +50,10 @@ SQL
|
|
50
50
|
|
51
51
|
class Point < ActiveRecord::Base
|
52
52
|
belongs_to :score, class_name: 'Merit::Score'
|
53
|
+
has_one :sash, through: :score
|
53
54
|
has_many :activity_logs,
|
54
|
-
|
55
|
-
|
55
|
+
class_name: Merit::ActivityLog,
|
56
|
+
as: :related_change
|
56
57
|
end
|
57
58
|
end
|
58
59
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Merit
|
2
|
+
module Base
|
3
|
+
module Sash
|
4
|
+
# Methods that are common between both the active_record and mongoid sash model
|
5
|
+
def badges
|
6
|
+
badge_ids.map { |id| Merit::Badge.find id }
|
7
|
+
end
|
8
|
+
|
9
|
+
def badge_ids
|
10
|
+
badges_sashes.map(&:badge_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
def points(category = 'default')
|
14
|
+
scores.where(category: category).first.points
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_points(num_points, log = 'Manually granted', category = 'default')
|
18
|
+
point = Merit::Score::Point.new
|
19
|
+
point.log = log
|
20
|
+
point.num_points = num_points
|
21
|
+
scores.where(category: category).first.score_points << point
|
22
|
+
point
|
23
|
+
end
|
24
|
+
|
25
|
+
# DEPRECATED: Please use <tt>subtract_points</tt> instead.
|
26
|
+
def substract_points(num_points, log = 'Manually granted', category = 'default')
|
27
|
+
warn '[DEPRECATION] `substract_points` is deprecated. Please use `subtract_points` instead.'
|
28
|
+
subtract_points num_points, log, category
|
29
|
+
end
|
30
|
+
|
31
|
+
def subtract_points(num_points, log = 'Manually granted', category = 'default')
|
32
|
+
add_points(-num_points, log, category)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def create_scores
|
38
|
+
scores << Merit::Score.create
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -3,13 +3,15 @@ module Merit
|
|
3
3
|
include Mongoid::Document
|
4
4
|
include Mongoid::Timestamps
|
5
5
|
|
6
|
-
|
7
|
-
field :action_method
|
8
|
-
field :action_value, type: Integer
|
9
|
-
field :had_errors, type: Boolean
|
6
|
+
has_many :activity_logs, class_name: 'Merit::ActivityLog', as: :related_change
|
10
7
|
|
11
|
-
|
12
|
-
field :
|
8
|
+
field :user_id
|
9
|
+
field :action_method
|
10
|
+
field :action_value, type: Integer
|
11
|
+
field :had_errors, type: Boolean
|
12
|
+
field :target_model
|
13
|
+
field :target_id
|
14
|
+
field :processed, type: Boolean, default: false
|
13
15
|
field :log
|
14
16
|
end
|
15
17
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Merit
|
2
|
+
class BadgesSash
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
include Base::BadgesSash
|
6
|
+
|
7
|
+
field :badge_id, type: Integer
|
8
|
+
attr_accessible :badge_id
|
9
|
+
has_many :activity_logs, class_name: 'Merit::ActivityLog', as: :related_change
|
10
|
+
|
11
|
+
def self.last_granted(options = {})
|
12
|
+
options[:since_date] ||= 1.month.ago
|
13
|
+
options[:limit] ||= 10
|
14
|
+
where(:created_at.lte => options[:since_date])
|
15
|
+
.limit(options[:limit])
|
16
|
+
.map(&:badge)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Merit
|
2
|
+
# Sash is a container for reputation data for meritable models. It's an
|
3
|
+
# indirection between meritable models and badges and scores (one to one
|
4
|
+
# relationship).
|
5
|
+
#
|
6
|
+
# It's existence make join models like badges_users and scores_users
|
7
|
+
# unnecessary. It should be transparent at the application.
|
8
|
+
class Sash
|
9
|
+
include Mongoid::Document
|
10
|
+
include Mongoid::Timestamps
|
11
|
+
include Base::Sash
|
12
|
+
|
13
|
+
has_many :badges_sashes, class_name: 'Merit::BadgesSash', dependent: :destroy
|
14
|
+
has_many :scores, class_name: 'Merit::Score', dependent: :destroy
|
15
|
+
|
16
|
+
after_create :create_scores
|
17
|
+
|
18
|
+
def add_badge(badge_id)
|
19
|
+
bs = Merit::BadgesSash.new(badge_id: badge_id)
|
20
|
+
badges_sashes.push(bs)
|
21
|
+
end
|
22
|
+
|
23
|
+
def rm_badge(badge_id)
|
24
|
+
bs = badges_sashes.where(badge_id: badge_id).first
|
25
|
+
badges_sashes.delete(bs)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Merit
|
2
|
+
class Score
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
|
6
|
+
field :category, type: String, default: 'default'
|
7
|
+
|
8
|
+
belongs_to :sash
|
9
|
+
has_many :score_points, class_name: 'Merit::Score::Point', dependent: :destroy
|
10
|
+
|
11
|
+
# Meant to display a leaderboard. Accepts options :table_name (users by
|
12
|
+
# default), :since_date (1.month.ago by default) and :limit (10 by
|
13
|
+
# default).
|
14
|
+
#
|
15
|
+
# It lists top 10 scored objects in the last month, unless you change
|
16
|
+
# query parameters.
|
17
|
+
def self.top_scored(options = {})
|
18
|
+
options[:since_date] ||= 1.month.ago
|
19
|
+
options[:limit] ||= 10
|
20
|
+
Score.where(created_at: (options[:since_date]..Time.now))
|
21
|
+
.desc(:points)
|
22
|
+
.limit(options[:limit])
|
23
|
+
.flatten.map { |score| score.sash.user }
|
24
|
+
end
|
25
|
+
|
26
|
+
def points
|
27
|
+
score_points.sum(:num_points) || 0
|
28
|
+
end
|
29
|
+
|
30
|
+
class Point
|
31
|
+
include Mongoid::Document
|
32
|
+
include Mongoid::Timestamps
|
33
|
+
|
34
|
+
field :num_points, type: Integer, default: 0
|
35
|
+
field :log, type: String
|
36
|
+
|
37
|
+
belongs_to :score, class_name: 'Merit::Score'
|
38
|
+
has_many :activity_logs, class_name: 'Merit::ActivityLog', as: :related_change
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/merit/rule.rb
CHANGED
@@ -4,7 +4,7 @@ module Merit
|
|
4
4
|
# Could split this class between badges and rankings functionality
|
5
5
|
class Rule
|
6
6
|
attr_accessor :badge_name, :level, :to, :model_name, :level_name,
|
7
|
-
|
7
|
+
:multiple, :temporary, :score, :block
|
8
8
|
|
9
9
|
# Does this rule's condition block apply?
|
10
10
|
def applies?(target_obj = nil)
|
data/lib/merit/rules_matcher.rb
CHANGED
@@ -23,7 +23,7 @@ module Merit
|
|
23
23
|
end
|
24
24
|
|
25
25
|
defined_rules[options[:to]] ||= {}
|
26
|
-
defined_rules[options[:to]].merge!(
|
26
|
+
defined_rules[options[:to]].merge!(options[:level] => rule)
|
27
27
|
end
|
28
28
|
|
29
29
|
# Not part of merit after_filter. To be called asynchronously:
|
data/lib/merit/target_finder.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Merit
|
2
2
|
class TargetFinder < Struct.new(:rule, :action)
|
3
3
|
def self.find(*args)
|
4
|
-
|
4
|
+
new(*args).find
|
5
5
|
end
|
6
6
|
|
7
7
|
def find
|
@@ -40,6 +40,5 @@ module Merit
|
|
40
40
|
str << ' (called from Merit::TargetFinder#other_target)'
|
41
41
|
Rails.logger.warn str
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
45
44
|
end
|
data/merit.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.homepage = "http://github.com/tute/merit"
|
6
6
|
s.files = `git ls-files`.split("\n").reject{|f| f =~ /^\./ }
|
7
7
|
s.license = 'MIT'
|
8
|
-
s.version = '1.
|
8
|
+
s.version = '1.8.0'
|
9
9
|
s.authors = ["Tute Costa"]
|
10
10
|
s.email = 'tutecosta@gmail.com'
|
11
11
|
|
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_development_dependency 'rails', '>= 3.2.0'
|
16
16
|
s.add_development_dependency 'capybara'
|
17
17
|
s.add_development_dependency 'simplecov'
|
18
|
+
s.add_development_dependency 'rubocop'
|
18
19
|
s.add_development_dependency 'minitest-rails'
|
19
20
|
s.add_development_dependency 'mocha', '0.13.3'
|
20
21
|
end
|