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,
"\n Problem:\n You cannot decorate a Module\n Summary:\n Decoration only works with classes. Decorating modules requires\n managing load order, a problem that is very complicated and\n beyond the scope of this system.\n Resolution:\n Decorate multiple classes that include the module like so:\n `decorate Catalog::Product, Content::Page do`\n eos\n )\n end\n\n if target.name.to_s.end_with?('Helper')\n raise(\n InvalidDecorator,\n <<-eos.strip_heredoc\n\n Problem:\n Rails::Decorators doesn't work with helpers.\n Summary:\n Rails does some magic with helpers which in certain cases\n causes decoration to not work.\n Resolution:\n Create a new helper and in a `to_prepare` block, use\n ActionPack's `helper` method to include the helper, e.g.\n `MyEngine::ApplicationController.helper(MyEngine::BlogsHelper)`\n eos\n )\n end\n\n decorator_name = \"\#{options[:with].to_s.camelize}\#{target.to_s.demodulize}Decorator\"\n\n if target.const_defined?(decorator_name)\n # We are probably reloading in Rails development env if this happens\n next if !Rails.application.config.cache_classes\n\n raise(\n InvalidDecorator,\n <<-eos.strip_heredoc\n\n Problem:\n \#{decorator_name} is already defined in \#{target.name}.\n Summary:\n When decorating a class, Rails::Decorators dynamically defines\n a module for prepending the decorations passed in the block. In\n this case, the name for the decoration module is already defined\n in the namespace, so decorating would redefine the constant.\n Resolution:\n Please specify a unique `with` option when decorating \#{target.name}.\n eos\n )\n end\n\n mod = Module.new do\n extend Rails::Decorators::Decorator\n module_eval(&module_definition)\n end\n\n target.const_set(decorator_name, mod)\n mod.decorates(target)\n end\nend\n".strip_heredoc
|