adequate_exposure 0.0.5 → 0.0.6

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 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