我有许多具有属性的模型,我需要在阅读时应用一些新行为。我是Ruby / Rails的新手,所以我现在只是为一个属性定义一个getter并在其上面应用我的功能(类似于亵渎过滤的东西),但是我要去为一个很多的对象/属性做这个,并希望更清洁。
例如,对于Post
对象的body
属性,这就是我现在完成的方式:
class Post < ActiveRecord::Base
include Replaceable
#...
# A key point is that we want to keep the original content in the db
def body
profanity_filter(self[:body])
end
end
......我的担忧看起来像这样:
module Replaceable
extend ActiveSupport::Concern
def profanity_filter(content)
# filter and update content...
content
end
end
这很有效,我很满意,除了现在我必须将它应用到整个应用程序的许多领域,而且我喜欢比在任何地方覆盖吸气剂更优雅的东西。
我调查了代表,以便我可以做一些像
这样的事情delegate :body, :title, :etc, :to => :profanity_filter
...但这不起作用,因为我无法传递需要过滤的内容。
任何帮助将不胜感激!
答案 0 :(得分:1)
这是实现自己的类宏的最佳时机。
我将重用你的Replaceable
模块来定义这个宏。
首先,让我们看看宏看起来像什么。
class Post < ActiveRecord::Base
include Replaceable
profanity_attrs :body, :foo, :bar, ...
end
然后我们实施它
module Replaceable
extend ActiveSupport::Concern
def profanity_filter(content)
# filter and update content...
content
end
# This module will be `extend`ed by the model classes
module Macro
def profanity_attrs(attributes)
# Note the implicit `self` here refer to the model class
attributes.each do |attr|
class_eval do
define_method(attr) do
# Note the `self` here refer to the model instance
profanity_filter(self[attr])
end
end
end
end
end
included do
extend Macro
end
end
P.S。我真的不知道profanity
的含义,所以随意更改宏的名称:)