qalam_merit 4.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +358 -0
- data/RELEASING.md +16 -0
- data/Rakefile +44 -0
- data/TESTING.txt +12 -0
- data/config/locales/en.yml +5 -0
- data/lib/merit.rb +95 -0
- data/lib/merit/badge_rules_methods.rb +30 -0
- data/lib/merit/base_target_finder.rb +31 -0
- data/lib/merit/class_methods.rb +41 -0
- data/lib/merit/controller_extensions.rb +71 -0
- data/lib/merit/generators/active_record/install_generator.rb +40 -0
- data/lib/merit/generators/active_record/merit_generator.rb +25 -0
- data/lib/merit/generators/active_record/remove_generator.rb +30 -0
- data/lib/merit/generators/active_record/templates/add_merit_fields_to_model.erb +7 -0
- data/lib/merit/generators/active_record/templates/create_badges_sashes.erb +14 -0
- data/lib/merit/generators/active_record/templates/create_merit_actions.erb +16 -0
- data/lib/merit/generators/active_record/templates/create_merit_activity_logs.erb +12 -0
- data/lib/merit/generators/active_record/templates/create_merit_badges.erb +17 -0
- data/lib/merit/generators/active_record/templates/create_sashes.erb +8 -0
- data/lib/merit/generators/active_record/templates/create_scores_and_points.erb +16 -0
- data/lib/merit/generators/active_record/templates/remove_merit_fields_from_model.erb +7 -0
- data/lib/merit/generators/active_record/templates/remove_merit_tables.erb +12 -0
- data/lib/merit/generators/install_generator.rb +30 -0
- data/lib/merit/generators/merit_generator.rb +33 -0
- data/lib/merit/generators/remove_generator.rb +23 -0
- data/lib/merit/generators/templates/badge.erb +69 -0
- data/lib/merit/generators/templates/merit.erb +18 -0
- data/lib/merit/generators/templates/merit_badge_rules.erb +50 -0
- data/lib/merit/generators/templates/merit_point_rules.erb +31 -0
- data/lib/merit/generators/templates/merit_rank_rules.erb +32 -0
- data/lib/merit/generators/templates/qalam_badge_sash.erb +20 -0
- data/lib/merit/generators/templates/qalam_sash.erb +14 -0
- data/lib/merit/judge.rb +102 -0
- data/lib/merit/models/action_concern.rb +50 -0
- data/lib/merit/models/active_record/action.rb +11 -0
- data/lib/merit/models/active_record/activity_log.rb +11 -0
- data/lib/merit/models/active_record/badges_sash.rb +13 -0
- data/lib/merit/models/active_record/sash.rb +32 -0
- data/lib/merit/models/active_record/score.rb +25 -0
- data/lib/merit/models/badges_sash_concern.rb +13 -0
- data/lib/merit/models/base/badges_sash.rb +15 -0
- data/lib/merit/models/base/sash.rb +55 -0
- data/lib/merit/models/sash_concern.rb +53 -0
- data/lib/merit/point_rules_methods.rb +33 -0
- data/lib/merit/rank_rules_methods.rb +58 -0
- data/lib/merit/reputation_change_observer.rb +19 -0
- data/lib/merit/rule.rb +35 -0
- data/lib/merit/rules_matcher.rb +24 -0
- data/lib/merit/sash_finder.rb +15 -0
- data/lib/merit/target_finder.rb +43 -0
- data/qalam_merit.gemspec +23 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/admin/users_controller.rb +9 -0
- data/test/dummy/app/controllers/api/comments_controller.rb +5 -0
- data/test/dummy/app/controllers/api/users_controller.rb +5 -0
- data/test/dummy/app/controllers/application_controller.rb +7 -0
- data/test/dummy/app/controllers/comments_controller.rb +56 -0
- data/test/dummy/app/controllers/registrations_controller.rb +21 -0
- data/test/dummy/app/controllers/users_controller.rb +38 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/address.rb +3 -0
- data/test/dummy/app/models/comment.rb +13 -0
- data/test/dummy/app/models/dummy_observer.rb +3 -0
- data/test/dummy/app/models/merit/badge_rules.rb +66 -0
- data/test/dummy/app/models/merit/point_rules.rb +44 -0
- data/test/dummy/app/models/merit/rank_rules.rb +24 -0
- data/test/dummy/app/models/user.rb +23 -0
- data/test/dummy/app/views/admin/users/index.html.erb +26 -0
- data/test/dummy/app/views/comments/_form.html.erb +29 -0
- data/test/dummy/app/views/comments/edit.html.erb +6 -0
- data/test/dummy/app/views/comments/index.html.erb +35 -0
- data/test/dummy/app/views/comments/new.html.erb +5 -0
- data/test/dummy/app/views/comments/show.html.erb +23 -0
- data/test/dummy/app/views/layouts/application.html.erb +24 -0
- data/test/dummy/app/views/users/_form.html.erb +22 -0
- data/test/dummy/app/views/users/edit.html.erb +6 -0
- data/test/dummy/app/views/users/index.html.erb +27 -0
- data/test/dummy/app/views/users/new.html.erb +5 -0
- data/test/dummy/app/views/users/show.html.erb +18 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/application_api_only.rb +28 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environment_api_only.rb +7 -0
- data/test/dummy/config/environments/development.rb +24 -0
- data/test/dummy/config/environments/production.rb +51 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/merit.rb +47 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/new_framework_defaults.rb +3 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/mongoid.yml +13 -0
- data/test/dummy/config/routes.rb +16 -0
- data/test/dummy/db/migrate/20110421191249_create_users.rb +12 -0
- data/test/dummy/db/migrate/20110421191250_create_comments.rb +16 -0
- data/test/dummy/db/migrate/20120318022220_add_fields_to_users.rb +11 -0
- data/test/dummy/db/migrate/20130321082817_add_fields_to_comments.rb +11 -0
- data/test/dummy/db/migrate/20130329224406_create_merit_actions.rb +18 -0
- data/test/dummy/db/migrate/20130329224407_create_merit_activity_logs.rb +15 -0
- data/test/dummy/db/migrate/20130329224408_create_sashes.rb +11 -0
- data/test/dummy/db/migrate/20130329224409_create_badges_sashes.rb +16 -0
- data/test/dummy/db/migrate/20130329224410_create_scores_and_points.rb +20 -0
- data/test/dummy/db/migrate/20140211144001_create_addresses.rb +11 -0
- data/test/dummy/db/migrate/20140819133931_add_target_data_to_merit_actions.rb +5 -0
- data/test/dummy/db/schema.rb +89 -0
- data/test/dummy/db/seeds.rb +19 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/rails.js +404 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/public/stylesheets/scaffold.css +56 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +332 -0
- data/test/support/integration_case.rb +5 -0
- data/test/test_helper.rb +40 -0
- data/test/unit/action_test.rb +12 -0
- data/test/unit/base_target_finder_test.rb +64 -0
- data/test/unit/merit_unit_test.rb +33 -0
- data/test/unit/rule_unit_test.rb +57 -0
- data/test/unit/rules_matcher_test.rb +37 -0
- data/test/unit/sash_finder_test.rb +27 -0
- data/test/unit/sash_test.rb +104 -0
- data/test/unit/score_test.rb +13 -0
- data/test/unit/target_finder_test.rb +98 -0
- metadata +360 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
### QALAM_MERIT ###
|
|
2
|
+
class Merit::QalamSash < ActiveRecord::Base
|
|
3
|
+
self.table_name = "sashes"
|
|
4
|
+
has_many :badges_sashes, class_name: 'Merit::QalamBadgeSash'
|
|
5
|
+
has_many :badges, through: :badges_sashes, source: :badge
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def user(sash_id = nil)
|
|
9
|
+
return [] unless sash_id
|
|
10
|
+
|
|
11
|
+
User.where(sash_id: sash_id)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/merit/judge.rb
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'observer'
|
|
2
|
+
|
|
3
|
+
module Merit
|
|
4
|
+
class Judge
|
|
5
|
+
include Observable
|
|
6
|
+
|
|
7
|
+
def initialize(rule, options = {})
|
|
8
|
+
@rule = rule
|
|
9
|
+
@action = options[:action]
|
|
10
|
+
Merit.observers.each do |class_name|
|
|
11
|
+
add_observer class_name.constantize.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Grant badge if rule applies. If it doesn't, and the badge is temporary,
|
|
16
|
+
# then remove it.
|
|
17
|
+
def apply_badges
|
|
18
|
+
if rule_applies?
|
|
19
|
+
grant_badges
|
|
20
|
+
else
|
|
21
|
+
remove_badges if @rule.temporary
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def apply_points
|
|
26
|
+
return unless rule_applies?
|
|
27
|
+
sashes.each do |sash|
|
|
28
|
+
point = sash.add_points points, category: category
|
|
29
|
+
notify_observers(
|
|
30
|
+
description: I18n.t("merit.granted_points", points: points),
|
|
31
|
+
merit_object: point,
|
|
32
|
+
sash_id: point.sash_id
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def grant_badges
|
|
40
|
+
sashes.each do |sash|
|
|
41
|
+
next unless new_or_multiple?(sash)
|
|
42
|
+
badge_sash = sash.add_badge badge.id
|
|
43
|
+
notify_observers(
|
|
44
|
+
description: I18n.t("merit.granted_badge", badge_name: badge.name),
|
|
45
|
+
merit_object: badge_sash,
|
|
46
|
+
sash_id: badge_sash.sash_id
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def remove_badges
|
|
52
|
+
sashes.each do |sash|
|
|
53
|
+
sash.rm_badge badge.id
|
|
54
|
+
notify_observers(
|
|
55
|
+
description: I18n.t("merit.removed_badge", badge_name: badge.name),
|
|
56
|
+
sash_id: sash.id
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def new_or_multiple?(sash)
|
|
62
|
+
!sash.badge_ids.include?(badge.id) || @rule.multiple
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def rule_object
|
|
66
|
+
BaseTargetFinder.find(@rule, @action)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def rule_applies?
|
|
70
|
+
@rule.applies? rule_object
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def points
|
|
74
|
+
if @rule.score.respond_to?(:call)
|
|
75
|
+
@rule.score.call(rule_object)
|
|
76
|
+
else
|
|
77
|
+
@rule.score
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def category
|
|
82
|
+
@rule.category
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def sashes
|
|
86
|
+
@sashes ||= SashFinder.find @rule, @action
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def badge
|
|
90
|
+
@rule.badge
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def notify_observers(changed_data = {})
|
|
94
|
+
changed
|
|
95
|
+
hash = {
|
|
96
|
+
granted_at: @action.created_at,
|
|
97
|
+
merit_action_id: @action.id
|
|
98
|
+
}.merge(changed_data)
|
|
99
|
+
super(hash)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Merit::Action general schema
|
|
2
|
+
# ______________________________________________________________
|
|
3
|
+
# source | action | target
|
|
4
|
+
# user_id | method,value | model,id | processed
|
|
5
|
+
# ______________________________________________________________
|
|
6
|
+
# 1 | comment nil | List 8 | true
|
|
7
|
+
# 1 | vote 3 | List 12 | true
|
|
8
|
+
# 3 | follow nil | User 1 | false
|
|
9
|
+
# X | create nil | User #{generated_id} | false
|
|
10
|
+
# ______________________________________________________________
|
|
11
|
+
#
|
|
12
|
+
# Rules relate to merit_actions by action name ('controller#action' string)
|
|
13
|
+
module Merit::Models
|
|
14
|
+
module ActionConcern
|
|
15
|
+
extend ActiveSupport::Concern
|
|
16
|
+
|
|
17
|
+
class_methods do
|
|
18
|
+
def check_unprocessed
|
|
19
|
+
where(processed: false).find_each(&:check_all_rules)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Check rules defined for a merit_action
|
|
24
|
+
def check_all_rules
|
|
25
|
+
mark_as_processed!
|
|
26
|
+
return if had_errors
|
|
27
|
+
|
|
28
|
+
check_rules rules_matcher.select_from(Merit::AppBadgeRules), :badges
|
|
29
|
+
check_rules rules_matcher.select_from(Merit::AppPointRules), :points
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def check_rules(rules_array, badges_or_points)
|
|
35
|
+
rules_array.each do |rule|
|
|
36
|
+
judge = Merit::Judge.new(rule, action: self)
|
|
37
|
+
judge.public_send(:"apply_#{badges_or_points}")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def mark_as_processed!
|
|
42
|
+
self.processed = true
|
|
43
|
+
save
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def rules_matcher
|
|
47
|
+
@rules_matcher ||= ::Merit::RulesMatcher.new(target_model, action_method)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Merit::Models::ActiveRecord
|
|
2
|
+
class Action < ActiveRecord::Base
|
|
3
|
+
include Merit::Models::ActionConcern
|
|
4
|
+
|
|
5
|
+
self.table_name = :merit_actions
|
|
6
|
+
|
|
7
|
+
has_many :activity_logs, class_name: 'Merit::ActivityLog'
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Merit::Action < Merit::Models::ActiveRecord::Action; end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Merit::Models::ActiveRecord
|
|
2
|
+
class ActivityLog < ActiveRecord::Base
|
|
3
|
+
self.table_name = :merit_activity_logs
|
|
4
|
+
|
|
5
|
+
belongs_to :action, class_name: 'Merit::Action'
|
|
6
|
+
belongs_to :related_change, polymorphic: true, optional: true
|
|
7
|
+
has_one :sash, through: :related_change
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Merit::ActivityLog < Merit::Models::ActiveRecord::ActivityLog; end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Merit::Models::ActiveRecord
|
|
2
|
+
class BadgesSash < ActiveRecord::Base
|
|
3
|
+
include Merit::Models::BadgesSashConcern
|
|
4
|
+
|
|
5
|
+
has_many :activity_logs,
|
|
6
|
+
class_name: 'Merit::ActivityLog',
|
|
7
|
+
as: :related_change
|
|
8
|
+
|
|
9
|
+
validates_presence_of :badge_id, :sash
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Merit::BadgesSash < Merit::Models::ActiveRecord::BadgesSash; end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Merit::Models::ActiveRecord
|
|
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 < ActiveRecord::Base
|
|
9
|
+
include Merit::Models::SashConcern
|
|
10
|
+
|
|
11
|
+
has_many :badges_sashes, dependent: :destroy
|
|
12
|
+
has_many :scores, dependent: :destroy, class_name: 'Merit::Score'
|
|
13
|
+
|
|
14
|
+
after_create :create_scores
|
|
15
|
+
|
|
16
|
+
# Retrieve all points from a category or none if category doesn't exist
|
|
17
|
+
# By default retrieve all Points
|
|
18
|
+
# @param category [String] The category
|
|
19
|
+
# @return [ActiveRecord::Relation] containing the points
|
|
20
|
+
def score_points(options = {})
|
|
21
|
+
scope = Merit::Score::Point
|
|
22
|
+
.joins(:score)
|
|
23
|
+
.where('merit_scores.sash_id = ?', id)
|
|
24
|
+
if (category = options[:category])
|
|
25
|
+
scope = scope.where('merit_scores.category = ?', category)
|
|
26
|
+
end
|
|
27
|
+
scope
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Merit::Sash < Merit::Models::ActiveRecord::Sash; end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Merit::Models::ActiveRecord
|
|
2
|
+
class Score < ActiveRecord::Base
|
|
3
|
+
self.table_name = :merit_scores
|
|
4
|
+
belongs_to :sash
|
|
5
|
+
has_many :score_points,
|
|
6
|
+
dependent: :destroy,
|
|
7
|
+
class_name: 'Merit::Score::Point'
|
|
8
|
+
|
|
9
|
+
def points
|
|
10
|
+
score_points.group(:score_id).sum(:num_points).values.first || 0
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Point < ActiveRecord::Base
|
|
14
|
+
belongs_to :score, class_name: 'Merit::Score'
|
|
15
|
+
has_one :sash, through: :score
|
|
16
|
+
has_many :activity_logs,
|
|
17
|
+
class_name: 'Merit::ActivityLog',
|
|
18
|
+
as: :related_change
|
|
19
|
+
delegate :sash_id, to: :score
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class Merit::Score < Merit::Models::ActiveRecord::Score; end
|
|
25
|
+
class Merit::Score::Point < Merit::Models::ActiveRecord::Score::Point; end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
module Models::Base
|
|
3
|
+
module Sash
|
|
4
|
+
def badges
|
|
5
|
+
badge_ids.map { |id| Merit::Badge.find id }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def badge_ids
|
|
9
|
+
badges_sashes.map(&:badge_id)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add_badge(badge_id)
|
|
13
|
+
bs = Merit::BadgesSash.new(badge_id: badge_id.to_i)
|
|
14
|
+
badges_sashes << bs
|
|
15
|
+
bs
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def rm_badge(badge_id)
|
|
19
|
+
badges_sashes.where(badge_id: badge_id.to_i).first.try(:destroy)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Retrieve the number of points from a category
|
|
23
|
+
# By default all points are summed up
|
|
24
|
+
# @param category [String] The category
|
|
25
|
+
# @return [Integer] The number of points
|
|
26
|
+
def points(options = {})
|
|
27
|
+
if (category = options[:category])
|
|
28
|
+
scores.where(category: category).first.try(:points) || 0
|
|
29
|
+
else
|
|
30
|
+
scores.reduce(0) { |sum, score| sum + score.points }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def add_points(num_points, options = {})
|
|
35
|
+
point = Merit::Score::Point.new
|
|
36
|
+
point.num_points = num_points
|
|
37
|
+
scores
|
|
38
|
+
.where(category: options[:category] || 'default')
|
|
39
|
+
.first_or_create
|
|
40
|
+
.score_points << point
|
|
41
|
+
point
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def subtract_points(num_points, options = {})
|
|
45
|
+
add_points(-num_points, options)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def create_scores
|
|
51
|
+
scores << Merit::Score.create
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Merit::Models
|
|
2
|
+
module SashConcern
|
|
3
|
+
def badges
|
|
4
|
+
badge_ids.map { |id| Merit::Badge.find id }
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def badge_ids
|
|
8
|
+
badges_sashes.map(&:badge_id)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def add_badge(badge_id)
|
|
12
|
+
bs = Merit::BadgesSash.new(badge_id: badge_id.to_i)
|
|
13
|
+
badges_sashes << bs
|
|
14
|
+
bs
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def rm_badge(badge_id)
|
|
18
|
+
badges_sashes.where(badge_id: badge_id.to_i).first.try(:destroy)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Retrieve the number of points from a category
|
|
22
|
+
# By default all points are summed up
|
|
23
|
+
# @param category [String] The category
|
|
24
|
+
# @return [Integer] The number of points
|
|
25
|
+
def points(options = {})
|
|
26
|
+
if (category = options[:category])
|
|
27
|
+
scores.where(category: category).first.try(:points) || 0
|
|
28
|
+
else
|
|
29
|
+
scores.reduce(0) { |sum, score| sum + score.points }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_points(num_points, options = {})
|
|
34
|
+
point = Merit::Score::Point.new
|
|
35
|
+
point.num_points = num_points
|
|
36
|
+
scores
|
|
37
|
+
.where(category: options[:category] || 'default')
|
|
38
|
+
.first_or_create
|
|
39
|
+
.score_points << point
|
|
40
|
+
point
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def subtract_points(num_points, options = {})
|
|
44
|
+
add_points(-num_points, options)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def create_scores
|
|
50
|
+
scores << Merit::Score.create
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
# Points are a simple integer value which are given to "meritable" resources
|
|
3
|
+
# according to rules in +app/models/merit/point_rules.rb+. They are given on
|
|
4
|
+
# actions-triggered.
|
|
5
|
+
module PointRulesMethods
|
|
6
|
+
# Define rules on certaing actions for giving points
|
|
7
|
+
def score(points, *args, &block)
|
|
8
|
+
options = args.extract_options!
|
|
9
|
+
options_to = options.fetch(:to) { :action_user }
|
|
10
|
+
|
|
11
|
+
actions = Array.wrap(options[:on])
|
|
12
|
+
|
|
13
|
+
Array.wrap(options_to).each do |to|
|
|
14
|
+
rule = Rule.new
|
|
15
|
+
rule.score = points
|
|
16
|
+
rule.to = to
|
|
17
|
+
rule.block = block
|
|
18
|
+
rule.category = options.fetch(:category) { :default }
|
|
19
|
+
rule.model_name = options[:model_name] if options[:model_name]
|
|
20
|
+
|
|
21
|
+
actions.each do |action|
|
|
22
|
+
defined_rules[action] ||= []
|
|
23
|
+
defined_rules[action] << rule
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Currently defined rules
|
|
29
|
+
def defined_rules
|
|
30
|
+
@defined_rules ||= {}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|