14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/rails/decorators/decorator.rb', line 14
def self.decorate(*targets, &module_definition)
options = targets.
targets.each do |target|
unless target.is_a?(Class)
raise(
InvalidDecorator,
<<-eos.strip_heredoc
Problem:
You cannot decorate a Module
Summary:
Decoration only works with classes. Decorating modules requires
managing load order, a problem that is very complicated and
beyond the scope of this system.
Resolution:
Decorate multiple classes that include the module like so:
`decorate Catalog::Product, Content::Page do`
eos
)
end
if target.name.to_s.end_with?('Helper')
raise(
InvalidDecorator,
<<-eos.strip_heredoc
Problem:
Rails::Decorators doesn't work with helpers.
Summary:
Rails does some magic with helpers which in certain cases
causes decoration to not work.
Resolution:
Create a new helper and in a `to_prepare` block, use
ActionPack's `helper` method to include the helper, e.g.
`MyEngine::ApplicationController.helper(MyEngine::BlogsHelper)`
eos
)
end
decorator_name = "#{options[:with].to_s.camelize}#{target.to_s.demodulize}Decorator"
if target.const_defined?(decorator_name)
next if !Rails.application.config.cache_classes
raise(
InvalidDecorator,
<<-eos.strip_heredoc
Problem:
#{decorator_name} is already defined in #{target.name}.
Summary:
When decorating a class, Rails::Decorators dynamically defines
a module for prepending the decorations passed in the block. In
this case, the name for the decoration module is already defined
in the namespace, so decorating would redefine the constant.
Resolution:
Please specify a unique `with` option when decorating #{target.name}.
eos
)
end
mod = Module.new do
extend Rails::Decorators::Decorator
module_eval(&module_definition)
end
target.const_set(decorator_name, mod)
mod.decorates(target)
end
end
|