draper 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -0
- data/CONTRIBUTING.md +5 -1
- data/Gemfile +23 -9
- data/README.md +144 -52
- data/Rakefile +1 -0
- data/draper.gemspec +1 -1
- data/lib/draper.rb +9 -6
- data/lib/draper/decoratable.rb +3 -7
- data/lib/draper/decoratable/equality.rb +14 -0
- data/lib/draper/decorator.rb +4 -7
- data/lib/draper/helper_proxy.rb +22 -3
- data/lib/draper/test/devise_helper.rb +18 -22
- data/lib/draper/test/rspec_integration.rb +4 -0
- data/lib/draper/test_case.rb +20 -0
- data/lib/draper/version.rb +1 -1
- data/lib/draper/view_context.rb +75 -13
- data/lib/draper/view_context/build_strategy.rb +48 -0
- data/lib/draper/view_helpers.rb +2 -2
- data/spec/draper/collection_decorator_spec.rb +169 -196
- data/spec/draper/decoratable/equality_spec.rb +10 -0
- data/spec/draper/decoratable_spec.rb +107 -132
- data/spec/draper/decorated_association_spec.rb +99 -96
- data/spec/draper/decorator_spec.rb +408 -434
- data/spec/draper/finders_spec.rb +160 -126
- data/spec/draper/helper_proxy_spec.rb +38 -8
- data/spec/draper/view_context/build_strategy_spec.rb +116 -0
- data/spec/draper/view_context_spec.rb +154 -0
- data/spec/draper/view_helpers_spec.rb +4 -37
- data/spec/dummy/app/controllers/posts_controller.rb +7 -0
- data/spec/dummy/app/decorators/post_decorator.rb +26 -2
- data/spec/dummy/app/helpers/application_helper.rb +3 -0
- data/spec/dummy/app/mailers/post_mailer.rb +10 -0
- data/spec/dummy/app/models/admin.rb +5 -0
- data/spec/dummy/app/models/mongoid_post.rb +5 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/views/posts/_post.html.erb +15 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/config/application.rb +9 -3
- data/spec/dummy/config/boot.rb +2 -7
- data/spec/dummy/config/environments/development.rb +2 -3
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +3 -4
- data/spec/dummy/config/initializers/secret_token.rb +1 -0
- data/spec/dummy/config/mongoid.yml +80 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/fast_spec/post_decorator_spec.rb +38 -0
- data/spec/dummy/lib/tasks/test.rake +11 -5
- data/spec/dummy/spec/decorators/devise_spec.rb +64 -0
- data/spec/dummy/spec/decorators/helpers_spec.rb +21 -0
- data/spec/dummy/spec/decorators/post_decorator_spec.rb +26 -6
- data/spec/dummy/spec/decorators/spec_type_spec.rb +7 -0
- data/spec/dummy/spec/decorators/view_context_spec.rb +22 -0
- data/spec/dummy/spec/mailers/post_mailer_spec.rb +10 -6
- data/spec/dummy/spec/models/mongoid_post_spec.rb +10 -0
- data/spec/dummy/spec/models/post_spec.rb +5 -5
- data/spec/dummy/spec/spec_helper.rb +1 -0
- data/spec/dummy/test/decorators/minitest/devise_test.rb +64 -0
- data/spec/dummy/test/decorators/minitest/helpers_test.rb +21 -0
- data/spec/dummy/{mini_test/mini_test_integration_test.rb → test/decorators/minitest/spec_type_test.rb} +9 -3
- data/spec/dummy/test/decorators/minitest/view_context_test.rb +24 -0
- data/spec/dummy/test/decorators/test_unit/devise_test.rb +64 -0
- data/spec/dummy/test/decorators/test_unit/helpers_test.rb +21 -0
- data/spec/dummy/test/decorators/test_unit/view_context_test.rb +24 -0
- data/spec/dummy/test/minitest_helper.rb +4 -0
- data/spec/dummy/test/test_helper.rb +3 -0
- data/spec/generators/decorator/decorator_generator_spec.rb +1 -0
- data/spec/integration/integration_spec.rb +31 -6
- data/spec/spec_helper.rb +32 -25
- data/spec/support/shared_examples/decoratable_equality.rb +40 -0
- data/spec/support/shared_examples/view_helpers.rb +39 -0
- metadata +56 -44
- data/spec/dummy/README.rdoc +0 -261
- data/spec/dummy/spec/decorators/rspec_integration_spec.rb +0 -19
- data/spec/support/action_controller.rb +0 -12
- data/spec/support/active_model.rb +0 -7
- data/spec/support/active_record.rb +0 -9
- data/spec/support/decorators/decorator_with_application_helper.rb +0 -25
- data/spec/support/decorators/namespaced_product_decorator.rb +0 -5
- data/spec/support/decorators/non_active_model_product_decorator.rb +0 -2
- data/spec/support/decorators/product_decorator.rb +0 -23
- data/spec/support/decorators/products_decorator.rb +0 -10
- data/spec/support/decorators/some_thing_decorator.rb +0 -2
- data/spec/support/decorators/specific_product_decorator.rb +0 -2
- data/spec/support/decorators/widget_decorator.rb +0 -2
- data/spec/support/models/namespaced_product.rb +0 -49
- data/spec/support/models/non_active_model_product.rb +0 -3
- data/spec/support/models/product.rb +0 -95
- data/spec/support/models/some_thing.rb +0 -5
- data/spec/support/models/uninferrable_decorator_model.rb +0 -3
- data/spec/support/models/widget.rb +0 -2
data/Rakefile
CHANGED
@@ -60,6 +60,7 @@ end
|
|
60
60
|
namespace "db" do
|
61
61
|
desc "Set up databases for integration testing"
|
62
62
|
task "setup" do
|
63
|
+
puts "Setting up databases"
|
63
64
|
run_in_dummy_app "rm -f db/*.sqlite3"
|
64
65
|
run_in_dummy_app "RAILS_ENV=development rake db:schema:load db:seed"
|
65
66
|
run_in_dummy_app "RAILS_ENV=production rake db:schema:load db:seed"
|
data/draper.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["jeff@casimircreative.com", "steve@steveklabnik.com"]
|
10
10
|
s.homepage = "http://github.com/drapergem/draper"
|
11
11
|
s.summary = "View Models for Rails"
|
12
|
-
s.description = "Draper adds
|
12
|
+
s.description = "Draper adds an object-oriented layer of presentation logic to your Rails apps."
|
13
13
|
s.rubyforge_project = "draper"
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/draper.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'action_view'
|
2
|
+
require 'active_model/serialization'
|
3
|
+
require 'active_support/inflector'
|
4
|
+
require 'active_support/core_ext/hash/keys'
|
5
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
2
6
|
|
3
7
|
require 'draper/version'
|
4
8
|
require 'draper/view_helpers'
|
@@ -15,17 +19,16 @@ require 'draper/view_context'
|
|
15
19
|
require 'draper/collection_decorator'
|
16
20
|
require 'draper/railtie' if defined?(Rails)
|
17
21
|
|
18
|
-
require 'active_support/core_ext/hash/keys'
|
19
|
-
|
20
22
|
module Draper
|
21
23
|
def self.setup_action_controller(base)
|
22
24
|
base.class_eval do
|
23
25
|
include Draper::ViewContext
|
24
26
|
extend Draper::HelperSupport
|
25
|
-
|
26
|
-
|
27
|
-
Draper::ViewContext.
|
28
|
-
|
27
|
+
|
28
|
+
before_filter do |controller|
|
29
|
+
Draper::ViewContext.clear!
|
30
|
+
Draper::ViewContext.controller = controller
|
31
|
+
end
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
data/lib/draper/decoratable.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'draper/decoratable/equality'
|
2
|
+
|
1
3
|
module Draper
|
2
4
|
# Provides shortcuts to decorate objects directly, so you can do
|
3
5
|
# `@product.decorate` instead of `ProductDecorator.new(@product)`.
|
@@ -7,6 +9,7 @@ module Draper
|
|
7
9
|
# plain old Ruby objects, you can include it manually.
|
8
10
|
module Decoratable
|
9
11
|
extend ActiveSupport::Concern
|
12
|
+
include Draper::Decoratable::Equality
|
10
13
|
|
11
14
|
# Decorates the object using the inferred {#decorator_class}.
|
12
15
|
# @param [Hash] options
|
@@ -40,13 +43,6 @@ module Draper
|
|
40
43
|
false
|
41
44
|
end
|
42
45
|
|
43
|
-
# Compares with possibly-decorated objects.
|
44
|
-
#
|
45
|
-
# @return [Boolean]
|
46
|
-
def ==(other)
|
47
|
-
super || (other.respond_to?(:source) && self == other.source)
|
48
|
-
end
|
49
|
-
|
50
46
|
module ClassMethods
|
51
47
|
|
52
48
|
# Decorates a collection of objects. Used at the end of a scope chain.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Draper
|
2
|
+
module Decoratable
|
3
|
+
module Equality
|
4
|
+
# Compares self with a possibly-decorated object.
|
5
|
+
#
|
6
|
+
# @return [Boolean]
|
7
|
+
def ==(other)
|
8
|
+
super ||
|
9
|
+
other.respond_to?(:decorated?) && other.decorated? &&
|
10
|
+
other.respond_to?(:source) && self == other.source
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/draper/decorator.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'active_support/core_ext/array/extract_options'
|
2
|
-
|
3
1
|
module Draper
|
4
2
|
class Decorator
|
5
3
|
include Draper::ViewHelpers
|
6
4
|
extend Draper::Delegation
|
7
|
-
include ActiveModel::Serialization
|
5
|
+
include ActiveModel::Serialization
|
8
6
|
|
9
7
|
# @return the object being decorated.
|
10
8
|
attr_reader :source
|
@@ -27,7 +25,6 @@ module Draper
|
|
27
25
|
# methods.
|
28
26
|
def initialize(source, options = {})
|
29
27
|
options.assert_valid_keys(:context)
|
30
|
-
source.to_a if source.respond_to?(:to_a) # forces evaluation of a lazy query from AR
|
31
28
|
@source = source
|
32
29
|
@context = options.fetch(:context, {})
|
33
30
|
handle_multiple_decoration(options) if source.instance_of?(self.class)
|
@@ -159,11 +156,11 @@ module Draper
|
|
159
156
|
true
|
160
157
|
end
|
161
158
|
|
162
|
-
#
|
159
|
+
# Compares the source with a possibly-decorated object.
|
163
160
|
#
|
164
161
|
# @return [Boolean]
|
165
162
|
def ==(other)
|
166
|
-
source
|
163
|
+
source.extend(Draper::Decoratable::Equality) == other
|
167
164
|
end
|
168
165
|
|
169
166
|
# Checks if `self.kind_of?(klass)` or `source.kind_of?(klass)`
|
@@ -191,7 +188,7 @@ module Draper
|
|
191
188
|
end
|
192
189
|
|
193
190
|
# ActiveModel compatibility
|
194
|
-
delegate :to_param, :to_partial_path
|
191
|
+
delegate :attributes, :to_param, :to_partial_path
|
195
192
|
|
196
193
|
# ActiveModel compatibility
|
197
194
|
singleton_class.delegate :model_name, to: :source_class
|
data/lib/draper/helper_proxy.rb
CHANGED
@@ -3,15 +3,34 @@ module Draper
|
|
3
3
|
# defined in your application.
|
4
4
|
class HelperProxy
|
5
5
|
|
6
|
+
# @overload initialize(view_context)
|
7
|
+
def initialize(view_context = nil)
|
8
|
+
view_context ||= current_view_context # backwards compatibility
|
9
|
+
|
10
|
+
@view_context = view_context
|
11
|
+
end
|
12
|
+
|
6
13
|
# Sends helper methods to the view context.
|
7
14
|
def method_missing(method, *args, &block)
|
8
|
-
|
15
|
+
self.class.define_proxy method
|
16
|
+
send(method, *args, &block)
|
9
17
|
end
|
10
18
|
|
19
|
+
protected
|
20
|
+
|
21
|
+
attr_reader :view_context
|
22
|
+
|
11
23
|
private
|
12
24
|
|
13
|
-
def
|
14
|
-
|
25
|
+
def self.define_proxy(name)
|
26
|
+
define_method name do |*args, &block|
|
27
|
+
view_context.send(name, *args, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_view_context
|
32
|
+
ActiveSupport::Deprecation.warn("wrong number of arguments (0 for 1) passed to Draper::HelperProxy.new", caller[1..-1])
|
33
|
+
Draper::ViewContext.current.view_context
|
15
34
|
end
|
16
35
|
end
|
17
36
|
end
|
@@ -1,33 +1,29 @@
|
|
1
1
|
module Draper
|
2
2
|
module DeviseHelper
|
3
|
-
def sign_in(
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
def sign_in(resource_or_scope, resource = nil)
|
4
|
+
scope = begin
|
5
|
+
Devise::Mapping.find_scope!(resource_or_scope)
|
6
|
+
rescue RuntimeError => e
|
7
|
+
# Draper 1.0 didn't require the mapping to exist
|
8
|
+
ActiveSupport::Deprecation.warn("#{e.message}.\nUse `sign_in :user, mock_user` instead.", caller)
|
9
|
+
:user
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
@request ||= ::ActionDispatch::TestRequest.new
|
12
|
+
_stub_current_scope scope, resource || resource_or_scope
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
@controller.request = request
|
19
|
-
::Draper::ViewContext.current = @controller.view_context
|
20
|
-
@controller
|
15
|
+
def sign_out(resource_or_scope)
|
16
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
17
|
+
_stub_current_scope scope, nil
|
21
18
|
end
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
private
|
21
|
+
|
22
|
+
def _stub_current_scope(scope, resource)
|
23
|
+
Draper::ViewContext.current.controller.singleton_class.class_eval do
|
24
|
+
define_method "current_#{scope}" do
|
25
|
+
resource
|
29
26
|
end
|
30
|
-
request.env['warden'] = Warden::Proxy.new(request.env, manager)
|
31
27
|
end
|
32
28
|
end
|
33
29
|
end
|
@@ -8,5 +8,9 @@ module Draper
|
|
8
8
|
|
9
9
|
RSpec.configure do |config|
|
10
10
|
config.include DecoratorExampleGroup, example_group: {file_path: %r{spec/decorators}}, type: :decorator
|
11
|
+
|
12
|
+
[:decorator, :controller, :mailer].each do |type|
|
13
|
+
config.after(:each, type: type) { Draper::ViewContext.clear! }
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
data/lib/draper/test_case.rb
CHANGED
@@ -13,6 +13,13 @@ module Draper
|
|
13
13
|
end
|
14
14
|
|
15
15
|
class TestCase < active_support_test_case
|
16
|
+
module ViewContextTeardown
|
17
|
+
def teardown
|
18
|
+
super
|
19
|
+
Draper::ViewContext.clear!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
16
23
|
module Behavior
|
17
24
|
if defined?(::Devise)
|
18
25
|
require 'draper/test/devise_helper'
|
@@ -29,5 +36,18 @@ module Draper
|
|
29
36
|
end
|
30
37
|
|
31
38
|
include Behavior
|
39
|
+
include ViewContextTeardown
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if defined?(ActionController::TestCase)
|
44
|
+
class ActionController::TestCase
|
45
|
+
include Draper::TestCase::ViewContextTeardown
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if defined?(ActionMailer::TestCase)
|
50
|
+
class ActionMailer::TestCase
|
51
|
+
include Draper::TestCase::ViewContextTeardown
|
32
52
|
end
|
33
53
|
end
|
data/lib/draper/version.rb
CHANGED
data/lib/draper/view_context.rb
CHANGED
@@ -1,37 +1,99 @@
|
|
1
|
+
require 'draper/view_context/build_strategy'
|
1
2
|
require 'request_store'
|
2
3
|
|
3
4
|
module Draper
|
4
5
|
module ViewContext
|
6
|
+
# Hooks into a controller or mailer to save the view context in {current}.
|
5
7
|
def view_context
|
6
8
|
super.tap do |context|
|
7
9
|
Draper::ViewContext.current = context
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
# Returns the current controller.
|
14
|
+
def self.controller
|
15
|
+
RequestStore.store[:current_controller]
|
13
16
|
end
|
14
17
|
|
15
|
-
|
18
|
+
# Sets the current controller.
|
19
|
+
def self.controller=(controller)
|
16
20
|
RequestStore.store[:current_controller] = controller
|
17
21
|
end
|
18
22
|
|
23
|
+
# Returns the current view context, or builds one if none is saved.
|
24
|
+
#
|
25
|
+
# @return [HelperProxy]
|
19
26
|
def self.current
|
20
|
-
RequestStore.store
|
27
|
+
RequestStore.store.fetch(:current_view_context) { build! }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sets the current view context.
|
31
|
+
def self.current=(view_context)
|
32
|
+
RequestStore.store[:current_view_context] = Draper::HelperProxy.new(view_context)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Clears the saved controller and view context.
|
36
|
+
def self.clear!
|
37
|
+
RequestStore.store.delete :current_controller
|
38
|
+
RequestStore.store.delete :current_view_context
|
39
|
+
end
|
40
|
+
|
41
|
+
# Builds a new view context for usage in tests. See {test_strategy} for
|
42
|
+
# details of how the view context is built.
|
43
|
+
def self.build
|
44
|
+
build_strategy.call
|
45
|
+
end
|
46
|
+
|
47
|
+
# Builds a new view context and sets it as the current view context.
|
48
|
+
#
|
49
|
+
# @return [HelperProxy]
|
50
|
+
def self.build!
|
51
|
+
# send because we want to return the HelperProxy returned from #current=
|
52
|
+
send :current=, build
|
21
53
|
end
|
22
54
|
|
23
|
-
|
24
|
-
|
55
|
+
# Configures the strategy used to build view contexts in tests, which
|
56
|
+
# defaults to `:full` if `test_strategy` has not been called. Evaluates
|
57
|
+
# the block, if given, in the context of the view context's class.
|
58
|
+
#
|
59
|
+
# @example Pass a block to add helper methods to the view context:
|
60
|
+
# Draper::ViewContext.test_strategy :fast do
|
61
|
+
# include ApplicationHelper
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# @param [:full, :fast] name
|
65
|
+
# the strategy to use:
|
66
|
+
#
|
67
|
+
# `:full` - build a fully-working view context. Your Rails environment
|
68
|
+
# must be loaded, including your `ApplicationController`.
|
69
|
+
#
|
70
|
+
# `:fast` - build a minimal view context in tests, with no dependencies
|
71
|
+
# on other components of your application.
|
72
|
+
def self.test_strategy(name, &block)
|
73
|
+
@build_strategy = Draper::ViewContext::BuildStrategy.new(name, &block)
|
25
74
|
end
|
26
75
|
|
76
|
+
# @private
|
77
|
+
def self.build_strategy
|
78
|
+
@build_strategy ||= Draper::ViewContext::BuildStrategy.new(:full)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @deprecated Use {controller} instead.
|
82
|
+
def self.current_controller
|
83
|
+
ActiveSupport::Deprecation.warn("Draper::ViewContext.current_controller is deprecated (use controller instead)", caller)
|
84
|
+
self.controller || ApplicationController.new
|
85
|
+
end
|
86
|
+
|
87
|
+
# @deprecated Use {controller=} instead.
|
88
|
+
def self.current_controller=(controller)
|
89
|
+
ActiveSupport::Deprecation.warn("Draper::ViewContext.current_controller= is deprecated (use controller instead)", caller)
|
90
|
+
self.controller = controller
|
91
|
+
end
|
92
|
+
|
93
|
+
# @deprecated Use {build} instead.
|
27
94
|
def self.build_view_context
|
28
|
-
|
29
|
-
|
30
|
-
context.controller.request ||= ActionController::TestRequest.new
|
31
|
-
context.request ||= context.controller.request
|
32
|
-
context.params ||= {}
|
33
|
-
end
|
34
|
-
end
|
95
|
+
ActiveSupport::Deprecation.warn("Draper::ViewContext.build_view_context is deprecated (use build instead)", caller)
|
96
|
+
build
|
35
97
|
end
|
36
98
|
end
|
37
99
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Draper
|
2
|
+
module ViewContext
|
3
|
+
# @private
|
4
|
+
module BuildStrategy
|
5
|
+
|
6
|
+
def self.new(name, &block)
|
7
|
+
const_get(name.to_s.camelize).new(&block)
|
8
|
+
end
|
9
|
+
|
10
|
+
class Fast
|
11
|
+
def initialize(&block)
|
12
|
+
@view_context_class = Class.new(ActionView::Base, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
view_context_class.new
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :view_context_class
|
22
|
+
end
|
23
|
+
|
24
|
+
class Full
|
25
|
+
def initialize(&block)
|
26
|
+
@block = block
|
27
|
+
end
|
28
|
+
|
29
|
+
def call
|
30
|
+
controller.view_context.tap do |context|
|
31
|
+
context.singleton_class.class_eval(&block) if block
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :block
|
38
|
+
|
39
|
+
def controller
|
40
|
+
(Draper::ViewContext.controller || ApplicationController.new).tap do |controller|
|
41
|
+
controller.request ||= ActionController::TestRequest.new if defined?(ActionController::TestRequest)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/draper/view_helpers.rb
CHANGED
@@ -11,7 +11,7 @@ module Draper
|
|
11
11
|
#
|
12
12
|
# @return [HelperProxy] the helpers proxy
|
13
13
|
def helpers
|
14
|
-
|
14
|
+
Draper::ViewContext.current
|
15
15
|
end
|
16
16
|
alias_method :h, :helpers
|
17
17
|
|
@@ -22,7 +22,7 @@ module Draper
|
|
22
22
|
#
|
23
23
|
# @return [HelperProxy] the helpers proxy
|
24
24
|
def helpers
|
25
|
-
|
25
|
+
Draper::ViewContext.current
|
26
26
|
end
|
27
27
|
alias_method :h, :helpers
|
28
28
|
|