adequate_exposure 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 331663a8f718896cab6be3800c0af9fc98379e8b
4
- data.tar.gz: e942a3866cdd940adf9dd9e08e979b68b8456446
3
+ metadata.gz: 15f771dd9996bd2a1920e2f00dbc487e568d84ce
4
+ data.tar.gz: 9db2690bceba1225904077e793d780813f968774
5
5
  SHA512:
6
- metadata.gz: 4ce222e1500bce49ee95bc6eec47bc7f4956591070fba3b9acf5e5a3e3585296da02c79bb82c6532e65acf7049e39833709e8efe8032a8de58b18a6da26eaf59
7
- data.tar.gz: 9e292f24fbf0242ee15b8bb41483a2aa73def2316373612645d94c99592430c31ba41bfc3be9d243326e29f5ee62084ec7e408b3da4b12a5201dd07dcf7645d2
6
+ metadata.gz: e5cbf18ca89f1b543a5ef99f19059beb805991238219835d827d2090b387bfb5c8c832b10a911f287f88f4bb274ca041e3353b13d91b17e71eb544e6b12c5ee6
7
+ data.tar.gz: e97dc7d95fe518d7b19a9e93ffd978240eb11de1a1ab6499777c15e6e548c36b581107eaf510e1a959929b4e4f3228da79a3b2402f84c4cef8f577b9afcef477
data/README.md CHANGED
@@ -17,7 +17,8 @@ that down we can start talking about the API.
17
17
 
18
18
  ## API
19
19
 
20
- The whole API consists of two methods so far: `expose` and `expose!`.
20
+ The whole API consists of three methods so far: `expose`, `expose!`, and
21
+ `exposure_config`.
21
22
 
22
23
  In the simplest scenario you'll just use it to expose a model in the
23
24
  controller:
@@ -33,7 +34,7 @@ ID and try to perform `Thing.find(id)`. If the ID isn't found, it'll call
33
34
  `Thing.new(things_params)`. The result will be memoized in an `@exposed_thing`
34
35
  instance variable.
35
36
 
36
- The default resolving workflow if pretty powerful and customizable. It could be
37
+ The default resolving workflow is pretty powerful and customizable. It could be
37
38
  expressed with the following pseudocode:
38
39
 
39
40
  ```ruby
@@ -108,7 +109,7 @@ Or if you (like me) absolutely hate parens in side-effect methods:
108
109
  expose :thing, ->{ get_thing_some_way_or_another }
109
110
  ```
110
111
 
111
- There is another shortcut that allows you to redefine entire fetch block with
112
+ There is another shortcut that allows you to redefine the entire fetch block with
112
113
  less code:
113
114
 
114
115
  ```ruby
@@ -120,7 +121,7 @@ expose :comments, ->{ post.comments }
120
121
  ### `id`
121
122
 
122
123
  The default fetch logic relies on the presence of an ID. And of course Adequate
123
- Exposure allows to to specify how exactly you want the ID to be extracted.
124
+ Exposure allows you to specify how exactly you want the ID to be extracted.
124
125
 
125
126
  Default behavior could be expressed using following code:
126
127
 
@@ -136,15 +137,17 @@ But nothing is stopping you from throwing in any arbitrary code:
136
137
  expose :thing, id: ->{ 42 }
137
138
  ```
138
139
 
139
- Passing lambdas might not always be fun, so here are couple shortcuts that could
140
- help making life easier.
140
+ Passing lambdas might not always be fun, so here are a couple of shortcuts that could
141
+ help make life easier.
141
142
 
142
143
  ```ruby
143
- # equivalent to id: ->{ params[:custom_thing_id] }
144
144
  expose :thing, id: :custom_thing_id
145
+ # equivalent to
146
+ expose :thing, id: ->{ params[:custom_thing_id] }
145
147
 
146
- # equivalent to id: ->{ params[:try_this_id] || params[:or_maybe_that_id] }
147
148
  expose :thing, id: [:try_this_id, :or_maybe_that_id]
149
+ # equivalent to
150
+ expose :thing, id: ->{ params[:try_this_id] || params[:or_maybe_that_id] }
148
151
  ```
149
152
 
150
153
  ### `find`
@@ -160,7 +163,7 @@ Where `scope` is a model scope, like `Thing` or `User.active` or
160
163
  `Post.published`.
161
164
 
162
165
  Now, if you're using FriendlyId or Stringex or something similar, you'd have to
163
- customize your finding logic. You code might look somewhat like this:
166
+ customize your finding logic. Your code might look somewhat like this:
164
167
 
165
168
  ```ruby
166
169
  expose :thing, find: ->(id, scope){ scope.find_by!(slug: id) }
@@ -184,10 +187,10 @@ expose :thing, build: ->(thing_params, scope){ scope.new(thing_params) }
184
187
 
185
188
  ### `build_params`
186
189
 
187
- This options is responsible for calulating params before passing it to the
190
+ These options are responsible for calulating params before passing them to the
188
191
  build step. The default behavior was modeled with Strong Parameters in mind and
189
- is somewhat smart: it calls `thing_params` controller method if it's available
190
- and request method it not `GET`. In all other cases it produces an empty hash.
192
+ is somewhat smart: it calls the `thing_params` controller method if it's available
193
+ and the request method it not `GET`. In all other cases it produces an empty hash.
191
194
 
192
195
  You can easily specify which controller method you want it to call instead of
193
196
  `thing_params`, or just provide your own logic:
@@ -217,7 +220,7 @@ Like before, shortcuts are there to make you happier:
217
220
 
218
221
  ```ruby
219
222
  expose :post, scope: :published
220
- # fully equivalent to
223
+ # equivalent to
221
224
  expose :post, scope: ->{ Post.published }
222
225
  ```
223
226
 
@@ -225,13 +228,13 @@ and
225
228
 
226
229
  ```ruby
227
230
  expose :thing, parent: :current_user
228
- # fully equivalent to:
231
+ # equivalent to:
229
232
  expose :thing, scope: ->{ current_user.things }
230
233
  ```
231
234
 
232
235
  ### `model`
233
236
 
234
- Allows to specify the model class to use. Pretty straightforward.
237
+ Allows you to specify the model class to use. Pretty straightforward.
235
238
 
236
239
  ```ruby
237
240
  expose :thing, model: ->{ AnotherThing }
@@ -250,6 +253,20 @@ that:
250
253
  expose :thing, decorate: ->(thing){ ThingDecorator.new(thing) }
251
254
  ```
252
255
 
256
+ ## `exposure_config`
257
+
258
+ You can pre-save some configuration using `exposure_config` method reuse it
259
+ later.
260
+
261
+ ```ruby
262
+ exposure_config :cool_find, find: ->{ very_cool_find_code }
263
+ exposure_config :cool_build, build: ->{ very_cool_build_code }
264
+
265
+ expose :thing, with: [:cool_find, :cool_build]
266
+ expose :another_thing, with: :cool_build
267
+ ```
268
+
269
+
253
270
  ## Contributing
254
271
 
255
272
  1. Fork it (https://github.com/rwz/adequate_exposure/fork)
@@ -1,12 +1,23 @@
1
1
  module AdequateExposure
2
2
  module Controller
3
- def expose(*args, &block)
4
- Exposure.expose! self, *args, &block
5
- end
3
+ extend ActiveSupport::Concern
4
+
5
+ included{ class_attribute :exposure_configuration }
6
+
7
+ module ClassMethods
8
+ def expose(*args, &block)
9
+ Exposure.expose! self, *args, &block
10
+ end
11
+
12
+ def expose!(name, *args, &block)
13
+ expose name, *args, &block
14
+ before_action name
15
+ end
6
16
 
7
- def expose!(name, *args, &block)
8
- expose name, *args, &block
9
- before_action name
17
+ def exposure_config(name, options)
18
+ store = self.exposure_configuration ||= {}
19
+ self.exposure_configuration = store.merge(name => options)
20
+ end
10
21
  end
11
22
  end
12
23
  end
@@ -41,12 +41,51 @@ module AdequateExposure
41
41
  end
42
42
 
43
43
  def normalize_options
44
+ normalize_with_option
45
+ normalize_id_option
46
+ normalize_model_option
47
+ normalize_build_params_option
48
+ normalize_scope_options
49
+ normalize_parent_option
50
+ normalize_from_option
51
+ normalize_find_by_option
52
+ end
53
+
54
+ def normalize_find_by_option
55
+ if find_by = options.delete(:find_by)
56
+ merge_lambda_option :find, ->(id, scope){ scope.find_by!(find_by => id) }
57
+ end
58
+ end
59
+
60
+ def normalize_parent_option
61
+ exposure_name = options.fetch(:name)
62
+
63
+ if parent = options.delete(:parent)
64
+ merge_lambda_option :scope, ->{ send(parent).send(exposure_name.to_s.pluralize) }
65
+ end
66
+ end
67
+
68
+ def normalize_from_option
44
69
  exposure_name = options.fetch(:name)
45
70
 
71
+ if from = options.delete(:from)
72
+ merge_lambda_option :fetch, ->{ send(from).send(exposure_name) }
73
+ end
74
+ end
75
+
76
+ def normalize_with_option
77
+ if configs = options.delete(:with)
78
+ Array.wrap(configs).each{ |config| reverse_merge_config! config }
79
+ end
80
+ end
81
+
82
+ def normalize_id_option
46
83
  normalize_non_proc_option :id do |ids|
47
84
  ->{ Array.wrap(ids).map{ |id| params[id] }.find(&:present?) }
48
85
  end
86
+ end
49
87
 
88
+ def normalize_model_option
50
89
  normalize_non_proc_option :model do |value|
51
90
  model = if [String, Symbol].include?(value.class)
52
91
  value.to_s.classify.constantize
@@ -56,27 +95,19 @@ module AdequateExposure
56
95
 
57
96
  ->{ model }
58
97
  end
98
+ end
59
99
 
100
+ def normalize_build_params_option
60
101
  normalize_non_proc_option :build_params do |value|
61
102
  options[:build_params_method] = value
62
103
  nil
63
104
  end
105
+ end
64
106
 
107
+ def normalize_scope_options
65
108
  normalize_non_proc_option :scope do |custom_scope|
66
109
  ->(model){ model.send(custom_scope) }
67
110
  end
68
-
69
- if parent = options.delete(:parent)
70
- merge_lambda_option :scope, ->{ send(parent).send(exposure_name.to_s.pluralize) }
71
- end
72
-
73
- if from = options.delete(:from)
74
- merge_lambda_option :fetch, ->{ send(from).send(exposure_name) }
75
- end
76
-
77
- if find_by = options.delete(:find_by)
78
- merge_lambda_option :find, ->(id, scope){ scope.find_by!(find_by => id) }
79
- end
80
111
  end
81
112
 
82
113
  def normalize_non_proc_option(name)
@@ -127,5 +158,10 @@ module AdequateExposure
127
158
  fail ArgumentError, "Using #{name.inspect} option with other options doesn't make sense"
128
159
  end
129
160
  end
161
+
162
+ def reverse_merge_config!(name)
163
+ config = controller.exposure_configuration.fetch(name)
164
+ options.reverse_merge! config
165
+ end
130
166
  end
131
167
  end
@@ -1,3 +1,3 @@
1
1
  module AdequateExposure
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -8,6 +8,6 @@ module AdequateExposure
8
8
  autoload :Flow, "adequate_exposure/flow"
9
9
 
10
10
  ActiveSupport.on_load :action_controller do
11
- extend Controller
11
+ include Controller
12
12
  end
13
13
  end
@@ -14,7 +14,7 @@ describe AdequateExposure::Controller do
14
14
 
15
15
  let(:controller_klass) do
16
16
  Class.new(BaseController) do
17
- extend AdequateExposure::Controller
17
+ include AdequateExposure::Controller
18
18
  end
19
19
  end
20
20
 
@@ -22,7 +22,7 @@ describe AdequateExposure::Controller do
22
22
  let(:controller){ controller_klass.new }
23
23
  before{ allow(controller).to receive(:request){ request } }
24
24
 
25
- %w[expose expose!].each do |method_name|
25
+ %w[expose expose! exposure_config].each do |method_name|
26
26
  define_method method_name do |*args, &block|
27
27
  controller_klass.send method_name, *args, &block
28
28
  end
@@ -54,6 +54,45 @@ describe AdequateExposure::Controller do
54
54
  end
55
55
  end
56
56
 
57
+ context ".exposure_config" do
58
+ it "subclass configration doesn't propagate to superclass" do
59
+ controller_subklass = Class.new(controller_klass)
60
+ controller_klass.exposure_config :foo, :bar
61
+ controller_subklass.exposure_config :foo, :lol
62
+ controller_subklass.exposure_config :fizz, :buzz
63
+ expect(controller_subklass.exposure_configuration).to eq(foo: :lol, fizz: :buzz)
64
+ expect(controller_klass.exposure_configuration).to eq(foo: :bar)
65
+ end
66
+
67
+ context "applying" do
68
+ let(:thing){ double("Thing") }
69
+
70
+ before do
71
+ exposure_config :sluggable, find_by: :slug
72
+ exposure_config :weird_id_name, id: :check_this_out
73
+ exposure_config :another_id_name, id: :whee
74
+ controller.params.merge! check_this_out: "foo", whee: "wut"
75
+ end
76
+
77
+ after{ expect(controller.thing).to eq(thing) }
78
+
79
+ it "can be reused later" do
80
+ expose :thing, with: :weird_id_name
81
+ expect(Thing).to receive(:find).with("foo").and_return(thing)
82
+ end
83
+
84
+ it "can apply multple configs at once" do
85
+ expose :thing, with: [:weird_id_name, :sluggable]
86
+ expect(Thing).to receive(:find_by!).with(slug: "foo").and_return(thing)
87
+ end
88
+
89
+ it "applies multiple configs in a correct order" do
90
+ expose :thing, with: [:another_id_name, :weird_id_name]
91
+ expect(Thing).to receive(:find).with("wut").and_return(thing)
92
+ end
93
+ end
94
+ end
95
+
57
96
  context "with block" do
58
97
  before{ expose(:thing){ compute_thing } }
59
98
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adequate_exposure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Pravosud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-09 00:00:00.000000000 Z
11
+ date: 2014-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties