I am writing a gem which will handle all kind of notifications for a model (sms, mobile and browser notifications)
in rails project under app directory created new folder 'notifiers' which contain files like
app/notifiers/user_notifier.rb
class UserNotifier < ApplicationNotifier
def send_reminder
{
type: 'sms',
content: 'hi everyone',
recipients: [12134343,2342322,3434343]
}
end
end
this user_notifier file should be against User model. means that this method send_reminder should be available to instance/object of User
User.last.send_reminder
So, issue is
This is possible with concerns and namespaces but this would create messy code
Thanks to Léonard, he posted the solution but while writing the gem we need to handle these configuration from gem. Because when someone use our gem he/she don't have to write any configuration related logic in application_record.rb manually.
posting it just to ensure that in future may it helpful for someone else.
what i did to tackle this issue (to attach gem with a model we add act_as_notifier in model with which we want it to be configured)
#rails_notifier/model_config.rb
def initialize(model_class)
@model_class = model_class
# get model corresponding notifier class
# for User model class, there would UserNotifier class
# under notifiers folder of app directory
# getting notitifer class name
notifier_class = "#{@model_class.name}Notifier"
# Notifier class attribute set later set with model object
attribute_name = @model_class.name.underscore
# register a `notifier` method in model class
# 'method_name' is a method of notifier class
# and options hash contain sender
@model_class.class_eval do
define_method(:notifier) do |method_name, options|
# create notifier class object
notifier_ = notifier_class.constantize.new
# define setter for notifier attribute
notifier_.send(:define_singleton_method, "#{attribute_name}=".to_sym) do |value|
instance_variable_set("@" + attribute_name.to_s, value)
end
# define getter for notifier attribute
notifier_.send(:define_singleton_method, attribute_name.to_sym) do
instance_variable_get("@" + attribute_name.to_s)
end
# self point to the object of model
# e.g User.last.notifier(:send_reminder), slef = User.last
# set notifier attribute with model object
notifier_.send("#{attribute_name}=".to_sym, self)
notifier_hash = notifier_.send(method_name)
RailsNotifier.notify(notifier_hash) if notifier_hash.present?
end
end
end