user_notification 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +1 -0
  5. data/Rakefile +18 -0
  6. data/lib/generators/user_notification/migration/migration_generator.rb +17 -0
  7. data/lib/generators/user_notification/migration/templates/migration.rb +24 -0
  8. data/lib/generators/user_notification/notification/notification_generator.rb +17 -0
  9. data/lib/generators/user_notification/notification/templates/notification.rb +3 -0
  10. data/lib/generators/user_notification.rb +14 -0
  11. data/lib/user_notification/actions/creation.rb +15 -0
  12. data/lib/user_notification/actions/destruction.rb +15 -0
  13. data/lib/user_notification/actions/update.rb +15 -0
  14. data/lib/user_notification/activity.rb +6 -0
  15. data/lib/user_notification/common.rb +342 -0
  16. data/lib/user_notification/config.rb +63 -0
  17. data/lib/user_notification/models/activist.rb +9 -0
  18. data/lib/user_notification/models/adapter.rb +5 -0
  19. data/lib/user_notification/models/notification.rb +13 -0
  20. data/lib/user_notification/models/trackable.rb +9 -0
  21. data/lib/user_notification/orm/active_record/activist.rb +48 -0
  22. data/lib/user_notification/orm/active_record/adapter.rb +16 -0
  23. data/lib/user_notification/orm/active_record/notification.rb +24 -0
  24. data/lib/user_notification/orm/active_record/trackable.rb +15 -0
  25. data/lib/user_notification/orm/active_record.rb +5 -0
  26. data/lib/user_notification/orm/mongo_mapper/activist.rb +46 -0
  27. data/lib/user_notification/orm/mongo_mapper/adapter.rb +12 -0
  28. data/lib/user_notification/orm/mongo_mapper/notification.rb +33 -0
  29. data/lib/user_notification/orm/mongo_mapper/trackable.rb +11 -0
  30. data/lib/user_notification/orm/mongo_mapper.rb +4 -0
  31. data/lib/user_notification/orm/mongoid/activist.rb +45 -0
  32. data/lib/user_notification/orm/mongoid/adapter.rb +12 -0
  33. data/lib/user_notification/orm/mongoid/notification.rb +26 -0
  34. data/lib/user_notification/orm/mongoid/trackable.rb +11 -0
  35. data/lib/user_notification/orm/mongoid.rb +4 -0
  36. data/lib/user_notification/renderable.rb +118 -0
  37. data/lib/user_notification/roles/deactivatable.rb +42 -0
  38. data/lib/user_notification/roles/tracked.rb +183 -0
  39. data/lib/user_notification/utility/store_controller.rb +37 -0
  40. data/lib/user_notification/utility/view_helpers.rb +26 -0
  41. data/lib/user_notification/version.rb +4 -0
  42. data/lib/user_notification.rb +68 -0
  43. data/test/migrations/001_create_notifications.rb +24 -0
  44. data/test/migrations/002_create_articles.rb +11 -0
  45. data/test/migrations/003_create_users.rb +8 -0
  46. data/test/migrations/004_add_nonstandard_to_notifications.rb +7 -0
  47. data/test/mongo_mapper.yml +4 -0
  48. data/test/mongoid.yml +6 -0
  49. data/test/test_activist.rb +56 -0
  50. data/test/test_common.rb +168 -0
  51. data/test/test_controller_integration.rb +41 -0
  52. data/test/test_generators.rb +30 -0
  53. data/test/test_helper.rb +124 -0
  54. data/test/test_notification.rb +67 -0
  55. data/test/test_tracking.rb +378 -0
  56. data/test/test_view_helpers.rb +36 -0
  57. data/test/views/layouts/_notification.erb +1 -0
  58. data/test/views/user_notification/_test.erb +8 -0
  59. metadata +260 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1c901c8b0055869556adb983350a2269ca0e3f6
4
+ data.tar.gz: ad1401b517003379e34d48742132287cee17de93
5
+ SHA512:
6
+ metadata.gz: 30f2acc2a7562ad950d7336fa5046ccd932c4908668d0c8715d4f6fc851c00d97015db08e352e464beb1ba07eddf56f585c1e6b2c45735036df7b15602230fbf
7
+ data.tar.gz: f3a169119d6080443fb38ccfc69f161c76561c38ef46b19bc861db2e193d5b8092bb4eacb809bd5a6337c711c73c6d9f142ca85c6210a141ae457c2e408bd9a1
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2013 Piotrek Okoński
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # User Notification [![Build Status](https://travis-ci.org/yesmeck/user_notification.png?branch=master)](https://travis-ci.org/yesmeck/user_notification)
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'yard'
4
+ require 'yard/rake/yardoc_task'
5
+ require 'rake/testtask'
6
+
7
+ task :default => :test
8
+
9
+ desc 'Generate documentation for the user_notification plugin.'
10
+ YARD::Rake::YardocTask.new do |doc|
11
+ doc.files = ['lib/**/*.rb']
12
+ end
13
+
14
+ Rake::TestTask.new do |t|
15
+ t.libs << "test"
16
+ t.test_files = FileList['test/test*.rb']
17
+ end
18
+
@@ -0,0 +1,17 @@
1
+ require 'generators/user_notification'
2
+ require 'rails/generators/active_record'
3
+
4
+ module UserNotification
5
+ module Generators
6
+ # Migration generator that creates migration file from template
7
+ class MigrationGenerator < ActiveRecord::Generators::Base
8
+ extend Base
9
+
10
+ argument :name, :type => :string, :default => 'create_notifications'
11
+ # Create migration in project's folder
12
+ def generate_files
13
+ migration_template 'migration.rb', "db/migrate/#{name}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # Migration responsible for creating a table with notifications
2
+ class CreateNotifications < ActiveRecord::Migration
3
+ # Create table
4
+ def self.up
5
+ create_table :notifications do |t|
6
+ t.belongs_to :trackable, :polymorphic => true
7
+ t.belongs_to :owner, :polymorphic => true
8
+ t.string :key
9
+ t.text :parameters
10
+ t.belongs_to :recipient, :polymorphic => true
11
+ t.boolwan :read, default: false
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :notifications, [:trackable_id, :trackable_type]
17
+ add_index :notifications, [:owner_id, :owner_type]
18
+ add_index :notifications, [:recipient_id, :recipient_type]
19
+ end
20
+ # Drop table
21
+ def self.down
22
+ drop_table :notifications
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ require 'generators/user_notification'
2
+ require 'rails/generators/active_record'
3
+
4
+ module UserNotification
5
+ module Generators
6
+ # Notification generator that creates notification model file from template
7
+ class NotificationGenerator < ActiveRecord::Generators::Base
8
+ extend Base
9
+
10
+ argument :name, :type => :string, :default => 'notification'
11
+ # Create model in project's folder
12
+ def generate_files
13
+ copy_file 'notification.rb', "app/models/#{name}.rb"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ # Notification model for customisation & custom methods
2
+ class Notification < UserNotification::Notification
3
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails/generators/named_base'
2
+
3
+ module UserNotification
4
+ # A generator module with Notification table schema.
5
+ module Generators
6
+ # A base module
7
+ module Base
8
+ # Get path for migration template
9
+ def source_root
10
+ @_user_notification_source_root ||= File.expand_path(File.join('../user_notification', generator_name, 'templates'), __FILE__)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module UserNotification
2
+ # Handles creation of Activities upon destruction and update of tracked model.
3
+ module Creation
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_create :notification_on_create
8
+ end
9
+ private
10
+ # Creates notification upon creation of the tracked model
11
+ def notification_on_create
12
+ create_notification(:create)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module UserNotification
2
+ # Handles creation of Activities upon destruction of tracked model.
3
+ module Destruction
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_destroy :notification_on_destroy
8
+ end
9
+ private
10
+ # Records an notification upon destruction of the tracked model
11
+ def notification_on_destroy
12
+ create_notification(:destroy)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module UserNotification
2
+ # Handles creation of Activities upon destruction and update of tracked model.
3
+ module Update
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_update :notification_on_update
8
+ end
9
+ private
10
+ # Creates notification upon modification of the tracked model
11
+ def notification_on_update
12
+ create_notification(:update)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module UserNotification
2
+ # Main model, stores all information about what happened,
3
+ # who caused it, when and anything else.
4
+ class Notification < inherit_orm("Notification")
5
+ end
6
+ end
@@ -0,0 +1,342 @@
1
+ module UserNotification
2
+ # Happens when creating custom notifications without either action or a key.
3
+ class NoKeyProvided < Exception; end
4
+
5
+ # Used to smartly transform value from metadata to data.
6
+ # Accepts Symbols, which it will send against context.
7
+ # Accepts Procs, which it will execute with controller and context.
8
+ # @since 0.4.0
9
+ def self.resolve_value(context, thing)
10
+ case thing
11
+ when Symbol
12
+ context.__send__(thing)
13
+ when Proc
14
+ thing.call(UserNotification.get_controller, context)
15
+ else
16
+ thing
17
+ end
18
+ end
19
+
20
+ # Common methods shared across the gem.
21
+ module Common
22
+ extend ActiveSupport::Concern
23
+
24
+ included do
25
+ include Trackable
26
+ class_attribute :notification_owner_global, :notification_recipient_global,
27
+ :notification_params_global, :notification_hooks, :notification_custom_fields_global
28
+ set_user_notification_class_defaults
29
+ end
30
+
31
+ # @!group Global options
32
+
33
+ # @!attribute notification_owner_global
34
+ # Global version of notification owner
35
+ # @see #notification_owner
36
+ # @return [Model]
37
+
38
+ # @!attribute notification_recipient_global
39
+ # Global version of notification recipient
40
+ # @see #notification_recipient
41
+ # @return [Model]
42
+
43
+ # @!attribute notification_params_global
44
+ # Global version of notification parameters
45
+ # @see #notification_params
46
+ # @return [Hash<Symbol, Object>]
47
+
48
+ # @!attribute notification_hooks
49
+ # @return [Hash<Symbol, Proc>]
50
+ # Hooks/functions that will be used to decide *if* the notification should get
51
+ # created.
52
+ #
53
+ # The supported keys are:
54
+ # * :create
55
+ # * :update
56
+ # * :destroy
57
+
58
+ # @!endgroup
59
+
60
+ # @!group Instance options
61
+
62
+ # Set or get parameters that will be passed to {Notification} when saving
63
+ #
64
+ # == Usage:
65
+ #
66
+ # @article.notification_params = {:article_title => @article.title}
67
+ # @article.save
68
+ #
69
+ # This way you can pass strings that should remain constant, even when model attributes
70
+ # change after creating this {Notification}.
71
+ # @return [Hash<Symbol, Object>]
72
+ attr_accessor :notification_params
73
+ @notification_params = {}
74
+ # Set or get owner object responsible for the {Notification}.
75
+ #
76
+ # == Usage:
77
+ #
78
+ # # where current_user is an object of logged in user
79
+ # @article.notification_owner = current_user
80
+ # # OR: take @article.author association
81
+ # @article.notification_owner = :author
82
+ # # OR: provide a Proc with custom code
83
+ # @article.notification_owner = proc {|controller, model| model.author }
84
+ # @article.save
85
+ # @article.notifications.last.owner #=> Returns owner object
86
+ # @return [Model] Polymorphic model
87
+ # @see #notification_owner_global
88
+ attr_accessor :notification_owner
89
+ @notification_owner = nil
90
+
91
+ # Set or get recipient for notification.
92
+ #
93
+ # Association is polymorphic, thus allowing assignment of
94
+ # all types of models. This can be used for example in the case of sending
95
+ # private notifications for only a single user.
96
+ # @return (see #notification_owner)
97
+ attr_accessor :notification_recipient
98
+ @notification_recipient = nil
99
+ # Set or get custom i18n key passed to {Notification}, later used in {Renderable#text}
100
+ #
101
+ # == Usage:
102
+ #
103
+ # @article = Article.new
104
+ # @article.notification_key = "my.custom.article.key"
105
+ # @article.save
106
+ # @article.notifications.last.key #=> "my.custom.article.key"
107
+ #
108
+ # @return [String]
109
+ attr_accessor :notification_key
110
+ @notification_key = nil
111
+
112
+ # Set or get custom fields for later processing
113
+ #
114
+ # @return [Hash]
115
+ attr_accessor :notification_custom_fields
116
+ @notification_custom_fields = {}
117
+
118
+ # @!visibility private
119
+ @@notification_hooks = {}
120
+
121
+ # @!endgroup
122
+
123
+ # Provides some global methods for every model class.
124
+ module ClassMethods
125
+ #
126
+ # @since 1.0.0
127
+ # @api private
128
+ def set_user_notification_class_defaults
129
+ self.notification_owner_global = nil
130
+ self.notification_recipient_global = nil
131
+ self.notification_params_global = {}
132
+ self.notification_hooks = {}
133
+ self.notification_custom_fields_global = {}
134
+ end
135
+
136
+ # Extracts a hook from the _:on_ option provided in
137
+ # {Tracked::ClassMethods#tracked}. Returns nil when no hook exists for
138
+ # given action
139
+ # {Common#get_hook}
140
+ #
141
+ # @see Tracked#get_hook
142
+ # @param key [String, Symbol] action to retrieve a hook for
143
+ # @return [Proc, nil] callable hook or nil
144
+ # @since 0.4.0
145
+ # @api private
146
+ def get_hook(key)
147
+ key = key.to_sym
148
+ if self.notification_hooks.has_key?(key) and self.notification_hooks[key].is_a? Proc
149
+ self.notification_hooks[key]
150
+ else
151
+ nil
152
+ end
153
+ end
154
+ end
155
+ #
156
+ # Returns true if UserNotification is enabled
157
+ # globally and for this class.
158
+ # @return [Boolean]
159
+ # @api private
160
+ # @since 0.5.0
161
+ def user_notification_enabled?
162
+ UserNotification.enabled?
163
+ end
164
+ #
165
+ # Shortcut for {ClassMethods#get_hook}
166
+ # @param (see ClassMethods#get_hook)
167
+ # @return (see ClassMethods#get_hook)
168
+ # @since (see ClassMethods#get_hook)
169
+ # @api (see ClassMethods#get_hook)
170
+ def get_hook(key)
171
+ self.class.get_hook(key)
172
+ end
173
+
174
+ # Calls hook safely.
175
+ # If a hook for given action exists, calls it with model (self) and
176
+ # controller (if available, see {StoreController})
177
+ # @param key (see #get_hook)
178
+ # @return [Boolean] if hook exists, it's decision, if there's no hook, true
179
+ # @since 0.4.0
180
+ # @api private
181
+ def call_hook_safe(key)
182
+ hook = self.get_hook(key)
183
+ if hook
184
+ # provides hook with model and controller
185
+ hook.call(self, UserNotification.get_controller)
186
+ else
187
+ true
188
+ end
189
+ end
190
+
191
+ # Directly creates notification record in the database, based on supplied options.
192
+ #
193
+ # It's meant for creating custom notifications while *preserving* *all*
194
+ # *configuration* defined before. If you fire up the simplest of options:
195
+ #
196
+ # current_user.create_notification(:avatar_changed)
197
+ #
198
+ # It will still gather data from any procs or symbols you passed as params
199
+ # to {Tracked::ClassMethods#tracked}. It will ask the hooks you defined
200
+ # whether to really save this notification.
201
+ #
202
+ # But you can also overwrite instance and global settings with your options:
203
+ #
204
+ # @article.notification :owner => proc {|controller| controller.current_user }
205
+ # @article.create_notification(:commented_on, :owner => @user)
206
+ #
207
+ # And it's smart! It won't execute your proc, since you've chosen to
208
+ # overwrite instance parameter _:owner_ with @user.
209
+ #
210
+ # [:key]
211
+ # The key will be generated from either:
212
+ # * the first parameter you pass that is not a hash (*action*)
213
+ # * the _:action_ option in the options hash (*action*)
214
+ # * the _:key_ option in the options hash (it has to be a full key,
215
+ # including model name)
216
+ # When you pass an *action* (first two options above), they will be
217
+ # added to parameterized model name:
218
+ #
219
+ # Given Article model and instance: @article,
220
+ #
221
+ # @article.create_notification :commented_on
222
+ # @article.notifications.last.key # => "article.commented_on"
223
+ #
224
+ # For other parameters, see {Tracked#notification}, and "Instance options"
225
+ # accessors at {Tracked}, information on hooks is available at
226
+ # {Tracked::ClassMethods#tracked}.
227
+ # @see #prepare_settings
228
+ # @return [Model, nil] If created successfully, new notification
229
+ # @since 0.4.0
230
+ # @api public
231
+ # @overload create_notification(action, options = {})
232
+ # @param [Symbol,String] action Name of the action
233
+ # @param [Hash] options Options with quality higher than instance options
234
+ # set in {Tracked#notification}
235
+ # @option options [Activist] :owner Owner
236
+ # @option options [Activist] :recipient Recipient
237
+ # @option options [Hash] :params Parameters, see
238
+ # {UserNotification.resolve_value}
239
+ # @overload create_notification(options = {})
240
+ # @param [Hash] options Options with quality higher than instance options
241
+ # set in {Tracked#notification}
242
+ # @option options [Symbol,String] :action Name of the action
243
+ # @option options [String] :key Full key
244
+ # @option options [Activist] :owner Owner
245
+ # @option options [Activist] :recipient Recipient
246
+ # @option options [Hash] :params Parameters, see
247
+ # {UserNotification.resolve_value}
248
+ def create_notification(*args)
249
+ return unless self.user_notification_enabled?
250
+ options = prepare_settings(*args)
251
+
252
+ if call_hook_safe(options[:key].split('.').last)
253
+ reset_notification_instance_options
254
+ return UserNotification::Adapter.create_notification(self, options)
255
+ end
256
+
257
+ nil
258
+ end
259
+
260
+ # Prepares settings used during creation of Notification record.
261
+ # params passed directly to tracked model have priority over
262
+ # settings specified in tracked() method
263
+ #
264
+ # @see #create_notification
265
+ # @return [Hash] Settings with preserved options that were passed
266
+ # @api private
267
+ # @overload prepare_settings(action, options = {})
268
+ # @see #create_notification
269
+ # @overload prepare_settings(options = {})
270
+ # @see #create_notification
271
+ def prepare_settings(*args)
272
+ # key
273
+ all_options = args.extract_options!
274
+ options = {
275
+ key: all_options.delete(:key),
276
+ action: all_options.delete(:action),
277
+ parameters: all_options.delete(:parameters) || all_options.delete(:params)
278
+ }
279
+ action = (args.first || options[:action]).try(:to_s)
280
+
281
+ options[:key] = extract_key(action, options)
282
+
283
+ raise NoKeyProvided, "No key provided for #{self.class.name}" unless options[:key]
284
+
285
+ options.delete(:action)
286
+
287
+ # user responsible for the notification
288
+ options[:owner] = UserNotification.resolve_value(self,
289
+ (all_options.has_key?(:owner) ? all_options[:owner] : (
290
+ self.notification_owner || self.class.notification_owner_global
291
+ )
292
+ )
293
+ )
294
+
295
+ # recipient of the notification
296
+ options[:recipient] = UserNotification.resolve_value(self,
297
+ (all_options.has_key?(:recipient) ? all_options[:recipient] : (
298
+ self.notification_recipient || self.class.notification_recipient_global
299
+ )
300
+ )
301
+ )
302
+
303
+ #customizable parameters
304
+ params = {}
305
+ params.merge!(self.class.notification_params_global)
306
+ params.merge!(self.notification_params) if self.notification_params
307
+ params.merge!(options[:params] || options[:parameters] || {})
308
+ params.each { |k, v| params[k] = UserNotification.resolve_value(self, v) }
309
+ options[:parameters] = params
310
+ options.delete(:params)
311
+
312
+ customs = self.class.notification_custom_fields_global.clone
313
+ customs.merge!(self.notification_custom_fields) if self.notification_custom_fields
314
+ customs.merge!(all_options)
315
+ customs.each do |k, v|
316
+ customs[k] = UserNotification.resolve_value(self, v)
317
+ end.merge options
318
+ end
319
+
320
+ # Helper method to serialize class name into relevant key
321
+ # @return [String] the resulted key
322
+ # @param [Symbol] or [String] the name of the operation to be done on class
323
+ # @param [Hash] options to be used on key generation, defaults to {}
324
+ def extract_key(action, options = {})
325
+ (options[:key] || self.notification_key ||
326
+ ((self.class.name.underscore.gsub('/', '_') + "." + action.to_s) if action)
327
+ ).try(:to_s)
328
+ end
329
+
330
+ # Resets all instance options on the object
331
+ # triggered by a successful #create_notification, should not be
332
+ # called from any other place, or from application code.
333
+ # @private
334
+ def reset_notification_instance_options
335
+ @notification_params = {}
336
+ @notification_key = nil
337
+ @notification_owner = nil
338
+ @notification_recipient = nil
339
+ @notification_custom_fields = {}
340
+ end
341
+ end
342
+ end
@@ -0,0 +1,63 @@
1
+ require 'singleton'
2
+
3
+ module UserNotification
4
+ # Class used to initialize configuration object.
5
+ class Config
6
+ include ::Singleton
7
+ attr_accessor :enabled
8
+
9
+ @@orm = :active_record
10
+
11
+ def initialize
12
+ # Indicates whether UserNotification is enabled globally
13
+ @enabled = true
14
+ end
15
+
16
+ # Evaluates given block to provide DSL configuration.
17
+ # @example Initializer for Rails
18
+ # UserNotification::Config.set do
19
+ # orm :mongo_mapper
20
+ # enabled false
21
+ # end
22
+ def self.set &block
23
+ b = Block.new
24
+ b.instance_eval &block
25
+ orm = b.instance_variable_get(:@orm)
26
+ @@orm = orm unless orm.nil?
27
+ enabled = b.instance_variable_get(:@en)
28
+ instance
29
+ instance.instance_variable_set(:@enabled, enabled) unless enabled.nil?
30
+ end
31
+
32
+ # Set the ORM for use by UserNotification.
33
+ def self.orm(orm = nil)
34
+ @@orm = (orm ? orm.to_sym : false) || @@orm
35
+ end
36
+
37
+ # alias for {#orm}
38
+ # @see #orm
39
+ def self.orm=(orm = nil)
40
+ orm(orm)
41
+ end
42
+
43
+ # instance version of {Config#orm}
44
+ # @see Config#orm
45
+ def orm(orm=nil)
46
+ self.class.orm(orm)
47
+ end
48
+
49
+ # Provides simple DSL for the config block.
50
+ class Block
51
+ # @see Config#orm
52
+ def orm(orm = nil)
53
+ @orm = (orm ? orm.to_sym : false) || @orm
54
+ end
55
+
56
+ # Decides whether to enable UserNotification.
57
+ # @param en [Boolean] Enabled?
58
+ def enabled(en = nil)
59
+ @en = (en.nil? ? @en : en)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ module UserNotification
2
+ # Provides helper methods for selecting notifications from a user.
3
+ module Activist
4
+ # Delegates to configured ORM.
5
+ def self.included(base)
6
+ base.extend UserNotification::inherit_orm("Activist")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module UserNotification
2
+ # Loads database-specific routines for use by UserNotification.
3
+ class Adapter < inherit_orm("Adapter")
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module UserNotification
2
+ class Notification < inherit_orm("Notification")
3
+
4
+ def mark_as_read
5
+ self.read = true
6
+ end
7
+
8
+ def mark_as_read!
9
+ self.update_attribute(:read, true)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module UserNotification
2
+ # Provides association for notifications bound to this object by *trackable*.
3
+ module Trackable
4
+ # Delegates to ORM.
5
+ def self.included(base)
6
+ base.extend UserNotification::inherit_orm("Trackable")
7
+ end
8
+ end
9
+ end