merit 2.4.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +3 -35
  3. data/NEWS.md +31 -0
  4. data/README.md +15 -3
  5. data/RELEASING.md +16 -0
  6. data/Rakefile +13 -1
  7. data/app/models/merit/badge.rb +2 -19
  8. data/lib/merit.rb +13 -35
  9. data/lib/merit/{rules_badge_methods.rb → badge_rules_methods.rb} +0 -0
  10. data/lib/merit/base_target_finder.rb +1 -6
  11. data/lib/merit/{model_additions.rb → class_methods.rb} +2 -19
  12. data/lib/merit/controller_extensions.rb +13 -30
  13. data/lib/{generators → merit/generators}/active_record/install_generator.rb +12 -8
  14. data/lib/{generators → merit/generators}/active_record/merit_generator.rb +7 -3
  15. data/lib/{generators → merit/generators}/active_record/remove_generator.rb +9 -5
  16. data/lib/{generators/active_record/templates/add_merit_fields_to_model.rb → merit/generators/active_record/templates/add_merit_fields_to_model.erb} +1 -1
  17. data/lib/{generators/active_record/templates/create_badges_sashes.rb → merit/generators/active_record/templates/create_badges_sashes.erb} +1 -1
  18. data/lib/{generators/active_record/templates/create_merit_actions.rb → merit/generators/active_record/templates/create_merit_actions.erb} +2 -2
  19. data/lib/{generators/active_record/templates/create_merit_activity_logs.rb → merit/generators/active_record/templates/create_merit_activity_logs.erb} +1 -1
  20. data/lib/merit/generators/active_record/templates/create_sashes.erb +7 -0
  21. data/lib/{generators/active_record/templates/create_scores_and_points.rb → merit/generators/active_record/templates/create_scores_and_points.erb} +2 -2
  22. data/lib/{generators/active_record/templates/remove_merit_fields_from_model.rb → merit/generators/active_record/templates/remove_merit_fields_from_model.erb} +1 -1
  23. data/lib/{generators/active_record/templates/remove_merit_tables.rb → merit/generators/active_record/templates/remove_merit_tables.erb} +1 -1
  24. data/lib/merit/generators/install_generator.rb +18 -0
  25. data/lib/{generators/merit → merit/generators}/merit_generator.rb +3 -1
  26. data/lib/{generators/merit → merit/generators}/remove_generator.rb +3 -1
  27. data/lib/{generators/merit/templates/merit.rb → merit/generators/templates/merit.erb} +0 -3
  28. data/lib/{generators/merit/templates/merit_badge_rules.rb → merit/generators/templates/merit_badge_rules.erb} +0 -0
  29. data/lib/{generators/merit/templates/merit_point_rules.rb → merit/generators/templates/merit_point_rules.erb} +0 -0
  30. data/lib/{generators/merit/templates/merit_rank_rules.rb → merit/generators/templates/merit_rank_rules.erb} +0 -0
  31. data/{app/models/merit/action.rb → lib/merit/models/action_concern.rb} +12 -10
  32. data/lib/merit/models/active_record/action.rb +11 -0
  33. data/lib/merit/models/active_record/{merit/activity_log.rb → activity_log.rb} +4 -6
  34. data/lib/merit/models/active_record/{merit/badges_sash.rb → badges_sash.rb} +4 -4
  35. data/lib/merit/models/active_record/{merit/sash.rb → sash.rb} +5 -2
  36. data/lib/merit/models/active_record/{merit/score.rb → score.rb} +4 -1
  37. data/lib/merit/models/badges_sash_concern.rb +13 -0
  38. data/lib/merit/models/base/badges_sash.rb +1 -1
  39. data/lib/merit/models/base/sash.rb +1 -1
  40. data/lib/merit/models/sash_concern.rb +53 -0
  41. data/lib/merit/{rules_points_methods.rb → point_rules_methods.rb} +0 -0
  42. data/lib/merit/{rules_rank_methods.rb → rank_rules_methods.rb} +3 -18
  43. data/merit.gemspec +7 -5
  44. data/test/dummy/app/controllers/comments_controller.rb +1 -1
  45. data/test/dummy/app/controllers/registrations_controller.rb +1 -1
  46. data/test/dummy/app/models/address.rb +1 -12
  47. data/test/dummy/app/models/comment.rb +3 -25
  48. data/test/dummy/app/models/user.rb +1 -18
  49. data/test/dummy/config/application.rb +8 -10
  50. data/test/dummy/config/application_api_only.rb +28 -0
  51. data/test/dummy/config/environment_api_only.rb +7 -0
  52. data/test/dummy/config/environments/test.rb +1 -1
  53. data/test/dummy/config/initializers/new_framework_defaults.rb +3 -0
  54. data/test/dummy/db/migrate/20110421191249_create_users.rb +2 -2
  55. data/test/dummy/db/migrate/20110421191250_create_comments.rb +2 -2
  56. data/test/dummy/db/migrate/20120318022220_add_fields_to_users.rb +1 -1
  57. data/test/dummy/db/migrate/20130321082817_add_fields_to_comments.rb +1 -1
  58. data/test/dummy/db/migrate/20130329224406_create_merit_actions.rb +2 -2
  59. data/test/dummy/db/migrate/20130329224407_create_merit_activity_logs.rb +1 -1
  60. data/test/dummy/db/migrate/20130329224408_create_sashes.rb +2 -2
  61. data/test/dummy/db/migrate/20130329224409_create_badges_sashes.rb +1 -1
  62. data/test/dummy/db/migrate/20130329224410_create_scores_and_points.rb +1 -1
  63. data/test/dummy/db/migrate/20140211144001_create_addresses.rb +1 -1
  64. data/test/dummy/db/migrate/20140819133931_add_target_data_to_merit_actions.rb +1 -1
  65. data/test/dummy/db/schema.rb +55 -59
  66. data/test/integration/navigation_test.rb +2 -2
  67. data/test/test_helper.rb +11 -12
  68. data/test/unit/base_target_finder_test.rb +7 -26
  69. data/test/unit/merit_unit_test.rb +13 -17
  70. data/test/unit/rule_unit_test.rb +15 -8
  71. data/test/unit/rules_matcher_test.rb +9 -6
  72. data/test/unit/sash_finder_test.rb +5 -5
  73. data/test/unit/score_test.rb +1 -1
  74. data/test/unit/target_finder_test.rb +13 -13
  75. metadata +61 -70
  76. data/UPGRADING.md +0 -256
  77. data/lib/generators/active_record/templates/add_target_data_to_merit_actions.rb +0 -5
  78. data/lib/generators/active_record/templates/create_sashes.rb +0 -7
  79. data/lib/generators/active_record/upgrade_generator.rb +0 -36
  80. data/lib/generators/merit/install_generator.rb +0 -16
  81. data/lib/generators/merit/upgrade_generator.rb +0 -7
  82. data/lib/merit/models/active_record/merit/action.rb +0 -12
  83. data/lib/merit/models/mongoid/merit/action.rb +0 -18
  84. data/lib/merit/models/mongoid/merit/activity_log.rb +0 -11
  85. data/lib/merit/models/mongoid/merit/badges_sash.rb +0 -22
  86. data/lib/merit/models/mongoid/merit/sash.rb +0 -30
  87. data/lib/merit/models/mongoid/merit/score.rb +0 -45
  88. data/test/dummy/db/migrate/20140906225844_create_players.rb +0 -8
  89. data/test/dummy/public/javascripts/application.js +0 -2
  90. data/test/dummy/public/javascripts/controls.js +0 -965
  91. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  92. data/test/dummy/public/javascripts/effects.js +0 -1123
  93. data/test/dummy/public/javascripts/prototype.js +0 -6001
  94. data/test/dummy/public/javascripts/rails.js +0 -191
  95. data/test/orm/active_record.rb +0 -2
  96. data/test/orm/mongoid.rb +0 -6
  97. data/test/orm_models/active_record.rb +0 -11
  98. data/test/orm_models/mongoid.rb +0 -15
@@ -1,256 +0,0 @@
1
- # Main Changes / Upgrading Notes
2
-
3
- ## 2.1.0
4
-
5
- Adds serialisation of destroyed target models so that reputation can be awarded
6
- when the item is already deleted from the DB. For this to work you need a new
7
- column, to add it you can run:
8
-
9
- ```
10
- rails generate merit:upgrade
11
- rake db:migrate
12
- ```
13
-
14
- This is a backwards compatible addition, so if you don't add the column but
15
- upgrade, your application should continue to work well, without the new feature.
16
-
17
- ## 2.0.0
18
-
19
- * Removes deprecated methods: `Merit::Badge.last_granted` and
20
- `Merit::Score.top_scored`.
21
- * Removes `add_points` `log` parameter.
22
- * Adds points category option.
23
-
24
- ## 1.9.0
25
-
26
- * Deprecates `Merit::Badge.last_granted` and `Merit::Score.top_scored`.
27
- Code can be readded to client applications following instructions in:
28
- https://github.com/tute/merit/wiki/How-to-show-a-points-leaderboard
29
- https://github.com/tute/merit/wiki/How-to-show-last-granted-badges
30
- * Deprecates `add_points` `log` parameter.
31
-
32
- ## 1.8.0
33
-
34
- * Completes implementation of observer patter for getting reputation grant
35
- notifications to the client app. See: https://github.com/tute/merit#getting-
36
- notifications.
37
- * Work on mongoid adapter (not yet ready), and other internals polishing.
38
-
39
- ## 1.7.0
40
-
41
- * Adds support for dynamic scoring
42
- * `substract_points` is deprecated in favor of `subtract_points`. Careless
43
- computers didn't mind my misspellings. ;-)
44
- * JRuby and Rubinius compatibility
45
-
46
- ## 1.6.0
47
-
48
- * Rails 4 ready.
49
- * Adds ability to wildcard controllers like:
50
- ```ruby
51
- grant_on '.*search#index', badge: 'searcher', multiple: true
52
- ```
53
- * Allows custom fields to be defined on badges [97c998f]. Example:
54
- Merit::Badge.create!({
55
- id: 1,
56
- name: 'best-unicorn',
57
- custom_fields: { category: 'fantasy' }
58
- })
59
-
60
- ## 1.5.0
61
-
62
- * Adds `Merit::ActivityLog` join model between `Merit::Action` and
63
- `Merit::BadgesSash` and `Merit::Score::Point` for logging purposes. Every
64
- time a badge is granted or removed, or points are changed, a new
65
- `ActivityLog` object gets created.
66
- * Namespaces `Badge`, `Sash` and `BadgesSash` into `Merit` module. If your app
67
- uses any of those class names, you should add a `Merit::` prefix.
68
- * Removes undocumented `log:string` column from `merit_actions`.
69
-
70
- Run the following migration to upgrade from 1.4.0:
71
-
72
- ```ruby
73
- class UpgradeMeritTo150 < ActiveRecord::Migration
74
- def self.up
75
- remove_column :merit_actions, :log
76
- create_table "merit_activity_logs", :force => true do |t|
77
- t.integer "action_id"
78
- t.string "related_change_type"
79
- t.integer "related_change_id"
80
- t.string "description"
81
- t.datetime "created_at"
82
- end
83
- end
84
- end
85
- ```
86
-
87
- ## 1.4.0
88
-
89
- * Removed `BadgesSash#set_notified!` undocumented method from code base.
90
- * `:to` option for points and badges granting may now return an array of
91
- objects. For instance:
92
-
93
- ```ruby
94
- # All user's comments earn points
95
- score 2, to: :user_comments, on: 'comments#vote'
96
- ```
97
-
98
- ## to 1.3.0
99
-
100
- Adds two methods meant to display a leaderboard.
101
-
102
- * `Badge.last_granted(options = {})`. Accepts options:
103
- * `:since_date` (`1.month.ago` by default)
104
- * `:limit` (10 by default).
105
-
106
- It lists last 10 badge grants in the last month, unless you change query
107
- parameters.
108
-
109
- * `Merit::Score.top_scored(options = {})`. Accepts options:
110
- * `:table_name` (`users` by default)
111
- * `:since_date` (`1.month.ago` by default)
112
- * `:limit` (10 by default).
113
-
114
- It lists top 10 scored objects in the last month, unless you change query
115
- parameters.
116
-
117
- ## to 1.2.0
118
-
119
- * `Badge#grant_to(meritable_object)` no longer exists. Use
120
- `meritable_object.add_badge(badge_id)` (may add badges more than once).
121
- * `Badge#delete_from(meritable_object)` no longer exists. Use
122
- `meritable_object.rm_badge(badge_id)`.
123
-
124
- ## to 1.1.0
125
-
126
- Code refactorings. Support for Ruby 1.8.7 has been dropped.
127
-
128
- ## to 1.0.1
129
-
130
- Adds `Merit::Point#created_at` (`merit_score_points` table) attribute.
131
- May already be added if upgrading from merit < 1).
132
-
133
- ## to 1.0.0
134
-
135
- Points granting history is now logged.
136
-
137
- * Attribute `points` and method `points=` don't exist anymore (method `points`
138
- still works for querying number of points for a resource).
139
- * There are new methods `add_points(num_points, log_message)` and
140
- `remove_points(num_points, log_message)` in meritable resources to manually
141
- change their amount of points, keeping a history log.
142
-
143
- Run the following migration to have the new DB tables:
144
-
145
- class UpgradeMerit < ActiveRecord::Migration
146
- def self.up
147
- create_table :merit_scores do |t|
148
- t.references :sash
149
- t.string :category, :default => 'default'
150
- end
151
-
152
- create_table :merit_score_points do |t|
153
- t.references :score
154
- t.integer :num_points, :default => 0
155
- t.string :log
156
- t.datetime :created_at
157
- end
158
- end
159
-
160
- def self.down
161
- drop_table :merit_scores
162
- drop_table :merit_score_points
163
- end
164
- end
165
-
166
- # This will create a single point entry log, with previous points granted
167
- # to each meritable resource. Code example for a User class.
168
-
169
- class UpgradeMeritableResources < ActiveRecord::Migration
170
- def up
171
- User.find_each do |user|
172
- unless user.sash
173
- user.sash = Sash.create!
174
- user.save
175
- end
176
-
177
- user.sash.scores << Merit::Score.create
178
- user.add_points(user.read_attribute(:points), 'Initial merit points import.')
179
- end
180
- remove_column :users, :points
181
- end
182
- end
183
-
184
- If you get an `ActiveRecord::DangerousAttributeError: points` exception, you
185
- may need to temporarily tweak your meritable model, as explained in
186
- http://stackoverflow.com/a/1515571/356060.
187
-
188
-
189
- ## to 0.10.0
190
-
191
- `badges_sashes` table gets a primary key `id` column. Run the following migration:
192
-
193
- class AddIdToBadgesSashes < ActiveRecord::Migration
194
- def self.up
195
- add_column :badges_sashes, :id, :primary_key
196
- end
197
-
198
- def self.down
199
- remove_column :badges_sashes, :id
200
- end
201
- end
202
-
203
- `set_notified!(badge = nil, sash = nil)` no longer exists, just call `set_notified!`
204
- over the `badge_sash` object, with no parameters.
205
-
206
- ## to 0.9.0
207
-
208
- Adds `allow_multiple` boolean option to `Badge#grant_to` (defaults to
209
- `false`). If you used this method to grant a badge it will now grant only if
210
- resource doesn't have the badge.
211
-
212
- Use `badge.grant_to resource, :allow_multiple => true` where needed.
213
-
214
- ## to 0.8.0
215
-
216
- No changes needed. Adds Mongoid support.
217
-
218
- ## to 0.7.0
219
-
220
- No changes needed. Adds `:multiple` boolean option to `grant_on` to grant
221
- badge multiple times.
222
-
223
- ## to 0.6.0
224
-
225
- <tt>MeritBadgeRules</tt>, <tt>MeritPointRules</tt> and <tt>MeritRankRules</tt>
226
- are now namespaced into Merit module. Move and change:
227
-
228
- <pre>
229
- app/models/merit_{badge|point|rank}_rules.rb -> app/models/merit/{badge|point|rank}_rules.rb
230
- </pre>
231
- <pre>
232
- -class Merit{Badge|Point|Rank}Rules
233
- - include Merit::{Badge|Point|Rank}Rules
234
- +module Merit
235
- + class {Badge|Point|Rank}Rules
236
- + include Merit::{Badge|Point|Rank}RulesMethods
237
- </pre>
238
-
239
- ## to 0.5.0
240
-
241
- Add <tt>log:string</tt> column to <tt>merit_actions</tt> table.
242
-
243
- ## to 0.4.0
244
-
245
- Rankings are now integer attributes (<tt>level</tt>), they are not badges
246
- anymore. <tt>set_rank</tt> doesn't accept <tt>badge_name</tt> anymore.
247
-
248
- ## to 0.3.0
249
-
250
- Badges data is now stored in <tt>config/initializers/merit.rb</tt> using
251
- <tt>ambry</tt> syntax (not in the DB anymore, as that table needed to be in
252
- sync in all development environments).
253
-
254
- ## to 0.2.0
255
-
256
- Added <tt>had_errors</tt> boolean attribute to <tt>merit_actions</tt> table.
@@ -1,5 +0,0 @@
1
- class AddTargetDataToMeritActions < ActiveRecord::Migration
2
- def change
3
- add_column :merit_actions, :target_data, :text
4
- end
5
- end
@@ -1,7 +0,0 @@
1
- class CreateSashes < ActiveRecord::Migration
2
- def change
3
- create_table :sashes do |t|
4
- t.timestamps
5
- end
6
- end
7
- end
@@ -1,36 +0,0 @@
1
- require 'rails/generators/active_record'
2
-
3
- module ActiveRecord
4
- module Generators
5
- class UpgradeGenerator < Rails::Generators::Base
6
- include Rails::Generators::Migration
7
-
8
- source_root File.expand_path('../templates', __FILE__)
9
- desc 'Makes Active Record migrations to handle upgrades between versions'
10
-
11
- def self.next_migration_number(path)
12
- ActiveRecord::Generators::Base.next_migration_number(path)
13
- end
14
-
15
- def copy_migrations_and_model
16
- if merit_actions_exists? && target_data_column_doesnt_exist?
17
- migration_template 'add_target_data_to_merit_actions.rb',
18
- 'db/migrate/add_target_data_to_merit_actions.rb'
19
- end
20
- end
21
-
22
- private
23
-
24
- def target_data_column_doesnt_exist?
25
- !ActiveRecord::Base.connection.column_exists?(:merit_actions,
26
- :target_data)
27
- end
28
-
29
- # Might be foolishly running this before install. Ugly error if we don't
30
- # check.
31
- def merit_actions_exists?
32
- ActiveRecord::Base.connection.table_exists? :merit_actions
33
- end
34
- end
35
- end
36
- end
@@ -1,16 +0,0 @@
1
- module Merit
2
- module Generators
3
- class InstallGenerator < Rails::Generators::Base
4
- source_root File.expand_path('../templates', __FILE__)
5
- hook_for :orm
6
-
7
- desc 'Copy config and rules files'
8
- def copy_migrations_and_model
9
- template 'merit.rb', 'config/initializers/merit.rb'
10
- template 'merit_badge_rules.rb', 'app/models/merit/badge_rules.rb'
11
- template 'merit_point_rules.rb', 'app/models/merit/point_rules.rb'
12
- template 'merit_rank_rules.rb', 'app/models/merit/rank_rules.rb'
13
- end
14
- end
15
- end
16
- end
@@ -1,7 +0,0 @@
1
- module Merit
2
- module Generators
3
- class UpgradeGenerator < Rails::Generators::Base
4
- hook_for :orm
5
- end
6
- end
7
- end
@@ -1,12 +0,0 @@
1
- module Merit
2
- class Action < ActiveRecord::Base
3
- self.table_name = :merit_actions
4
-
5
- has_many :activity_logs, class_name: 'Merit::ActivityLog'
6
-
7
- if show_attr_accessible?
8
- attr_accessible :user_id, :action_method, :action_value, :had_errors,
9
- :target_model, :target_id, :processed, :log, :target_data
10
- end
11
- end
12
- end
@@ -1,18 +0,0 @@
1
- module Merit
2
- class Action
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
-
6
- has_many :activity_logs, class_name: 'Merit::ActivityLog', as: :related_change
7
-
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 :target_data
15
- field :processed, type: Boolean, default: false
16
- field :log
17
- end
18
- end
@@ -1,11 +0,0 @@
1
- module Merit
2
- class ActivityLog
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
-
6
- field :description
7
-
8
- belongs_to :action, class_name: 'Merit::Action'
9
- belongs_to :related_change, polymorphic: true
10
- end
11
- end
@@ -1,22 +0,0 @@
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
-
9
- attr_accessible :badge_id if show_attr_accessible?
10
-
11
- belongs_to :sash, class_name: 'Merit::Sash'
12
- has_many :activity_logs, class_name: 'Merit::ActivityLog', as: :related_change
13
-
14
- def self.last_granted(options = {})
15
- options[:since_date] ||= 1.month.ago
16
- options[:limit] ||= 10
17
- where(:created_at.lte => options[:since_date])
18
- .limit(options[:limit])
19
- .map(&:badge)
20
- end
21
- end
22
- end
@@ -1,30 +0,0 @@
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
- # Retrieve all points from a category or none if category doesn't exist
19
- # By default retrieve all Points
20
- # @param category [String] The category
21
- # @return [ActiveRecord::Relation] containing the points
22
- def score_points(options = {})
23
- scope = scores
24
- if (category = options[:category])
25
- scope = scope.where(category: category)
26
- end
27
- Merit::Score::Point.where(:score_id.in => scope.map(&:_id))
28
- end
29
- end
30
- end
@@ -1,45 +0,0 @@
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, class_name: 'Merit::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
-
40
- def sash_id
41
- score.sash_id
42
- end
43
- end
44
- end
45
- end