context_exposer 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +13 -1
- data/README.md +186 -16
- data/lib/context_exposer.rb +15 -0
- data/lib/context_exposer/base_controller.rb +67 -47
- data/lib/context_exposer/cached_resource_controller.rb +10 -0
- data/lib/context_exposer/integrations.rb +8 -0
- data/lib/context_exposer/integrations/base.rb +15 -0
- data/lib/context_exposer/integrations/key_filter.rb +30 -0
- data/lib/context_exposer/integrations/with_decent_exposure.rb +19 -0
- data/lib/context_exposer/integrations/with_decorates_before.rb +31 -0
- data/lib/context_exposer/integrations/with_instance_vars.rb +19 -0
- data/lib/context_exposer/macros.rb +17 -0
- data/lib/context_exposer/patch/decorates_before_rendering.rb +179 -0
- data/lib/context_exposer/rails_config.rb +3 -0
- data/lib/context_exposer/resource_controller.rb +30 -8
- data/lib/context_exposer/version.rb +1 -1
- data/lib/context_exposer/view_context.rb +1 -1
- data/spec/app/items_spec.rb +36 -0
- data/spec/app/posts_spec.rb +29 -1
- data/spec/context_exposer/expose_resource_spec.rb +51 -38
- data/spec/context_exposer/expose_spec.rb +11 -10
- data/spec/dummy/app/controllers/items_controller.rb +12 -0
- data/spec/dummy/app/controllers/posts_controller.rb +3 -4
- data/spec/dummy/app/views/items/index.html.erb +2 -0
- data/spec/dummy/app/views/items/show.html.erb +2 -0
- data/spec/dummy/app/views/posts/index.html.erb +2 -1
- data/spec/dummy/app/views/posts/show.html.erb +2 -1
- data/spec/dummy/config/initializers/context_exposer.rb +1 -0
- data/spec/dummy/config/routes.rb +1 -57
- data/spec/dummy/log/test.log +483 -0
- data/spec/dummy_spec_helper.rb +82 -0
- data/spec/spec_helper.rb +13 -1
- data/spec/support/decorators/base_decorator.rb +22 -0
- data/spec/support/decorators/item_decorator.rb +11 -0
- data/spec/support/decorators/post_decorator.rb +5 -0
- data/spec/support/models/base.rb +18 -0
- data/spec/support/models/base/clazz_methods.rb +29 -0
- data/spec/support/models/item.rb +9 -0
- data/spec/support/models/post.rb +5 -0
- metadata +38 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cff7846013a27d16f62e455b571af3336ea88531
|
4
|
+
data.tar.gz: d7b782a83befc4da2b8ffa9a145eff505734d303
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47926e8db084652454e11b10b82e949618809ed3a1b9141c98b5830dae93a5e771fe79aca837a7a1520062710b9c3fe5f4a7cf63366942048db414391b7e1f36
|
7
|
+
data.tar.gz: 191e35391a9271b9cc3a3dea8e2429fee8ebb0c6788ade0feb2f9c449303c280fc6bcf26c3d2bf3151db1dcc94db809fff341c87fcd9a91a0717a885785e7553
|
data/Gemfile
CHANGED
@@ -4,5 +4,17 @@ source 'https://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
gem 'rails', '>= 3.1'
|
7
|
+
gem "rspec", '>= 2.0', group: [:test, :development]
|
7
8
|
gem "rspec-rails", '>= 2.0', group: [:test, :development]
|
8
|
-
gem 'pry', group: [:development]
|
9
|
+
gem 'pry', group: [:development]
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem 'capybara', '>= 2.0'
|
13
|
+
gem 'spork-rails', '>= 3.0'
|
14
|
+
|
15
|
+
gem 'decent_exposure'
|
16
|
+
gem 'decorates_before_rendering', github: 'ohwillie/decorates_before_rendering'
|
17
|
+
|
18
|
+
# gem 'factory_girl_rails', '>= 3.0'
|
19
|
+
# gem 'database_cleaner', '>= 0.7'
|
20
|
+
end
|
data/README.md
CHANGED
@@ -7,6 +7,14 @@ No more pollution of the View with content helper methods or even worse, instanc
|
|
7
7
|
|
8
8
|
The Context object will by default be an instance of `ContextExposer::ViewContext`, but you can subclass this baseclass to add you own logic for more complex scenarios. This also allows for a more modular approach, where you can easily share or subclass logic between different view contexts. Nice!
|
9
9
|
|
10
|
+
The gem comes with integrations ready for easy migration or symbiosis with existing strategies (and gems), such as:
|
11
|
+
|
12
|
+
* exposing of instance variables (Rails default strategy)
|
13
|
+
* decent_exposure gem (expose methods)
|
14
|
+
* decorates_before_rendering gem (expose decorated instance vars)
|
15
|
+
|
16
|
+
For more on integration (and migration path) see below ;)
|
17
|
+
|
10
18
|
## Installation
|
11
19
|
|
12
20
|
Add this line to your application's Gemfile:
|
@@ -36,15 +44,44 @@ class PostsController < ActionController::Base
|
|
36
44
|
end
|
37
45
|
```
|
38
46
|
|
47
|
+
The view will have the methods exposed and available on the `ctx` object.
|
48
|
+
|
39
49
|
HAML view example
|
40
50
|
|
41
51
|
```haml
|
42
52
|
%h1 Posts
|
43
|
-
=
|
53
|
+
= ctx.posts.each do |post|
|
44
54
|
%h2 = post.name
|
45
55
|
```
|
46
56
|
|
47
|
-
You can also
|
57
|
+
You can also have the exposed methods automatically cache the result in an instance variable, by using the `expose_cached` variant.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class PostsController < ActionController::Base
|
61
|
+
include ContextExposer::BaseController
|
62
|
+
|
63
|
+
expose_cached(:post) { Post.find params[:id] }
|
64
|
+
expose_cached(:posts) { Post.find params[:id] }
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
This is especially useful if used in combination with `decorates_before_rendering`, which only works on cached objects.
|
69
|
+
|
70
|
+
## Macros
|
71
|
+
|
72
|
+
You can also choose to use the class macros made available on `ActionController::Base` as Rails loads.
|
73
|
+
|
74
|
+
Use `:base` or `resource` or your custom extension to include the ContextExposer controller module of your choice. The macro `context_exposer :base` is equivalent to writing `include ContextExposer::BaseController`
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
class PostsController < ActionController::Base
|
78
|
+
context_exposer :base
|
79
|
+
```
|
80
|
+
|
81
|
+
## Sublclassing and customizing the ViewContext
|
82
|
+
|
83
|
+
You can also define your own subclass of `ViewContext` and designate an instance of this custom class as your "exposed" target, via `view_ctx_class`method.
|
84
|
+
You can also override the class method of the same name for custom class name construction behavior ;)
|
48
85
|
|
49
86
|
Example:
|
50
87
|
|
@@ -52,10 +89,16 @@ Example:
|
|
52
89
|
class PostsController < ActionController::Base
|
53
90
|
include ContextExposer::BaseController
|
54
91
|
|
55
|
-
|
92
|
+
view_ctx_class :posts_view_context
|
56
93
|
|
57
|
-
|
58
|
-
exposed(:
|
94
|
+
# One model instance
|
95
|
+
exposed(:post) { Post.find params[:id] }
|
96
|
+
|
97
|
+
# Relation (for further scoping or lazy load)
|
98
|
+
exposed(:posts) { Post.all }
|
99
|
+
|
100
|
+
# Array of model instances
|
101
|
+
exposed(:posts_list) { Post.all.to_a }
|
59
102
|
end
|
60
103
|
```
|
61
104
|
|
@@ -90,7 +133,7 @@ HAML view example
|
|
90
133
|
|
91
134
|
```haml
|
92
135
|
%h1 Admin Posts
|
93
|
-
=
|
136
|
+
= ctx.admin_posts.each do |post|
|
94
137
|
%h2 = post.name
|
95
138
|
```
|
96
139
|
|
@@ -101,17 +144,26 @@ This approach opens up many new exciting ways to slice and dice your logic in a
|
|
101
144
|
|
102
145
|
### ResourceController
|
103
146
|
|
104
|
-
The `ResourceController` automatically sets up the typical singular and plural-form resource helpers.
|
147
|
+
The `ResourceController` automatically sets up the typical singular and plural-form resource helpers. For example for PostsController:
|
148
|
+
|
149
|
+
* `post` - one Post instance
|
150
|
+
* `posts` - Search Relatation (for lazy load or further scoping)
|
151
|
+
* `posts_list` - Array of Post instances
|
105
152
|
|
106
153
|
This simplifies the above `PostsController` example to this:
|
107
154
|
|
108
155
|
```ruby
|
109
156
|
class PostsController < ActionController::Base
|
157
|
+
# alternatively: context_exposer :resource
|
110
158
|
include ContextExposer::ResourceController
|
159
|
+
|
160
|
+
expose_resources :all
|
111
161
|
end
|
112
162
|
```
|
113
163
|
|
114
|
-
`
|
164
|
+
The macro `expose_resources` optionally takes a list of the types of resource you want to expose. Valid types are `:one`, `:many` and `:list` respectively (for fx: `post`, `posts` and `posts_list`).
|
165
|
+
|
166
|
+
`ContextExposer::ResourceController` uses the following internal logic for its default functionality. You can override these methods to customize your behavior as needed.
|
115
167
|
|
116
168
|
```ruby
|
117
169
|
module ContextExposer::ResourceController
|
@@ -132,22 +184,75 @@ module ContextExposer::ResourceController
|
|
132
184
|
end
|
133
185
|
```
|
134
186
|
|
135
|
-
|
187
|
+
Tip: You can create reusable module and then include your custom ResourceController.
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
module NamedResourceController
|
191
|
+
extend ActiveSupport::Concern
|
192
|
+
include ContextExposer::ResourceController
|
193
|
+
|
194
|
+
protected
|
195
|
+
|
196
|
+
def resource_id
|
197
|
+
params[:name]
|
198
|
+
end
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
class PostsController < ActionController::Base
|
204
|
+
include NamedResourceController
|
205
|
+
end
|
206
|
+
|
207
|
+
Tip: If you put your module inside the `ContextExposer` namespace, you can even use the `context_exposer` macro ;)
|
208
|
+
|
209
|
+
## Integrations with other exposure gems and patterns
|
210
|
+
|
211
|
+
You can use the class macro `integrate_with(name)` to integrate with either:
|
212
|
+
|
213
|
+
* decent_exposure - `integrate_with :decent_exposure`
|
214
|
+
* decorates_before_rendering - `integrate_with :decorates_before`
|
215
|
+
* instance vars - `integrate_with :instance_vars`
|
216
|
+
|
217
|
+
Note: You can even integrate with multiple strategies
|
136
218
|
|
137
|
-
|
219
|
+
`integrate_with :decent_exposure, :instance_vars`
|
220
|
+
|
221
|
+
You can also specify your integrations directly as part of your `context_exposer` call (recommended)
|
222
|
+
|
223
|
+
`context_exposer :base, with: :decent_exposure`
|
224
|
+
|
225
|
+
In case you use the usual (default) Rails pattern of passing instance variables, you can slowly migrate to exposing via `ctx` object, by adding a simple macro `context_expose :instance_vars` to your controller.
|
226
|
+
|
227
|
+
For decorated instance variables (see `decorates_before_rendering` gem), similarly use `context_expose :decorated_instance_vars`.
|
228
|
+
|
229
|
+
All of these `context_expose :xxxx` methods can optionally take an `:except` or `:only` option with a list of keys, similar to a `before_filter`.
|
230
|
+
|
231
|
+
The method `context_expose :decorated_instance_vars` can additionally take a `:for`option of either `:collection` or `:non_collection` to limit the type of instance vars exposed.
|
232
|
+
|
233
|
+
`context_expose` integration
|
234
|
+
|
235
|
+
* :instance_vars
|
236
|
+
* :decorated_instance_vars
|
237
|
+
* :decently
|
238
|
+
|
239
|
+
Here is a full example demonstrating integration with `decent_exposure`.
|
138
240
|
|
139
241
|
```ruby
|
140
242
|
# using gem 'decent_exposure'
|
141
243
|
# auto-included in ActionController::Base
|
142
244
|
|
143
245
|
class PostsController < ActionController::Base
|
144
|
-
|
246
|
+
# make context_expose_decently method available
|
247
|
+
context_exposer :base, with :decent_exposure
|
145
248
|
|
146
|
-
expose(:posts)
|
147
|
-
expose(:post)
|
148
|
-
expose(:postal)
|
249
|
+
expose(:posts) { Post.all.order(:created_at, :asc) }
|
250
|
+
expose(:post) { Post.first}
|
251
|
+
expose(:postal) { '1234' }
|
149
252
|
|
150
|
-
|
253
|
+
# mirror all methods exposed via #expose on #ctx object
|
254
|
+
# except for 'postal' method
|
255
|
+
context_expose :decently except: 'postal'
|
151
256
|
end
|
152
257
|
```
|
153
258
|
|
@@ -155,10 +260,75 @@ HAML view example
|
|
155
260
|
|
156
261
|
```haml
|
157
262
|
%h1 Posts
|
158
|
-
=
|
263
|
+
= ctx.posts.each do |post|
|
159
264
|
%h2 = post.name
|
160
265
|
```
|
161
266
|
|
267
|
+
## Decorates before rendering
|
268
|
+
|
269
|
+
A patch for the `decorates_before_render` gem is currently made available.
|
270
|
+
|
271
|
+
`ContextExposer.patch :decorates_before_rendering`
|
272
|
+
|
273
|
+
You typically use this in a Rails initializer. This way, `decorates_before_rendering` should try to decorate all your exposed variables before rendering, whether your view context is exposed as instance vars, methods or on the `ctx` object of the view ;)
|
274
|
+
|
275
|
+
Note: You can now also use the macro `decorates_before_render` to include the `DecoratesBeforeRendering` module.
|
276
|
+
|
277
|
+
### Auto-finding a decorator
|
278
|
+
|
279
|
+
For the patched version of `decorates_before_render` to work, your exposed and cached object must either have a `model_name` method that returns the name of the model name to be used to calculate the decorator name to use, or alternatively (and with higher precedence if present), a `decorator` method that takes the controller (self) as an argument and returns the full name of the decorator to use ;)
|
280
|
+
|
281
|
+
Example:
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
class PostsController < ActionController::Base
|
285
|
+
decorates_before_render
|
286
|
+
context_exposer :base, with :decent_exposure
|
287
|
+
|
288
|
+
expose_cached(:first_post) { Post.first }
|
289
|
+
|
290
|
+
protected
|
291
|
+
|
292
|
+
def admin?
|
293
|
+
@admin ||= current_user.admin?
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
class Post < ActiveRecord::Base
|
300
|
+
def decorator contrl
|
301
|
+
contrl.send(:admin?) ? 'Admin::PostDecorator' : model_name
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
### Auto-detection Error handling
|
306
|
+
|
307
|
+
If the auto-decoration can't find a decorator for an exposed variable (or method), it will either ignore it (not decorate it) or call `__handle_decorate_error_(error)` which by default will log a Rails warning. Override this error handler as it suits you.
|
308
|
+
|
309
|
+
## Testing
|
310
|
+
|
311
|
+
The tests have been written in rspec 2 and capybara.
|
312
|
+
The test suite consists of:
|
313
|
+
|
314
|
+
* Full app tests
|
315
|
+
* Units tests
|
316
|
+
|
317
|
+
### Dummy app feature tests
|
318
|
+
|
319
|
+
A Dummy app has been set up for use with Capybara feature testing.
|
320
|
+
Please see: http://alindeman.github.com/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html
|
321
|
+
|
322
|
+
The feature tests can be found in `spec/app`
|
323
|
+
|
324
|
+
`$ bundle exec rspec spec/context_exposer`
|
325
|
+
|
326
|
+
### Unit tests (specs)
|
327
|
+
|
328
|
+
The unit tests can be found in `spec/context_exposer`
|
329
|
+
|
330
|
+
`$ bundle exec rspec spec/context_exposer`
|
331
|
+
|
162
332
|
## Contributing
|
163
333
|
|
164
334
|
1. Fork it
|
data/lib/context_exposer.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
require "context_exposer/version"
|
2
2
|
|
3
3
|
module ContextExposer
|
4
|
+
def self.patch name
|
5
|
+
case name.to_sym
|
6
|
+
when :decorates_before_rendering
|
7
|
+
require "context_exposer/patch/#{name}"
|
8
|
+
else
|
9
|
+
raise ArgumentError, "No patch defined for: #{name}. Try one of #{patches}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.patches
|
14
|
+
[:decorates_before_rendering]
|
15
|
+
end
|
4
16
|
end
|
5
17
|
|
6
18
|
require "active_support"
|
7
19
|
require "context_exposer/base_controller"
|
8
20
|
require "context_exposer/resource_controller"
|
21
|
+
require "context_exposer/cached_resource_controller"
|
9
22
|
require "context_exposer/view_context"
|
23
|
+
require "context_exposer/macros"
|
24
|
+
require "context_exposer/rails_config"
|
@@ -1,51 +1,51 @@
|
|
1
|
+
require "context_exposer/integrations"
|
2
|
+
|
1
3
|
module ContextExposer::BaseController
|
2
4
|
extend ActiveSupport::Concern
|
5
|
+
include ContextExposer::Integrations::Base
|
3
6
|
|
4
7
|
included do
|
5
|
-
before_filter :configure_exposed_context
|
6
|
-
|
7
|
-
expose_context :context
|
8
|
+
# before_filter :configure_exposed_context
|
9
|
+
set_callback :process_action, :before, :configure_exposed_context
|
8
10
|
|
9
|
-
|
11
|
+
expose_context :ctx
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
@
|
14
|
+
def view_ctx
|
15
|
+
@view_ctx ||= build_view_ctx
|
14
16
|
end
|
15
|
-
alias_method :
|
17
|
+
alias_method :ctx, :view_ctx
|
16
18
|
|
17
19
|
module ClassMethods
|
18
|
-
def exposed name, &block
|
19
|
-
|
20
|
-
exposure_storage[name.to_sym] = block
|
20
|
+
def exposed name, options = {}, &block
|
21
|
+
_exposure_storage[name.to_sym] = {options: options, proc: block}
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
except = (options[:except] || {}).map(&:to_sym)
|
27
|
-
only = (options[:only] || {}).map(&:to_sym)
|
28
|
-
|
29
|
-
transfer_keys = transfer_keys - except
|
24
|
+
def expose_cached name, options = {}, &block
|
25
|
+
exposed name, options.merge(cached: true), &block
|
26
|
+
end
|
30
27
|
|
31
|
-
|
32
|
-
|
28
|
+
def view_ctx_class name
|
29
|
+
define_method :view_ctx_class do
|
30
|
+
@view_ctx_class ||= name.kind_of?(Class) ? name : name.to_s.camelize.constantize
|
33
31
|
end
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
34
|
+
def integrate_with *names
|
35
|
+
names.flatten.compact.each do |name|
|
36
|
+
self.send :include, "ContextExposer::Integrations::With#{name.to_s.camelize}".constantize
|
39
37
|
end
|
40
38
|
end
|
41
|
-
alias_method :
|
39
|
+
alias_method :integrates_with, :integrate_with
|
42
40
|
|
43
|
-
def
|
44
|
-
|
45
|
-
@view_context_class ||= name.kind_of?(Class) ? name : name.to_s.camelize.constantize
|
46
|
-
end
|
41
|
+
def context_expose name, options = {}
|
42
|
+
send "context_expose_#{name}", options
|
47
43
|
end
|
48
44
|
|
45
|
+
def _exposure_storage
|
46
|
+
_exposure_hash[self.to_s] ||= {}
|
47
|
+
end
|
48
|
+
|
49
49
|
protected
|
50
50
|
|
51
51
|
def expose_context name
|
@@ -59,32 +59,26 @@ module ContextExposer::BaseController
|
|
59
59
|
end
|
60
60
|
helper_method name
|
61
61
|
hide_action name
|
62
|
-
@
|
62
|
+
@_exposed_view_context = true
|
63
63
|
end
|
64
64
|
|
65
65
|
def exposed_view_context?
|
66
|
-
@
|
66
|
+
@_exposed_view_context == true
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
def exposure_hash
|
74
|
-
@exposure_hash ||= {}
|
75
|
-
end
|
69
|
+
def _exposure_hash
|
70
|
+
@_exposure_hash ||= {}
|
71
|
+
end
|
76
72
|
end
|
77
73
|
|
78
74
|
# must be called after Controller is instantiated
|
79
75
|
def configure_exposed_context
|
80
76
|
return if configured_exposed_context?
|
81
77
|
clazz = self.class
|
82
|
-
exposed_methods = clazz.send(:
|
83
|
-
exposed_methods.each do |name,
|
84
|
-
|
85
|
-
|
86
|
-
this.instance_eval(&procedure)
|
87
|
-
end
|
78
|
+
exposed_methods = clazz.send(:_exposure_hash)[clazz.to_s] || []
|
79
|
+
exposed_methods.each do |name, obj|
|
80
|
+
options = obj[:options] || {}
|
81
|
+
options[:cached] ? _add_cached_ctx_method(obj, name) : _add_ctx_method(obj, name)
|
88
82
|
end
|
89
83
|
@configured_exposed_context = true
|
90
84
|
end
|
@@ -95,13 +89,39 @@ module ContextExposer::BaseController
|
|
95
89
|
|
96
90
|
protected
|
97
91
|
|
92
|
+
def _add_ctx_method obj, name
|
93
|
+
this = self
|
94
|
+
proc = obj[:proc]
|
95
|
+
inst_var_name = "@#{name}"
|
96
|
+
|
97
|
+
view_ctx.send :define_singleton_method, name do
|
98
|
+
this.instance_eval(&proc)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def _add_cached_ctx_method obj, name
|
103
|
+
this = self
|
104
|
+
options = obj[:options]
|
105
|
+
proc = obj[:proc]
|
106
|
+
inst_var_name = "@#{name}"
|
107
|
+
|
108
|
+
view_ctx.send :define_singleton_method, name do
|
109
|
+
old_val = instance_variable_get inst_var_name
|
110
|
+
return old_val if old_val
|
111
|
+
|
112
|
+
val = this.instance_eval(&proc)
|
113
|
+
instance_variable_set inst_var_name, val
|
114
|
+
val
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
98
118
|
# returns a ViewContext object
|
99
119
|
# view helpers can be exposed as singleton methods, dynamically be attached (see below)
|
100
|
-
def
|
101
|
-
|
120
|
+
def build_view_ctx
|
121
|
+
view_ctx_class.new self
|
102
122
|
end
|
103
123
|
|
104
|
-
def
|
105
|
-
@
|
124
|
+
def view_ctx_class
|
125
|
+
@view_ctx_class ||= ContextExposer::ViewContext
|
106
126
|
end
|
107
127
|
end
|