Describe the bug
As soon as I added notification-pusher
to my project (which previously only had notification-handler
, notification-settings
), the code where I was creating a Notification
record started having this error:
ArgumentError:
wrong number of arguments (given 0, expected 1..2)
# notifications-rails/notification-pusher/lib/notification_pusher/notification_library.rb:20:in `push'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:71:in `can_push?'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:59:in `initialize_pusher'
# notifications-rails/notification-handler/lib/notification_handler/target.rb:22:in `notify'
Looking at the code, I see that notification-pusher
adds this callback to Notification:
after_create_commit :initialize_pusher
which calls the initialize_pusher
from notification-settings/lib/notification_settings/notification_library.rb
:
def initialize_pusher
return unless can_push?
super
end
which (before calling super
to pass control on to the "main" initialize_pusher
in notification-pusher/lib/notification_pusher/notification_library.rb
) checks:
def can_push?
if target.notification_setting.present?
return false unless status_allows_push?
if push.is_a?(Array)
return false unless can_use_pushers?(push)
else
return false unless can_use_pusher?(push)
end
end
true
end
The only place Notification#push
is defined is in notification-pusher/lib/notification_pusher/notification_library.rb
:
def push(name, options = {})
self.pusher = name
self.pusher_options = options
initialize_pusher
end
That obviously isn't what it was intended to call, esp. since that would in turn call initialize_pusher
again and cause an infinite loop.
I assume what was intended was to refer to pusher
rather than push
. pusher
appears to also be defined in notification-pusher/lib/notification_pusher/notification_library.rb
:
Next error: undefined method
to_sym' for nil:NilClass`
After I made the changes mentioned above, I ran into another error...
NoMethodError:
undefined method `to_sym' for nil:NilClass
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:107:in `local_settings_allow_push?'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:103:in `local_pusher_settings?'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:98:in `settings_allow_push?'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:86:in `can_use_pusher?'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:72:in `can_push?'
# notifications-rails/notification-settings/lib/notification_settings/notification_library.rb:60:in `initialize_pusher'
from here:
def local_settings_allow_push?(pusher)
target.notification_setting.settings.dig(pusher.to_sym)
end
which was called from here:
def can_push?
if target.notification_setting.present?
return false unless status_allows_push?
if pusher.is_a?(Array)
return false unless can_use_pushers?(pusher)
else
return false unless can_use_pusher?(pusher)
end
end
true
end
But of course pusher
was nil. Aren't we allowed to create a notification without passing a pusher
? The official examples suggest that this should be allowed:
notification = Notification.create(target: User.first, object: Recipe.first)
notification.push(:CustomPusher, option_one: 'value_two')
Next issue: pushers disabled by default?
I found the suggestion in #4 to try passing push: :ActionMailer
. I wasn't sure how push:
would work since push
isn't an attribute (how was that ever working?), so I tried pusher: :ActionMailer
instead:
notification = user.notify(object: self, category: 'weekly_report_mailer.individual_contribution_link', pusher: :ActionMailer)
... which resolved the error, but didn't actually call the pusher, because global_settings_allow_push?
returned nil:
[105, 114] in notifications-rails/notification-settings/lib/notification_settings/notification_library.rb
105: def local_settings_allow_push?(pusher)
106: target.notification_setting.settings.dig(pusher.to_sym)
107: end
108:
109: def global_settings_allow_push?
=> 110: target.notification_setting.settings.dig(:index)
111: end
Wat? Where is it documented that there needs to be a truthy :index
setting in order for pushes to be considered enabled? https://github.com/jonhue/notifications-rails/tree/master/notification-settings talks about setting s.settings[:enabled] = false
to disable notifications ("globally"? for a user), but says nothing about :index
. What's the difference? What does :index
even mean or refer to? (I see "index" mentioned in https://github.com/jonhue/notifications-rails/tree/master/notification-renderer, but I'm not using notification-renderer
and it doesn't mention anything about an :index
setting.)
Should this be called something else? :push_enabled
(to be different from :enabled
setting used by settings_allow_create?
), perhaps?
I thought things were enabled by default? Should we make another change like #37 (which made settings_allow_create?
true by default) to make global_settings_allow_push?
true by default?
Or are we really expected to go through all our users and set {index: true}
in each of their settings? (Or am I missing something?)
Conclusion
Is anyone actually using this gem?
I'm frustrated by how much this project overpromises, and how much I've had to fight just to get these gems working at all.
The examples in each gem are nice but they're too isolated. They don't really give the big picture of how you're expected to use several of the notifications-rails
gems together. A full example app that demonstrates how these gems could really be put to use would be nice to see...
Some automated tests would be really helpful in inspiring confidence that things actually work in intended ways, and continue to stay working (#7)...
Additional context
Using latest version from git.