ker*_*lin 2 ruby methods ruby-on-rails
假设我有一个名为Article的模型:
class Article < ActiveRecord::Base
end
Run Code Online (Sandbox Code Playgroud)
然后我有一个用于向文章对象(装饰器)添加行为的类:
class ArticleDecorator
def format_title
end
end
Run Code Online (Sandbox Code Playgroud)
如果我想扩展一个文章对象的行为,我可以使ArticleDecorator成为一个模块,然后调用article.extend(ArticleDecorator),但我更喜欢这样的东西:
article = ArticleDecorator.decorate(Article.top_articles.first) # for single object
Run Code Online (Sandbox Code Playgroud)
要么
articles = ArticleDecorator.decorate(Article.all) # for collection of objects
Run Code Online (Sandbox Code Playgroud)
我将如何实现这种装饰方法?
你究竟想从decorate方法中得到什么?它应该只是为传递的对象添加一些新方法,还是应该使用相应的格式方法自动包装这些对象的方法?为什么你想ArticleDecorator成为一个班级而不仅仅是一个模块?
更新:
看起来像nathanvda的解决方案是你需要的,但我建议一个更清洁的版本:
module ArticleDecorator
def format_title
"#{title} [decorated]"
end
def self.decorate(object_or_objects_to_decorate)
object_or_objects_to_decorate.tap do |objects|
Array(objects).each { |obj| obj.extend ArticleDecorator }
end
end
end
Run Code Online (Sandbox Code Playgroud)
它做同样的事情,但是:
Kernel#Array方法检查参数的类型.Object#extend直接调用(这是一个公共方法,所以不需要调用它send).Object#extend仅包含实例方法,因此我们可以将它们直接放入,ArticleDecorator而不用另一个模块包装它们.| 归档时间: |
|
| 查看次数: |
1943 次 |
| 最近记录: |