merit 1.1.0 → 1.1.1
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.
- data/Gemfile.lock +1 -1
- data/README.md +0 -4
- data/app/models/badge.rb +12 -1
- data/app/models/merit_action.rb +38 -22
- data/lib/generators/active_record/templates/create_merit_actions.rb +1 -1
- data/lib/merit.rb +7 -3
- data/lib/merit/controller_extensions.rb +27 -20
- data/lib/merit/model_additions.rb +11 -24
- data/lib/merit/models/active_record/merit/score.rb +0 -1
- data/lib/merit/models/active_record/sash.rb +14 -0
- data/lib/merit/rule.rb +8 -17
- data/lib/merit/rules_badge_methods.rb +29 -0
- data/lib/merit/{rules_points.rb → rules_points_methods.rb} +0 -0
- data/lib/merit/{rules_rank.rb → rules_rank_methods.rb} +2 -1
- data/merit.gemspec +1 -1
- data/test/merit_unit_test.rb +0 -6
- metadata +5 -5
- data/lib/merit/rules_badge.rb +0 -64
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -148,11 +148,7 @@ end
|
|
|
148
148
|
|
|
149
149
|
# To-do list
|
|
150
150
|
|
|
151
|
-
* `Merit::BadgeRules.new.defined_rules` should be cached on initialization,
|
|
152
|
-
instead of initialized per controllers `after_filter` and
|
|
153
|
-
`merit_action.check_rules`.
|
|
154
151
|
* target_object should be configurable (now it's singularized controller name)
|
|
155
|
-
* Translate comments from spanish in `rules_badge.rb`.
|
|
156
152
|
* Should namespace app/models into Merit module.
|
|
157
153
|
* :value parameter (for star voting for example) should be configurable
|
|
158
154
|
(depends on params[:value] on the controller).
|
data/app/models/badge.rb
CHANGED
|
@@ -23,6 +23,15 @@ class Badge
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def self.find_by_name_and_level(name, level)
|
|
27
|
+
badges = Badge.by_name(name)
|
|
28
|
+
badges = badges.by_level(level) unless level.nil?
|
|
29
|
+
if !(badge = badges.first)
|
|
30
|
+
raise ::Merit::BadgeNotFound, "No badge '#{name}'#{level.nil? ? '' : " with level #{level}"} found. Define it in 'config/initializers/merit.rb'."
|
|
31
|
+
end
|
|
32
|
+
badge
|
|
33
|
+
end
|
|
34
|
+
|
|
26
35
|
# Grant badge to sash
|
|
27
36
|
# Accepts :allow_multiple boolean option, defaults to false
|
|
28
37
|
def grant_to(object_or_sash, *args)
|
|
@@ -49,11 +58,13 @@ class Badge
|
|
|
49
58
|
end
|
|
50
59
|
end
|
|
51
60
|
|
|
61
|
+
private
|
|
62
|
+
|
|
52
63
|
def sash_from(object_or_sash)
|
|
53
64
|
if object_or_sash.kind_of?(Sash)
|
|
54
65
|
object_or_sash
|
|
55
66
|
else
|
|
56
|
-
object_or_sash.
|
|
67
|
+
object_or_sash._sash
|
|
57
68
|
end
|
|
58
69
|
end
|
|
59
70
|
end
|
data/app/models/merit_action.rb
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
require "merit/models/#{Merit.orm}/merit_action"
|
|
2
2
|
|
|
3
|
+
# MeritAction general schema
|
|
4
|
+
# ______________________________________________________________
|
|
5
|
+
# source | action | target
|
|
6
|
+
# user_id | method,value | model,id | processed
|
|
7
|
+
# ______________________________________________________________
|
|
8
|
+
# 1 | comment nil | List 8 | true
|
|
9
|
+
# 1 | vote 3 | List 12 | true
|
|
10
|
+
# 3 | follow nil | User 1 | false
|
|
11
|
+
# X | create nil | User #{generated_id} | false
|
|
12
|
+
# ______________________________________________________________
|
|
13
|
+
#
|
|
14
|
+
# Rules relate to merit_actions by action name ('controller#action' string)
|
|
3
15
|
class MeritAction
|
|
4
16
|
attr_accessible :user_id, :action_method, :action_value, :had_errors,
|
|
5
17
|
:target_model, :target_id, :processed, :log
|
|
6
18
|
|
|
19
|
+
def self.check_unprocessed_rules
|
|
20
|
+
where(:processed => false).map &:check_rules
|
|
21
|
+
end
|
|
22
|
+
|
|
7
23
|
# Check rules defined for a merit_action
|
|
8
24
|
def check_rules
|
|
9
25
|
unless had_errors
|
|
@@ -13,24 +29,38 @@ class MeritAction
|
|
|
13
29
|
processed!
|
|
14
30
|
end
|
|
15
31
|
|
|
32
|
+
def target(to)
|
|
33
|
+
@target ||= (to == :action_user) ? action_user : other_target(to)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def target_object(model_name = nil)
|
|
37
|
+
# Grab custom model_name from Rule, or target_model from MeritAction triggered
|
|
38
|
+
klass = model_name || target_model
|
|
39
|
+
klass.singularize.camelize.constantize.find_by_id(target_id)
|
|
40
|
+
rescue => e
|
|
41
|
+
Rails.logger.warn "[merit] no target_object found: #{e}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def log_activity(str)
|
|
45
|
+
self.update_attribute :log, "#{self.log}#{str}|"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
16
50
|
def check_badge_rules
|
|
17
|
-
|
|
18
|
-
|
|
51
|
+
rules = AppBadgeRules[action_str] || []
|
|
52
|
+
rules.each { |rule| rule.apply_badges(self) }
|
|
19
53
|
end
|
|
20
54
|
|
|
21
55
|
def check_point_rules
|
|
22
|
-
|
|
23
|
-
|
|
56
|
+
rules = AppPointRules[action_str] || []
|
|
57
|
+
rules.each { |rule| rule.apply_points(self) }
|
|
24
58
|
end
|
|
25
59
|
|
|
26
60
|
def action_str
|
|
27
61
|
"#{target_model}\##{action_method}"
|
|
28
62
|
end
|
|
29
63
|
|
|
30
|
-
def target(to)
|
|
31
|
-
@target ||= (to == :action_user) ? action_user : other_target(to)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
64
|
def action_user
|
|
35
65
|
begin
|
|
36
66
|
Merit.user_model.find(user_id)
|
|
@@ -49,20 +79,6 @@ class MeritAction
|
|
|
49
79
|
end
|
|
50
80
|
end
|
|
51
81
|
|
|
52
|
-
# Action's target object
|
|
53
|
-
def target_object(model_name = nil)
|
|
54
|
-
# Grab custom model_name from Rule, or target_model from MeritAction triggered
|
|
55
|
-
klass = model_name || target_model
|
|
56
|
-
klass.singularize.camelize.constantize.find_by_id(target_id)
|
|
57
|
-
rescue => e
|
|
58
|
-
Rails.logger.warn "[merit] no target_object found: #{e}"
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def log!(str)
|
|
62
|
-
self.log = "#{self.log}#{str}|"
|
|
63
|
-
self.save
|
|
64
|
-
end
|
|
65
|
-
|
|
66
82
|
# Mark merit_action as processed
|
|
67
83
|
def processed!
|
|
68
84
|
self.processed = true
|
|
@@ -4,7 +4,7 @@ class CreateMeritActions < ActiveRecord::Migration
|
|
|
4
4
|
t.integer :user_id # source
|
|
5
5
|
t.string :action_method
|
|
6
6
|
t.integer :action_value
|
|
7
|
-
t.boolean :had_errors
|
|
7
|
+
t.boolean :had_errors, :default => false
|
|
8
8
|
t.string :target_model
|
|
9
9
|
t.integer :target_id
|
|
10
10
|
t.boolean :processed, :default => false
|
data/lib/merit.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'merit/rule'
|
|
2
|
-
require 'merit/
|
|
3
|
-
require 'merit/
|
|
4
|
-
require 'merit/
|
|
2
|
+
require 'merit/rules_badge_methods'
|
|
3
|
+
require 'merit/rules_points_methods'
|
|
4
|
+
require 'merit/rules_rank_methods'
|
|
5
5
|
require 'merit/controller_extensions'
|
|
6
6
|
require 'merit/model_additions'
|
|
7
7
|
|
|
@@ -48,6 +48,10 @@ module Merit
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
ActiveSupport.on_load(:action_controller) do
|
|
51
|
+
# Load application defined rules
|
|
52
|
+
::Merit::AppBadgeRules = BadgeRules.new.defined_rules
|
|
53
|
+
::Merit::AppPointRules = PointRules.new.defined_rules
|
|
54
|
+
|
|
51
55
|
include Merit::ControllerExtensions
|
|
52
56
|
end
|
|
53
57
|
end
|
|
@@ -1,31 +1,38 @@
|
|
|
1
1
|
module Merit
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
# 'controller_name#action_name'
|
|
2
|
+
# Sets up an app-wide after_filter, and inserts merit_action entries if
|
|
3
|
+
# there are defined rules (for badges or points) for current
|
|
4
|
+
# 'controller_name#action_name'
|
|
5
5
|
module ControllerExtensions
|
|
6
6
|
def self.included(base)
|
|
7
7
|
base.after_filter do |controller|
|
|
8
|
-
|
|
9
|
-
badge_rules = BadgeRules.new
|
|
10
|
-
point_rules = PointRules.new
|
|
11
|
-
if badge_rules.defined_rules[action].present? || point_rules.defined_rules[action].present?
|
|
12
|
-
merit_action_id = MeritAction.create(
|
|
13
|
-
:user_id => send(Merit.current_user_method).try(:id),
|
|
14
|
-
:action_method => action_name,
|
|
15
|
-
:action_value => params[:value],
|
|
16
|
-
:had_errors => target_object.try(:errors).try(:present?) || false,
|
|
17
|
-
:target_model => controller_name,
|
|
18
|
-
:target_id => target_id
|
|
19
|
-
).id
|
|
8
|
+
return unless rules_defined?
|
|
20
9
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
MeritAction.create(
|
|
11
|
+
:user_id => send(Merit.current_user_method).try(:id),
|
|
12
|
+
:action_method => action_name,
|
|
13
|
+
:action_value => params[:value],
|
|
14
|
+
:had_errors => had_errors?,
|
|
15
|
+
:target_model => controller_name,
|
|
16
|
+
:target_id => target_id
|
|
17
|
+
).id
|
|
18
|
+
|
|
19
|
+
if Merit.checks_on_each_request
|
|
20
|
+
MeritAction.check_unprocessed_rules
|
|
25
21
|
end
|
|
26
22
|
end
|
|
27
23
|
end
|
|
28
24
|
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def rules_defined?
|
|
28
|
+
action = "#{controller_name}\##{action_name}"
|
|
29
|
+
AppBadgeRules[action].present? || AppPointRules[action].present?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def had_errors?
|
|
33
|
+
target_object.try(:errors).try(:present?) || false
|
|
34
|
+
end
|
|
35
|
+
|
|
29
36
|
def target_object
|
|
30
37
|
target_obj = instance_variable_get(:"@#{controller_name.singularize}")
|
|
31
38
|
if target_obj.nil?
|
|
@@ -36,7 +43,7 @@ module Merit
|
|
|
36
43
|
|
|
37
44
|
def target_id
|
|
38
45
|
target_id = params[:id] || target_object.try(:id)
|
|
39
|
-
# using friendly_id if id nil or string
|
|
46
|
+
# using friendly_id if id is nil or string but an object was found
|
|
40
47
|
if target_object.present? && (target_id.nil? || !(target_id =~ /^[0-9]+$/))
|
|
41
48
|
target_id = target_object.id
|
|
42
49
|
end
|
|
@@ -3,8 +3,9 @@ module Merit
|
|
|
3
3
|
|
|
4
4
|
module ClassMethods
|
|
5
5
|
def has_merit(options = {})
|
|
6
|
-
#
|
|
7
|
-
#
|
|
6
|
+
# MeritableModel#sash_id is more stable than Sash#meritable_model_id
|
|
7
|
+
# That's why MeritableModel belongs_to Sash. Can't use
|
|
8
|
+
# :dependent => destroy as it may raise FK constraint exceptions. See:
|
|
8
9
|
# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1079-belongs_to-dependent-destroy-should-destroy-self-before-assocation
|
|
9
10
|
belongs_to :sash
|
|
10
11
|
|
|
@@ -22,31 +23,17 @@ module Merit
|
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
# Add instance methods to meritable models
|
|
26
|
-
# Using define_method on meritable classes to not pollute every model
|
|
27
|
-
|
|
28
26
|
# Delegate relationship methods from meritable models to their sash
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
define_method(:add_points) do |num_points, log = 'Manually through `add_points`', category = 'default'|
|
|
37
|
-
_sash = sash || create_sash_and_scores
|
|
38
|
-
_sash.add_points num_points, log, category
|
|
39
|
-
end
|
|
40
|
-
define_method(:substract_points) do |num_points, log = 'Manually through `substract_points`', category = 'default'|
|
|
41
|
-
_sash = sash || create_sash_and_scores
|
|
42
|
-
_sash.substract_points num_points, log, category
|
|
27
|
+
# _sash initializes a sash if doesn't have one yet.
|
|
28
|
+
# From Rails 3.2 we can override association methods to do so
|
|
29
|
+
# transparently, but merit supports Rails ~> 3.0.0. See:
|
|
30
|
+
# http://blog.hasmanythrough.com/2012/1/20/modularized-association-methods-in-rails-3-2
|
|
31
|
+
%w(badge_ids badges points add_points substract_points).each do |method|
|
|
32
|
+
delegate method, to: :_sash
|
|
43
33
|
end
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
define_method(:create_sash_and_scores) do
|
|
47
|
-
if self.sash.blank?
|
|
34
|
+
define_method(:_sash) do
|
|
35
|
+
if sash.nil?
|
|
48
36
|
self.sash = Sash.create
|
|
49
|
-
self.sash.scores << Merit::Score.create
|
|
50
37
|
self.save(:validate => false)
|
|
51
38
|
end
|
|
52
39
|
self.sash
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
# Sash is a container for reputation data for meritable models. It's an
|
|
2
|
+
# indirection between meritable models and badges and scores (one to one
|
|
3
|
+
# relationship).
|
|
4
|
+
#
|
|
5
|
+
# It's existence make join models like badges_users and scores_users
|
|
6
|
+
# unnecessary. It should be transparent at the application.
|
|
1
7
|
class Sash < ActiveRecord::Base
|
|
2
8
|
has_many :badges_sashes, :dependent => :destroy
|
|
3
9
|
has_many :scores, :dependent => :destroy, :class_name => 'Merit::Score'
|
|
4
10
|
|
|
11
|
+
after_create :create_scores
|
|
12
|
+
|
|
5
13
|
def badges
|
|
6
14
|
badge_ids.collect { |b_id| Badge.find(b_id) }
|
|
7
15
|
end
|
|
@@ -33,4 +41,10 @@ class Sash < ActiveRecord::Base
|
|
|
33
41
|
def substract_points(num_points, log = 'Manually granted through `add_points`', category = 'default')
|
|
34
42
|
add_points -num_points, log, category
|
|
35
43
|
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def create_scores
|
|
48
|
+
self.scores << Merit::Score.create
|
|
49
|
+
end
|
|
36
50
|
end
|
data/lib/merit/rule.rb
CHANGED
|
@@ -28,25 +28,25 @@ module Merit
|
|
|
28
28
|
|
|
29
29
|
# Grant badge if rule applies. If it doesn't, and the badge is temporary,
|
|
30
30
|
# then remove it.
|
|
31
|
-
def
|
|
31
|
+
def apply_badges(action)
|
|
32
32
|
unless (sash = sash_to_badge(action))
|
|
33
|
-
Rails.logger.warn "[merit] no sash found on Rule#
|
|
33
|
+
Rails.logger.warn "[merit] no sash found on Rule#apply_badges for action #{action.inspect}"
|
|
34
34
|
return
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
if applies? action.target_object(model_name)
|
|
38
38
|
if badge.grant_to(sash, :allow_multiple => self.multiple)
|
|
39
39
|
to_action_user = (to.to_sym == :action_user ? '_to_action_user' : '')
|
|
40
|
-
action.
|
|
40
|
+
action.log_activity "badge_granted#{to_action_user}:#{badge.id}"
|
|
41
41
|
end
|
|
42
42
|
elsif temporary?
|
|
43
43
|
if badge.delete_from(sash)
|
|
44
|
-
action.
|
|
44
|
+
action.log_activity "badge_removed:#{badge.id}"
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def
|
|
49
|
+
def apply_points(action)
|
|
50
50
|
unless (sash = sash_to_badge(action))
|
|
51
51
|
Rails.logger.warn "[merit] no sash found on Rule#grant_points"
|
|
52
52
|
return
|
|
@@ -54,7 +54,7 @@ module Merit
|
|
|
54
54
|
|
|
55
55
|
if applies? action.target_object(model_name)
|
|
56
56
|
sash.add_points self.score, action.inspect[0..240]
|
|
57
|
-
action.
|
|
57
|
+
action.log_activity "points_granted:#{self.score}"
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
@@ -68,21 +68,12 @@ module Merit
|
|
|
68
68
|
else
|
|
69
69
|
target = action.target(to)
|
|
70
70
|
end
|
|
71
|
-
if target
|
|
72
|
-
target.sash || target.create_sash_and_scores
|
|
73
|
-
end
|
|
71
|
+
target._sash if target
|
|
74
72
|
end
|
|
75
73
|
|
|
76
74
|
# Get rule's related Badge.
|
|
77
75
|
def badge
|
|
78
|
-
|
|
79
|
-
badges = Badge.by_name(badge_name)
|
|
80
|
-
badges = badges.by_level(level) unless level.nil?
|
|
81
|
-
if !(@badge = badges.first)
|
|
82
|
-
raise BadgeNotFound, "No badge '#{badge_name}'#{level.nil? ? '' : " with level #level"} found. Define it in 'config/initializers/merit.rb'."
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
@badge
|
|
76
|
+
@badge ||= Badge.find_by_name_and_level(badge_name, level)
|
|
86
77
|
end
|
|
87
78
|
end
|
|
88
79
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Merit
|
|
2
|
+
module BadgeRulesMethods
|
|
3
|
+
# Define rule for granting badges
|
|
4
|
+
def grant_on(action, *args, &block)
|
|
5
|
+
options = args.extract_options!
|
|
6
|
+
|
|
7
|
+
actions = Array.wrap(action)
|
|
8
|
+
|
|
9
|
+
rule = Rule.new
|
|
10
|
+
rule.badge_name = options[:badge]
|
|
11
|
+
rule.level = options[:level]
|
|
12
|
+
rule.to = options[:to] || :action_user
|
|
13
|
+
rule.multiple = options[:multiple] || false
|
|
14
|
+
rule.temporary = options[:temporary] || false
|
|
15
|
+
rule.model_name = options[:model_name] || actions[0].split('#')[0]
|
|
16
|
+
rule.block = block
|
|
17
|
+
|
|
18
|
+
actions.each do |action|
|
|
19
|
+
defined_rules[action] ||= []
|
|
20
|
+
defined_rules[action] << rule
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Currently defined rules
|
|
25
|
+
def defined_rules
|
|
26
|
+
@defined_rules ||= {}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
File without changes
|
|
@@ -22,7 +22,8 @@ module Merit
|
|
|
22
22
|
defined_rules[options[:to]].merge!({ options[:level] => rule })
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
#
|
|
25
|
+
# Not part of merit after_filter. To be called asynchronously:
|
|
26
|
+
# Merit::RankRules.new.check_rank_rules
|
|
26
27
|
def check_rank_rules
|
|
27
28
|
defined_rules.each do |scoped_model, level_and_rules|
|
|
28
29
|
level_and_rules = level_and_rules.sort
|
data/merit.gemspec
CHANGED
|
@@ -4,7 +4,7 @@ Gem::Specification.new do |s|
|
|
|
4
4
|
s.description = "Manage badges, points and rankings (reputation) of resources in a Rails application."
|
|
5
5
|
s.homepage = "http://github.com/tute/merit"
|
|
6
6
|
s.files = `git ls-files`.split("\n").reject{|f| f =~ /^\./ }
|
|
7
|
-
s.version = '1.1.
|
|
7
|
+
s.version = '1.1.1'
|
|
8
8
|
s.authors = ["Tute Costa"]
|
|
9
9
|
s.email = 'tutecosta@gmail.com'
|
|
10
10
|
s.add_dependency 'ambry', '~> 0.3.0'
|
data/test/merit_unit_test.rb
CHANGED
|
@@ -45,12 +45,6 @@ class MeritUnitTest < ActiveSupport::TestCase
|
|
|
45
45
|
assert badge_sash.notified_user
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
# TODO: Test and refactor:
|
|
49
|
-
# Rule: grant_or_delete_badge(action), sash_to_badge
|
|
50
|
-
# Badge: delete_from
|
|
51
|
-
# MeritAction: target(to), action_user, other_target(to), target_object(model_name = nil)
|
|
52
|
-
|
|
53
|
-
|
|
54
48
|
test "Badge#grant_to allow_multiple option" do
|
|
55
49
|
badge = Badge.create(:id => 99, :name => 'test-badge')
|
|
56
50
|
sash = Sash.create(:id => 99)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: merit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.1
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-11-
|
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: ambry
|
|
@@ -180,9 +180,9 @@ files:
|
|
|
180
180
|
- lib/merit/models/mongoid/merit_action.rb
|
|
181
181
|
- lib/merit/models/mongoid/sash.rb
|
|
182
182
|
- lib/merit/rule.rb
|
|
183
|
-
- lib/merit/
|
|
184
|
-
- lib/merit/
|
|
185
|
-
- lib/merit/
|
|
183
|
+
- lib/merit/rules_badge_methods.rb
|
|
184
|
+
- lib/merit/rules_points_methods.rb
|
|
185
|
+
- lib/merit/rules_rank_methods.rb
|
|
186
186
|
- merit.gemspec
|
|
187
187
|
- test/dummy-mongoid/Rakefile
|
|
188
188
|
- test/dummy-mongoid/app/controllers/application_controller.rb
|
data/lib/merit/rules_badge.rb
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
module Merit
|
|
2
|
-
# La configuración para especificar cuándo aplicar cada badge va en
|
|
3
|
-
# app/models/merit/badge_rules.rb, con la siguiente sintaxis:
|
|
4
|
-
#
|
|
5
|
-
# grant_on 'users#create', :badge => 'just', :level => 'registered' do
|
|
6
|
-
# # Nothing, or code block which evaluates to boolean
|
|
7
|
-
# end
|
|
8
|
-
#
|
|
9
|
-
# También se puede asignar medallas desde métodos en controladores:
|
|
10
|
-
#
|
|
11
|
-
# Badge.find(3).grant_to(current_user)
|
|
12
|
-
#
|
|
13
|
-
# Merit crea una tabla Badges similar a:
|
|
14
|
-
# ___________________________________________________
|
|
15
|
-
# id | name | level | image
|
|
16
|
-
# 1 | creador | inspirado | creador-inspirado.png
|
|
17
|
-
# 2 | creador | blogger | creador-blogger.png
|
|
18
|
-
# 2 | creador | best-seller | creador-bestseller.png
|
|
19
|
-
# ___________________________________________________
|
|
20
|
-
#
|
|
21
|
-
# Y llena una tabla de acciones, del estilo de:
|
|
22
|
-
# ______________________________________________________________
|
|
23
|
-
# source (user_id) | action (method, value) | target (model, id) | processed
|
|
24
|
-
# 1 | comment nil | List 8 | true
|
|
25
|
-
# 1 | vote 3 | List 12 | true
|
|
26
|
-
# 3 | follow nil | User 1 | false
|
|
27
|
-
# X | create nil | User #{generated_id} | false
|
|
28
|
-
# ______________________________________________________________
|
|
29
|
-
#
|
|
30
|
-
# Luego chequea las condiciones sincronizadamente, o mediante un proceso en
|
|
31
|
-
# background, por ejemplo cada 5 minutos (Merit::BadgeRules#check_new_actions).
|
|
32
|
-
module BadgeRulesMethods
|
|
33
|
-
# Define rule for granting badges
|
|
34
|
-
def grant_on(action, *args, &block)
|
|
35
|
-
options = args.extract_options!
|
|
36
|
-
|
|
37
|
-
actions = action.kind_of?(String) ? [action] : action
|
|
38
|
-
|
|
39
|
-
rule = Rule.new
|
|
40
|
-
rule.badge_name = options[:badge]
|
|
41
|
-
rule.level = options[:level]
|
|
42
|
-
rule.to = options[:to] || :action_user
|
|
43
|
-
rule.multiple = options[:multiple] || false
|
|
44
|
-
rule.temporary = options[:temporary] || false
|
|
45
|
-
rule.model_name = options[:model_name] || actions[0].split('#')[0]
|
|
46
|
-
rule.block = block
|
|
47
|
-
|
|
48
|
-
actions.each do |action|
|
|
49
|
-
defined_rules[action] ||= []
|
|
50
|
-
defined_rules[action] << rule
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Check non processed actions and grant badges if applies
|
|
55
|
-
def check_new_actions
|
|
56
|
-
MeritAction.where(:processed => false).map &:check_rules
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Currently defined rules
|
|
60
|
-
def defined_rules
|
|
61
|
-
@defined_rules ||= {}
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|