RubyonRails:在应用程序目录中添加子文件夹,其中包含特定于模型的文件

neskvpey  于 2021-09-29  发布在  Java
关注(0)|答案(2)|浏览(319)

我正在写一个gem,它将处理模型的各种通知(短信、手机和浏览器通知)
在应用目录下的rails项目中创建了新文件夹“notifiers”,其中包含以下文件

  1. app/notifiers/user_notifier.rb
  2. class UserNotifier < ApplicationNotifier
  3. def send_reminder
  4. {
  5. type: 'sms',
  6. content: 'hi everyone',
  7. recipients: [12134343,2342322,3434343]
  8. }
  9. end
  10. end

此用户通知程序文件应针对用户模型。表示此方法发送提醒应可用于用户的示例/对象 User.last.send_reminder 所以,问题是
如何使notifiers文件夹的文件特定于模型(user.rb模型文件在notifiers文件夹中有user_notifier.rb文件)
该文件user_notifier.rb方法对用户模型的可用性
这在关注点和名称空间中是可能的,但这会创建混乱的代码

c90pui9n

c90pui9n1#

如何使notifiers文件夹的文件特定于模型?
app文件夹下的所有代码都是在没有任何配置的情况下加载的。您只需要遵守类的命名约定。在这种情况下 UserNotifier 这个名字对吗 app/notifiers/user_notifier.rb .
该文件user_notifier.rb方法如何可用于用户模型?

  1. # app/models/application_record.rb
  2. class ApplicationRecord < ActiveRecord::Base
  3. # your code
  4. def send_notification(notification_name, recipients)
  5. notifier = "#{self.class.name}Notifier".constantize.new()
  6. send(notification_name, recipients)
  7. end
  8. end
  9. # app/models/user.rb
  10. class User < ApplicationRecord
  11. # your code
  12. # a method where you want to send a notification
  13. def foo
  14. send_notification(:reminder, [id])
  15. end
  16. end
  17. # app/notifiers/user_notifier.rb
  18. class UserNotifier < ApplicationNotifier
  19. def reminder(recipients)
  20. {
  21. type: 'sms',
  22. content: 'hi everyone',
  23. recipients: recipients
  24. }
  25. end
  26. end
展开查看全部
vxf3dgd4

vxf3dgd42#

多亏了léonard,他发布了解决方案,但在编写gem时,我们需要从gem处理这些配置。因为当有人使用我们的gem时,他/她不必手动在application_record.rb中编写任何与配置相关的逻辑。
发布它只是为了确保将来它可能对其他人有所帮助。
我是如何解决这个问题的(为了将gem附加到一个模型中,我们在希望配置它的模型中添加了act_as_notifier)
在通知程序gem的model_config.rb类中
拥有@model_类并查找相应的通知程序类
在通知程序类中添加attr_访问器,并用model对象初始化它
还定义自定义getter和setters通知程序属性

  1. # rails_notifier/model_config.rb
  2. def initialize(model_class)
  3. @model_class = model_class
  4. # get model corresponding notifier class
  5. # for User model class, there would UserNotifier class
  6. # under notifiers folder of app directory
  7. # getting notitifer class name
  8. notifier_class = "#{@model_class.name}Notifier"
  9. # Notifier class attribute set later set with model object
  10. attribute_name = @model_class.name.underscore
  11. # register a `notifier` method in model class
  12. # 'method_name' is a method of notifier class
  13. # and options hash contain sender
  14. @model_class.class_eval do
  15. define_method(:notifier) do |method_name, options|
  16. # create notifier class object
  17. notifier_ = notifier_class.constantize.new
  18. # define setter for notifier attribute
  19. notifier_.send(:define_singleton_method, "#{attribute_name}=".to_sym) do |value|
  20. instance_variable_set("@" + attribute_name.to_s, value)
  21. end
  22. # define getter for notifier attribute
  23. notifier_.send(:define_singleton_method, attribute_name.to_sym) do
  24. instance_variable_get("@" + attribute_name.to_s)
  25. end
  26. # self point to the object of model
  27. # e.g User.last.notifier(:send_reminder), slef = User.last
  28. # set notifier attribute with model object
  29. notifier_.send("#{attribute_name}=".to_sym, self)
  30. notifier_hash = notifier_.send(method_name)
  31. RailsNotifier.notify(notifier_hash) if notifier_hash.present?
  32. end
  33. end
  34. end
展开查看全部

相关问题