merit 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- merit (1.1.1)
4
+ merit (1.1.2)
5
5
  ambry (~> 0.3.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -53,16 +53,16 @@ end
53
53
 
54
54
  ## Grant manually
55
55
 
56
- You may also grant badges "by hand" (optionally multiple times):
56
+ You may also grant badges "by hand":
57
57
 
58
58
  ```ruby
59
- Badge.find(3).grant_to(current_user, :allow_multiple => true)
59
+ current_user.add_badge(badge.id)
60
60
  ```
61
61
 
62
- Similarly you can take back badges that have been granted:
62
+ Similarly you can remove badges that have been granted:
63
63
 
64
64
  ```ruby
65
- Badge.find(3).delete_from(current_user)
65
+ current_user.rm_badge(badge.id)
66
66
  ```
67
67
 
68
68
  ---
@@ -144,11 +144,7 @@ set_rank :level => 3, :to => Commiter.active do |commiter|
144
144
  end
145
145
  ```
146
146
 
147
- ---
148
147
 
149
148
  # To-do list
150
149
 
151
- * target_object should be configurable (now it's singularized controller name)
152
- * Should namespace app/models into Merit module.
153
- * :value parameter (for star voting for example) should be configurable
154
- (depends on params[:value] on the controller).
150
+ * Should namespace Badge, BadgesSash and Sash into Merit module.
data/UPGRADING.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Upgrading
2
2
 
3
+ ## to 1.2.0 (unreleased)
4
+
5
+ * `Badge#grant_to(meritable_object)` no longer exists. Use
6
+ `meritable_object.add_badge(badge_id)` (may add badges more than once).
7
+ * `Badge#delete_from(meritable_object)` no longer exists. Use
8
+ `meritable_object.rm_badge(badge_id)`.
9
+
3
10
  ## to 1.1.0
4
11
 
5
12
  Code refactorings. Support for Ruby 1.8.7 has been dropped.
data/app/models/badge.rb CHANGED
@@ -31,40 +31,4 @@ class Badge
31
31
  end
32
32
  badge
33
33
  end
34
-
35
- # Grant badge to sash
36
- # Accepts :allow_multiple boolean option, defaults to false
37
- def grant_to(object_or_sash, *args)
38
- options = args.extract_options!
39
- options[:allow_multiple] ||= false
40
- sash = sash_from(object_or_sash)
41
-
42
- if !sash.badge_ids.include?(id) || options[:allow_multiple]
43
- sash.add_badge(id)
44
- true
45
- else
46
- false
47
- end
48
- end
49
-
50
- # Take out badge from sash
51
- def delete_from(object_or_sash)
52
- sash = sash_from(object_or_sash)
53
- if sash.badge_ids.include?(id)
54
- sash.rm_badge(id)
55
- true
56
- else
57
- false
58
- end
59
- end
60
-
61
- private
62
-
63
- def sash_from(object_or_sash)
64
- if object_or_sash.kind_of?(Sash)
65
- object_or_sash
66
- else
67
- object_or_sash._sash
68
- end
69
- end
70
34
  end
@@ -0,0 +1,98 @@
1
+ require "merit/models/#{Merit.orm}/merit/action"
2
+
3
+ # Merit::Action 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)
15
+ module Merit
16
+ class Action
17
+ attr_accessible :user_id, :action_method, :action_value, :had_errors,
18
+ :target_model, :target_id, :processed, :log
19
+
20
+ def self.check_unprocessed_rules
21
+ where(:processed => false).map &:check_all_rules
22
+ end
23
+
24
+ # Check rules defined for a merit_action
25
+ def check_all_rules
26
+ processed!
27
+ return if had_errors
28
+
29
+ badge_rules = ::Merit::AppBadgeRules[action_str] || []
30
+ point_rules = ::Merit::AppPointRules[action_str] || []
31
+ check_rules badge_rules, :badges
32
+ check_rules point_rules, :points
33
+ end
34
+
35
+ def log_activity(str)
36
+ self.update_attribute :log, "#{self.log}#{str}|"
37
+ end
38
+
39
+ def target_object(model_name = nil)
40
+ # Grab custom model_name from Rule, or target_model from Merit::Action triggered
41
+ klass = model_name || target_model
42
+ klass.singularize.camelize.constantize.find_by_id(target_id)
43
+ rescue => e
44
+ Rails.logger.warn "[merit] no target_obj found: #{e}"
45
+ end
46
+
47
+ private
48
+
49
+ def check_rules(rules_array, badges_or_points)
50
+ rules_array.each do |rule|
51
+ judge = Judge.new sash_to_badge(rule), rule, :action => self
52
+ judge.send :"apply_#{badges_or_points}"
53
+ end
54
+ end
55
+
56
+ # Subject to badge: source_user or target.user?
57
+ def sash_to_badge(rule)
58
+ if rule.to == :itself
59
+ target = target_object(rule.model_name)
60
+ else
61
+ target = target(rule.to)
62
+ end
63
+ target.try(:_sash)
64
+ end
65
+
66
+ def target(to)
67
+ (to == :action_user) ? action_user : other_target(to)
68
+ end
69
+
70
+ def action_str
71
+ "#{target_model}\##{action_method}"
72
+ end
73
+
74
+ def action_user
75
+ begin
76
+ Merit.user_model.find(user_id)
77
+ rescue ActiveRecord::RecordNotFound
78
+ Rails.logger.warn "[merit] no #{Merit.user_model} found with id #{user_id}"
79
+ return
80
+ end
81
+ end
82
+
83
+ def other_target(to)
84
+ begin
85
+ target_object.send(to)
86
+ rescue NoMethodError
87
+ Rails.logger.warn "[merit] NoMethodError on '#{target_object.inspect}.#{to}' (called from Merit::Action#other_target)"
88
+ return
89
+ end
90
+ end
91
+
92
+ # Mark merit_action as processed
93
+ def processed!
94
+ self.processed = true
95
+ self.save
96
+ end
97
+ end
98
+ end
@@ -1,3 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+ #
1
3
  # +grant_on+ accepts:
2
4
  # * Nothing (always grants)
3
5
  # * A block which evaluates to boolean (recieves the object as parameter)
@@ -1,3 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+ #
1
3
  # Points are a simple integer value which are given to "meritable" resources
2
4
  # according to rules in +app/models/merit/point_rules.rb+. They are given on
3
5
  # actions-triggered, either to the action user or to the method (or array of
@@ -1,3 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+ #
1
3
  # 5 stars is a common ranking use case. They are not given at specified
2
4
  # actions like badges, you should define a cron job to test if ranks are to be
3
5
  # granted.
data/lib/merit.rb CHANGED
@@ -4,6 +4,7 @@ require 'merit/rules_points_methods'
4
4
  require 'merit/rules_rank_methods'
5
5
  require 'merit/controller_extensions'
6
6
  require 'merit/model_additions'
7
+ require 'merit/judge'
7
8
 
8
9
  module Merit
9
10
  # Check rules on each request
@@ -7,7 +7,7 @@ module Merit
7
7
  base.after_filter do |controller|
8
8
  return unless rules_defined?
9
9
 
10
- MeritAction.create(
10
+ Merit::Action.create(
11
11
  :user_id => send(Merit.current_user_method).try(:id),
12
12
  :action_method => action_name,
13
13
  :action_value => params[:value],
@@ -17,7 +17,7 @@ module Merit
17
17
  ).id
18
18
 
19
19
  if Merit.checks_on_each_request
20
- MeritAction.check_unprocessed_rules
20
+ Merit::Action.check_unprocessed_rules
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,53 @@
1
+ module Merit
2
+ class Judge
3
+ def initialize(sash, rule, options = {})
4
+ @sash = sash
5
+ @rule = rule
6
+ # FIXME: Too much context:
7
+ # A Judge should apply reputation independently of the action
8
+ @action = options[:action]
9
+ end
10
+
11
+ # Grant badge if rule applies. If it doesn't, and the badge is temporary,
12
+ # then remove it.
13
+ def apply_badges
14
+ if rule_applies?
15
+ grant_badge if new_or_multiple?
16
+ else
17
+ remove_badge if @rule.temporary
18
+ end
19
+ end
20
+
21
+ def apply_points
22
+ return unless rule_applies?
23
+ @sash.add_points @rule.score, @action.inspect[0..240]
24
+ @action.log_activity "points_granted:#{@rule.score}"
25
+ end
26
+
27
+ private
28
+
29
+ def grant_badge
30
+ @sash.add_badge(badge.id)
31
+ to_action_user = (@rule.to.to_sym == :action_user ? '_to_action_user' : '')
32
+ @action.log_activity "badge_granted#{to_action_user}:#{badge.id}"
33
+ end
34
+
35
+ def remove_badge
36
+ @sash.rm_badge(badge.id)
37
+ @action.log_activity "badge_removed:#{badge.id}"
38
+ end
39
+
40
+ def new_or_multiple?
41
+ !@sash.badge_ids.include?(badge.id) || @rule.multiple
42
+ end
43
+
44
+ # FIXME: Too tightly coupled three objects
45
+ def rule_applies?
46
+ @rule.applies? @action.target_object(@rule.model_name)
47
+ end
48
+
49
+ def badge
50
+ @rule.badge
51
+ end
52
+ end
53
+ end
@@ -28,7 +28,7 @@ module Merit
28
28
  # From Rails 3.2 we can override association methods to do so
29
29
  # transparently, but merit supports Rails ~> 3.0.0. See:
30
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|
31
+ %w(badge_ids badges points add_badge rm_badge add_points substract_points).each do |method|
32
32
  delegate method, to: :_sash
33
33
  end
34
34
  define_method(:_sash) do
@@ -0,0 +1,5 @@
1
+ module Merit
2
+ class Action < ActiveRecord::Base
3
+ self.table_name = :merit_actions
4
+ end
5
+ end
@@ -28,6 +28,7 @@ class Sash < ActiveRecord::Base
28
28
  badges_sashes.find_by_badge_id(badge_id).try(:destroy)
29
29
  end
30
30
 
31
+
31
32
  def points(category = 'default')
32
33
  scores.where(:category => category).first.points
33
34
  end
@@ -38,6 +39,7 @@ class Sash < ActiveRecord::Base
38
39
  point.num_points = num_points
39
40
  self.scores.where(:category => category).first.score_points << point
40
41
  end
42
+
41
43
  def substract_points(num_points, log = 'Manually granted through `add_points`', category = 'default')
42
44
  add_points -num_points, log, category
43
45
  end
@@ -0,0 +1,15 @@
1
+ module Merit
2
+ class Action
3
+ include MongoMapper::Document
4
+
5
+ key :user_id, String
6
+ key :action_method, String
7
+ key :action_value, Integer
8
+ key :had_errors, Boolean
9
+ key :target_model, String
10
+ key :target_id, String
11
+ key :processed, Boolean, :default => false
12
+ key :log, String
13
+ timestamps!
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Merit
2
+ class Action
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+
6
+ belongs_to :user
7
+ field :action_method
8
+ field :action_value, :type => Integer
9
+ field :had_errors, :type => Boolean
10
+
11
+ belongs_to :target, :polymorphic => true
12
+ field :processed, :type => Boolean, :default => false
13
+ field :log
14
+ end
15
+ end
data/lib/merit/rule.rb CHANGED
@@ -15,62 +15,14 @@ module Merit
15
15
  if target_obj.present?
16
16
  block.call(target_obj)
17
17
  else
18
- # TODO RAISE ERROR
19
18
  Rails.logger.warn "[merit] no target_obj found on Rule#applies?"
20
19
  false
21
20
  end
22
- else # evaluates to boolean. block.arity returns 0 in Ruby 1.9.3 and -1 in Ruby 1.8.7
21
+ when 0
23
22
  block.call
24
23
  end
25
24
  end
26
25
 
27
- def temporary?; self.temporary; end
28
-
29
- # Grant badge if rule applies. If it doesn't, and the badge is temporary,
30
- # then remove it.
31
- def apply_badges(action)
32
- unless (sash = sash_to_badge(action))
33
- Rails.logger.warn "[merit] no sash found on Rule#apply_badges for action #{action.inspect}"
34
- return
35
- end
36
-
37
- if applies? action.target_object(model_name)
38
- if badge.grant_to(sash, :allow_multiple => self.multiple)
39
- to_action_user = (to.to_sym == :action_user ? '_to_action_user' : '')
40
- action.log_activity "badge_granted#{to_action_user}:#{badge.id}"
41
- end
42
- elsif temporary?
43
- if badge.delete_from(sash)
44
- action.log_activity "badge_removed:#{badge.id}"
45
- end
46
- end
47
- end
48
-
49
- def apply_points(action)
50
- unless (sash = sash_to_badge(action))
51
- Rails.logger.warn "[merit] no sash found on Rule#grant_points"
52
- return
53
- end
54
-
55
- if applies? action.target_object(model_name)
56
- sash.add_points self.score, action.inspect[0..240]
57
- action.log_activity "points_granted:#{self.score}"
58
- end
59
- end
60
-
61
- # Subject to badge: source_user or target.user?
62
- # Knows (law of demeter):
63
- # * Rule#model_name & Rule#to
64
- # * MeritAction#object & MeritAction#target_object
65
- def sash_to_badge(action)
66
- if to == :itself
67
- target = action.target_object(model_name)
68
- else
69
- target = action.target(to)
70
- end
71
- target._sash if target
72
- end
73
-
74
26
  # Get rule's related Badge.
75
27
  def badge
76
28
  @badge ||= Badge.find_by_name_and_level(badge_name, level)
@@ -6,7 +6,7 @@ module Merit
6
6
  # Define rules on certaing actions for giving points
7
7
  def score(points, *args, &block)
8
8
  options = args.extract_options!
9
- options[:to] ||= [:action_user]
9
+ options[:to] ||= :action_user
10
10
 
11
11
  actions = Array.wrap(options[:on])
12
12
 
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.1'
7
+ s.version = '1.1.2'
8
8
  s.authors = ["Tute Costa"]
9
9
  s.email = 'tutecosta@gmail.com'
10
10
  s.add_dependency 'ambry', '~> 0.3.0'
@@ -4,4 +4,8 @@ class Comment < ActiveRecord::Base
4
4
  attr_accessible :name, :comment, :user_id, :votes
5
5
 
6
6
  validates :name, :comment, :user_id, :presence => true
7
+
8
+ def friend
9
+ User.find_by_name('friend')
10
+ end
7
11
  end
@@ -33,6 +33,10 @@ module Merit
33
33
  grant_on 'comments#create', :badge => 'commenter', :level => 10 do |comment|
34
34
  comment.user.comments.count >= 10
35
35
  end
36
+ # Testing badge granting in more than one rule per action with different targets
37
+ grant_on 'comments#create', :badge => 'has_commenter_friend', :to => :friend do |comment|
38
+ comment.user.comments.count >= 10
39
+ end
36
40
 
37
41
  # If it has at least 10 votes, grant relevant-commenter badge
38
42
  grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do |comment|
@@ -12,12 +12,16 @@ badge_id = 0
12
12
  [{
13
13
  :id => (badge_id = badge_id+1),
14
14
  :name => 'commenter',
15
- :description => 'You\'ve participated good in our boards!',
15
+ :description => 'You\'ve participated good in our boards! (level 10)',
16
16
  :level => 10
17
17
  }, {
18
18
  :id => (badge_id = badge_id+1),
19
19
  :name => 'commenter',
20
20
  :description => 'You\'ve participated great in our boards!'
21
+ }, {
22
+ :id => (badge_id = badge_id+1),
23
+ :name => 'has_commenter_friend',
24
+ :description => 'Testing badge granting in more than one rule per action, with different targets'
21
25
  }, {
22
26
  :id => (badge_id = badge_id+1),
23
27
  :name => 'relevant-commenter',
@@ -1,6 +1,8 @@
1
1
  commenter = User.create(:name => 'the-commenter-guy')
2
2
  social = User.create(:name => 'social-skilled-man')
3
- bored = User.create(:name => 'bored-or-speechless')
3
+
4
+ User.create(:name => 'bored-or-speechless')
5
+ User.create(:name => 'friend')
4
6
 
5
7
  (1..9).each do |i|
6
8
  Comment.create(
@@ -10,6 +10,26 @@ class NavigationTest < ActiveSupport::IntegrationCase
10
10
  assert_equal [Badge.by_name('just-registered').first], user.badges.to_a
11
11
  end
12
12
 
13
+ test 'User#add_badge should add one badge, #rm_badge should delete one' do
14
+ user = User.create(:name => 'test-user')
15
+ assert_equal [], user.badges.to_a
16
+
17
+ badge = Badge.first
18
+ user.add_badge badge.id
19
+ user.add_badge badge.id
20
+ assert_equal [badge, badge], user.badges.to_a
21
+
22
+ user.rm_badge badge.id
23
+ assert_equal [badge], user.reload.badges.to_a
24
+ end
25
+
26
+ test 'Remove inexistent badge should do nothing' do
27
+ user = User.create(:name => 'test-user')
28
+ assert_equal [], user.badges.to_a
29
+ user.rm_badge 1
30
+ assert_equal [], user.badges.to_a
31
+ end
32
+
13
33
  test 'users#index should grant badge multiple times' do
14
34
  user = User.create(:name => 'test-user')
15
35
  visit '/users'
@@ -22,6 +42,9 @@ class NavigationTest < ActiveSupport::IntegrationCase
22
42
  test 'user workflow should grant some badges at some times' do
23
43
  # Commented 9 times, no badges yet
24
44
  user = User.create(:name => 'test-user')
45
+ # Create needed friend user object
46
+ friend = User.create(:name => 'friend')
47
+
25
48
  (1..9).each do |i|
26
49
  Comment.create(
27
50
  :name => "Title #{i}",
@@ -47,8 +70,8 @@ class NavigationTest < ActiveSupport::IntegrationCase
47
70
  fill_in 'User', :with => user.id
48
71
  click_button('Create Comment')
49
72
 
50
- user = User.where(:name => 'test-user').first
51
- assert_equal [Badge.by_name('commenter').by_level(10).first], user.badges.to_a
73
+ assert_equal [Badge.by_name('commenter').by_level(10).first], user.reload.badges.to_a
74
+ assert_equal [Badge.by_name('has_commenter_friend').first], friend.reload.badges.to_a
52
75
 
53
76
  # Vote (to 5) a user's comment, assert relevant-commenter badge granted
54
77
  relevant_comment = user.comments.where(:votes => 8).first
@@ -85,6 +108,7 @@ class NavigationTest < ActiveSupport::IntegrationCase
85
108
  end
86
109
 
87
110
  test 'user workflow should add up points at some times' do
111
+ User.delete_all
88
112
  user = User.create(:name => 'test-user')
89
113
  assert_equal 0, user.points, 'User should start with 0 points'
90
114
 
@@ -16,7 +16,7 @@ class MeritUnitTest < ActiveSupport::TestCase
16
16
  assert !rule.applies?, 'block which expects object should return false if no argument'
17
17
  end
18
18
 
19
- test "Rule#badge should get related badge or raise Merit exception" do
19
+ test "Rule#badge should get related badge or raise Merit::BadgeNotFound" do
20
20
  rule = Merit::Rule.new
21
21
  rule.badge_name = 'inexistent'
22
22
  assert_raise Merit::BadgeNotFound do
@@ -28,13 +28,16 @@ class MeritUnitTest < ActiveSupport::TestCase
28
28
  assert_equal Badge.find(98), rule.badge
29
29
  end
30
30
 
31
- test "Extending only certain ActiveRecord models" do
31
+ test "Extends only meritable ActiveRecord models" do
32
32
  class MeritableModel < ActiveRecord::Base
33
33
  def self.columns; @columns ||= []; end
34
34
  has_merit
35
35
  end
36
+ class OtherModels < ActiveRecord::Base
37
+ def self.columns; @columns ||= []; end
38
+ end
36
39
  assert MeritableModel.method_defined?(:points), 'Meritable model should respond to merit methods'
37
- assert !ActiveRecord::Base.method_defined?(:points), 'ActiveRecord::Base shouldn\'t respond to merit methods'
40
+ assert !OtherModels.method_defined?(:points), 'Other models shouldn\'t respond to merit methods'
38
41
  end
39
42
 
40
43
  # Do we need this non-documented attribute?
@@ -44,19 +47,4 @@ class MeritUnitTest < ActiveSupport::TestCase
44
47
  badge_sash.set_notified!
45
48
  assert badge_sash.notified_user
46
49
  end
47
-
48
- test "Badge#grant_to allow_multiple option" do
49
- badge = Badge.create(:id => 99, :name => 'test-badge')
50
- sash = Sash.create(:id => 99)
51
-
52
- assert_equal 0, sash.badge_ids.count
53
-
54
- assert badge.grant_to(sash)
55
- assert_equal 1, sash.badge_ids.count
56
- assert !badge.grant_to(sash)
57
- assert_equal 1, sash.badge_ids.count
58
-
59
- assert badge.grant_to(sash, :allow_multiple => true)
60
- assert_equal 2, sash.badge_ids.count
61
- end
62
50
  end
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.1
4
+ version: 1.1.2
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-28 00:00:00.000000000 Z
12
+ date: 2012-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ambry
@@ -154,7 +154,7 @@ files:
154
154
  - TESTING.txt
155
155
  - UPGRADING.md
156
156
  - app/models/badge.rb
157
- - app/models/merit_action.rb
157
+ - app/models/merit/action.rb
158
158
  - lib/generators/active_record/install_generator.rb
159
159
  - lib/generators/active_record/merit_generator.rb
160
160
  - lib/generators/active_record/templates/add_fields_to_model.rb
@@ -170,14 +170,15 @@ files:
170
170
  - lib/generators/merit/templates/merit_rank_rules.rb
171
171
  - lib/merit.rb
172
172
  - lib/merit/controller_extensions.rb
173
+ - lib/merit/judge.rb
173
174
  - lib/merit/model_additions.rb
174
175
  - lib/merit/models/active_record/badges_sash.rb
176
+ - lib/merit/models/active_record/merit/action.rb
175
177
  - lib/merit/models/active_record/merit/score.rb
176
- - lib/merit/models/active_record/merit_action.rb
177
178
  - lib/merit/models/active_record/sash.rb
178
- - lib/merit/models/mongo_mapper/merit_action.rb
179
+ - lib/merit/models/mongo_mapper/merit/action.rb
179
180
  - lib/merit/models/mongo_mapper/sash.rb
180
- - lib/merit/models/mongoid/merit_action.rb
181
+ - lib/merit/models/mongoid/merit/action.rb
181
182
  - lib/merit/models/mongoid/sash.rb
182
183
  - lib/merit/rule.rb
183
184
  - lib/merit/rules_badge_methods.rb
@@ -1,87 +0,0 @@
1
- require "merit/models/#{Merit.orm}/merit_action"
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)
15
- class MeritAction
16
- attr_accessible :user_id, :action_method, :action_value, :had_errors,
17
- :target_model, :target_id, :processed, :log
18
-
19
- def self.check_unprocessed_rules
20
- where(:processed => false).map &:check_rules
21
- end
22
-
23
- # Check rules defined for a merit_action
24
- def check_rules
25
- unless had_errors
26
- check_badge_rules
27
- check_point_rules
28
- end
29
- processed!
30
- end
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
-
50
- def check_badge_rules
51
- rules = AppBadgeRules[action_str] || []
52
- rules.each { |rule| rule.apply_badges(self) }
53
- end
54
-
55
- def check_point_rules
56
- rules = AppPointRules[action_str] || []
57
- rules.each { |rule| rule.apply_points(self) }
58
- end
59
-
60
- def action_str
61
- "#{target_model}\##{action_method}"
62
- end
63
-
64
- def action_user
65
- begin
66
- Merit.user_model.find(user_id)
67
- rescue ActiveRecord::RecordNotFound
68
- Rails.logger.warn "[merit] no #{Merit.user_model} found with id #{user_id}"
69
- return
70
- end
71
- end
72
-
73
- def other_target(to)
74
- begin
75
- target_object.send(to)
76
- rescue NoMethodError
77
- Rails.logger.warn "[merit] NoMethodError on '#{target_object.inspect}.#{to}' (called from MeritAction#other_target)"
78
- return
79
- end
80
- end
81
-
82
- # Mark merit_action as processed
83
- def processed!
84
- self.processed = true
85
- self.save
86
- end
87
- end
@@ -1,2 +0,0 @@
1
- class MeritAction < ActiveRecord::Base
2
- end
@@ -1,13 +0,0 @@
1
- class MeritAction
2
- include MongoMapper::Document
3
-
4
- key :user_id, String
5
- key :action_method, String
6
- key :action_value, Integer
7
- key :had_errors, Boolean
8
- key :target_model, String
9
- key :target_id, String
10
- key :processed, Boolean, :default => false
11
- key :log, String
12
- timestamps!
13
- end
@@ -1,13 +0,0 @@
1
- class MeritAction
2
- include Mongoid::Document
3
- include Mongoid::Timestamps
4
-
5
- belongs_to :user
6
- field :action_method
7
- field :action_value, :type => Integer
8
- field :had_errors, :type => Boolean
9
-
10
- belongs_to :target, :polymorphic => true
11
- field :processed, :type => Boolean, :default => false
12
- field :log
13
- end