因此,我们的目标是将来自班级的"ProductCustomer"
转变为"product customer"
。
我以前有这个:
notification.notifiable.model_name.human.downcase
它当然没有用,因为如果notifiable
是nil
它会中断。我没有
想使用try
或类似内容,因为可以使用notifiable_type
来解决。
所以现在我改为:
notification.notifiable_type.split(/(?=[A-Z])/).join(' ').downcase
但是这在视图中每次使用都太复杂了。所以要么我想将它定义为一个视图助手,要么使用一些ruby格式化方法,如果有一个简单的。
在这种情况下,有人可以告诉我Rails惯例是什么吗?如果它是一个帮手,该方法是怎样的,我应该把它放在哪里?
答案 0 :(得分:2)
/your_app/config/initializers/my_initializer.rb
module MyModule
def human_model_name
self.class.to_s.tableize.singularize.humanize.downcase
end
end
ActiveRecord::Base.send(:include, MyModule)
在MyModule
中添加ActiveRecord::Base
会在所有human_model_name
个实例中添加ActiveRecord
。所以,你将能够......
user.human_model_name #=> user
notification.human_model_name #=> notification
notification.notifiable.human_model_name #=> product customer
any_active_record_instance.human_model_name #=> etc.
为避免notifiable
为nil
时出现异常,您可以使用try
方法。
notification.try(:notifiable).try(:human_model_name)
更简洁的方法可以使用delegate
class Notification < ActiveRecord::Base
delegate :human_model_name, to: :notifiable, prefix: true, allow_nil: true
end
然后,你可以这样做:
notification.notifiable_human_model_name # if notifiable is nil will return nil as result instead of an exception
Notification
模型class Notification < ActiveRecord::Base
def human_notifable_name
return unless self.notifiable # to avoid exception with nil notifiable
self.notifiable.class.to_s.tableize.singularize.humanize.downcase
end
end
则...
notification.human_notifable_name
module ApplicationHelper # or NotificationHelper
def human_model_name(instance)
return unless instance # to avoid exception with nil instance
instance.class.to_s.tableize.singularize.humanize.downcase
end
end
然后,在你看来......
<%= human_model_name(notification.notifiable) %>
两种选择都没问题。我会根据具体情况使用其中一种。在这种情况下,我会使用第一个选项。我认为您正在添加在任何模型中都很有用的行为。我的意思是你的方法与通知没有直接关系。以更通用的方式,您希望方法返回ActiveRecord实例的类名。今天,您需要notifiable
ActiveRecord
实例的模型名称。但是,明天您可能需要任何ActiveRecord
模型的型号名称。
回答问题“我应该在哪里放一个方法?”我建议稍微破解(不用担心)MVC模式并阅读:
(有点旧,但你可以得到这个想法)
答案 1 :(得分:1)
"ProductCustomer".tableize.singularize.humanize.downcase