pathway 0.6.1 → 0.6.2

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: 6e5314504a8dfd84cb2f31dd46586839df19b603
4
- data.tar.gz: c92541f944631c3b10fe3c91adaf7e31dc58a4ed
3
+ metadata.gz: 4018ba4c006cf059f12c711202755d036b98a5ce
4
+ data.tar.gz: 43aa4a956c419086daa4f3cb2c090ba59f6d2b66
5
5
  SHA512:
6
- metadata.gz: eca5cc01b6a9c6705f7518add28afb922bd275f5821adcff37c9fde237fba4d29be1474ad2258e5a5849b3936e610b60ef200a5a539c32f65638861267e1d2b1
7
- data.tar.gz: 2cd6000ff33eeb6e36a3b0fe22689d64dba3c4f91cc6916d55194e15ea1c084d8418ba38f742082d0fb47f18caf55c17d823bd2db2eae0d4c7da16ec8cfe978c
6
+ metadata.gz: 4b78616b14447e8577bec833efbc133badb5dd33f6ea0ac7ed118640efc72e9bb3d2c7eabfc0453dab40197567d609c14b786bc172e9c324b3a7967a58a554e5
7
+ data.tar.gz: a3603b314011b5650f722e63d5f2d7e744a545f0843936bef536dfd9b3a8aa75871da0d8a3fba043c7e8a3c624ac1dde3dafc0b8026b788f94b2e09ec597d5ab
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.6.2] - 2018-05-19
2
+ ### Changed
3
+ - Allow `:error_message` option for `sequel_models` plugin to propagate down inherited classes
4
+
1
5
  ## [0.6.1] - 2018-03-16
2
6
  ### Changed
3
7
  - Update default error message for `:fetch_model` step, at `sequel_models` plugin, to indicate the model's name
data/README.md CHANGED
@@ -199,26 +199,26 @@ Lets start by showing some actual code:
199
199
  ```
200
200
 
201
201
  To define your `call` method using the DSL just call to `process` and pass a block, inside it the DSL will be available.
202
- Each `step` (or `set`) call is referring to a method inside the operation class, superclasses or available through a plugin, these methods will be eventually invoked on `call`.
202
+ Each `step` (or `set`) call is referring to a method inside the operation class, superclasses or available through a plugin, these methods will be eventually invoked by `call`.
203
203
  All of the steps constitute the operation use case and follow a series of conventions in order to carry the process state along the execution process.
204
204
 
205
- When you run the `call` method, the auto-generated code will save the provided argument at the `input` key within the execution state. Subsequent steps will receive this state and will be able to update it, to set the result value or and auxiliary key to communicate with the next steps on the execution path.
205
+ When you run the `call` method, the auto-generated code will save the provided argument at the `input` key within the execution state. Subsequent steps will receive this state and will be able to modify it, setting the result value or auxiliary keys to communicate with the next steps on the execution path.
206
206
 
207
207
  Each step (as the operation as whole) can succeed of fail, when the latter happens execution is halted, and the operation `call` method returns immediately.
208
208
  To signal a failure you must return a `failure(...)` or `error(...)` in the same fashion as when defining `call` directly.
209
209
 
210
210
  If you return a `success(...)` or anything that's not a failure the execution carries on but the value is ignored. If you want to save the result value, you must use `set` instead of `step` at the process block, that will save your wrapped value, into the key provided at `to:`.
211
211
  Also non-failure return values inside steps are automatically wrapped so you can use `success` for clarity sake but it's optional.
212
- If you omit the `to:` keyword argument when defining a `set` step, the result key value will be used by default, but we'll explain more on that later.
212
+ If you omit the `to:` keyword argument when defining a `set` step, the result key will be used by default, but we'll explain more on that later.
213
213
 
214
214
  ##### Operation execution state
215
215
 
216
- In order to operate with the execution state, every step method receives a structure representing the current state. This structure is similar to a `Hash` and responds to its key methods (`:[]`, `:[]=`, `:fetch`, `:store` and `:include?`).
216
+ In order to operate with the execution state, every step method receives a structure representing the current state. This structure is similar to a `Hash` and responds to its main methods (`:[]`, `:[]=`, `:fetch`, `:store`, `:include?` and `to_hash`).
217
217
 
218
- When an operation is executed, before running the first step, an initial state is created by coping all the values from the initialization context (and also including `input`).
218
+ When an operation is executed, before running the first step, an initial state is created by copying all the values from the initialization context (and also including `input`).
219
219
  Note that these values can be replaced on later steps but it won't mutate the context object itself since is always frozen.
220
220
 
221
- A state object can be splatted on method definition in the same fashion as a `Hash`, allowing to cherry pick the attributes we are interested for a given step:
221
+ A state object can be splatted on method definition in the same fashion as a `Hash`, thus, allowing to cherry pick the attributes we are interested on any given step:
222
222
 
223
223
  ```ruby
224
224
  # ...
@@ -229,13 +229,13 @@ A state object can be splatted on method definition in the same fashion as a `Ha
229
229
  # ...
230
230
  ```
231
231
 
232
- Note the empty double splat at the end of the parameter list, this Ruby-ism means: grab the mentioned keys and ignore all the rest. If you omit it when you have outstanding keys Ruby's `Hash` destructing will fail.
232
+ Note the empty double splat at the end of the parameter list, this Ruby-ism means: grab the mentioned keys and ignore all the rest. If you omit the `**` when you have outstanding keys, Ruby's `Hash` destructing will fail.
233
233
 
234
234
  ##### Successful operation result
235
235
 
236
236
  On each step you can access or change the operation result for a successful execution.
237
237
  The value will be stored at one of the attributes within the state.
238
- By default the state `:value` key will hold the resulting value, but if you prefer to use another name you can specify it through the `result_at` operation class method.
238
+ By default the state's key `:value` will hold the result, but if you prefer to use another name you can specify it through the `result_at` operation class method.
239
239
 
240
240
  ##### Full example
241
241
 
@@ -280,40 +280,41 @@ class CreateNugget < Pathway::Operation
280
280
  end
281
281
  ```
282
282
 
283
- In the above example the operation will create nugget (whatever that is...). As you can see we are using the methods we mention before to indicate that we need a current user to be present `context: current_user` on initialization, a `call` method to be defined `process do ... end`, and the result value should be stored at the `:nugget` key.
283
+ The example above the operation will produce a nugget (whatever that is...).
284
+
285
+ As you can see in the code, we are using the previously mentioned methods to indicate we need a current user to be present on initialization: `context: current_user`, a `call` method (defined by `process do ... end`), and that the result value should be stored at the `:nugget` key (`result_at :nugget`).
284
286
 
285
287
  Lets delve into the `process` block: it defines three steps using the `step` method and `create_nugget` using `set`, as we said before, this last step will set the result key (`:nugget`) since the `to:` keyword argument is absent.
286
288
 
287
289
  Now, for each of the step methods:
288
290
 
289
- - `:authorize` doesn't needs the state so just ignores it, then checks if the current user is allowed to perform the operation and halts the execution by returning a `:forbidden` error type if is not, otherwise does nothing and the execution goes on.
290
- - `:validate` gets the state, checks the validity of the `:input` value which as we said is just the `call` method input, returns an `error(...)` when there's a problem, and if the validation is correct it updates the state but saving the sanitized values in `:params`. Note that the return value is `state[:params]`, but is ignored like the last one, since this method is specified using `step`.
291
+ - `:authorize` doesn't need the state so just ignores it, then checks if the current user is allowed to perform the operation and halts the execution by returning a `:forbidden` error type if is not, otherwise does nothing and the execution goes on.
292
+ - `:validate` gets the state, checks the validity of the `:input` value which as we said is just the `call` method input, returns an `error(...)` when there's a problem, and if the validation is correct it updates the state but saving the sanitized values in `:params`. Note that on success the return value is `state[:params]`, but is ignored like on `:authorize`, since this method was also specified using `step`.
291
293
  - `:create_nugget` first takes the `:params` attribute from the state (ignoring everything else), and calls `create` on the `Nugget` model with the sanitized params and the current user. The return value is saved to the result key (`:nugget` in this case) as the step is defined using `step` without `to:`.
292
294
  - `:notify` grabs the `:nugget` from the state, and simply emits a notification with it, it has no meaningful return value, so is ignored.
293
295
 
294
- This example basically touches all the essential concepts needed for defining an operation class. If you can grasp it you already have a good understanding on how to implement one. There are still some very important bits to cover (like testing), and we'll tackle that on later sections.
296
+ This example basically touches all the essential concepts needed for defining an operation class. If you can grasp it you've already a good understanding on how to implement one. There are still some very important bits to cover (like testing), and we'll tackle them on later sections.
295
297
 
296
- On a final note, you may be thinking that the code could be bit less verbose; also, shouldn't very common stuff like validation or authorization be simpler to use?; and maybe, why specify the result key?, it could be possible infer it from the surrounding code. We will address all these issues on the next section by using plugins, `pathway`'s extension mechanism.
298
+ On a final note, you may be thinking the code could be bit less verbose; also, shouldn't very common stuff like validation or authorization be simpler to use?; and maybe, why specify the result key name?, it could be possible infer it from the surrounding code. We will address all those issues on the next section using plugins, `pathway`'s extension mechanism.
297
299
 
298
300
  ### Plugins
299
301
 
300
- Pathway can be extended by the use of plugins. They are very similar to the one found in [Roda](http://roda.jeremyevans.net/) or [Sequel](http://sequel.jeremyevans.net/). So if you are already familiar with any of those gems you shouldn't have any problem using `pathway`'s plugin system.
302
+ Pathway operations can be extended with plugins. They are very similar as the ones found in [Roda](http://roda.jeremyevans.net/) or [Sequel](http://sequel.jeremyevans.net/). So if you are already familiar with any of those gems you shouldn't have any problem with `pathway`'s plugin system.
301
303
 
302
- In order to activate a plugin you must call the `plugin` method on the class:
304
+ To activate a plugin just call the `plugin` method on the operation class:
303
305
 
304
306
  ```ruby
305
307
  class BaseOperation < Pathway::Operation
306
308
  plugin :foobar, qux: 'quz'
307
309
  end
308
310
 
309
-
310
311
  class SomeOperation < BaseOperation
311
312
  # The :foobar plugin will also be activated here
312
313
  end
313
314
  ```
314
315
 
315
316
  The plugin name must be specified as a `Symbol` (or also as the `Module` where is implemented, but more on that later), and can it take parameters next to the plugin's name.
316
- When activated it will enrich your operations with new instance and class methods plus new customs step for the process DSL.
317
+ When activated it will enrich your operations with new instance and class methods plus extra customs step for the process DSL.
317
318
 
318
319
  Mind you, if you wish to activate a plugin for a number of operations you can activate it for all of them directly on the `Pathway::Operation` class, or you can create your own base operation and all its descendants will inherit the base class' plugins.
319
320
 
@@ -346,7 +347,7 @@ class CreateNugget < Pathway::Operation
346
347
  end
347
348
  ```
348
349
 
349
- As it can be seen at the code above, the form is first defined elsewhere, and the operation can be set up to use it by calling `form NuggetForm`, and use validate the input at the process block by calling `step :validate`.
350
+ As it can be seen at the code above, the form is first created elsewhere, then is configured to be used by the operation (by calling `form NuggetForm`), and validate the input at the process block by calling `step :validate`.
350
351
 
351
352
  ```ruby
352
353
  class CreateNugget < Pathway::Operation
@@ -366,7 +367,7 @@ class CreateNugget < Pathway::Operation
366
367
  end
367
368
  ```
368
369
 
369
- This second example is equivalent to the first one, but here we call `form` a block instead and no parameter; this block will be use as definition body for a form object that will be stored internally. This way you to keep the form and operation at the same place, which is convenient when you have a rather simpler form and don't need to reuse it.
370
+ Now, this second example is equivalent to the first one, but here we call `form` with a block instead and no parameter; this block will be use as definition body for a form object that will be stored internally. Thus keeping the form and operation at the same place, this is convenient when you have a rather simpler form and don't need to reuse it.
370
371
 
371
372
  One interesting nuance to keep in mind regarding the inline block form is that, when doing operation inheritance, if the parent operation already has a form, the child operation will define a new one extending from the parent's. This is very useful to share form functionality among related operations in the same class hierarchy.
372
373
 
@@ -399,7 +400,7 @@ class CreateNugget < Pathway::Operation
399
400
  end
400
401
  ```
401
402
 
402
- Here we see that the form needs a `:user_name` option so we tell the operation to grab the attribute with the same name from the execution state by activating `:auto_wire_options`, afterwards, when the validation runs, the form will already have the user name available.
403
+ Here the defined form needs a `:user_name` option, so we tell the operation to grab the attribute with the same name from the state by activating `:auto_wire_options`, afterwards, when the validation runs, the form will already have the user name available.
403
404
 
404
405
  Mind you, this option is `false` by default, so be sure to set it to `true` at `Pathway::Operation` if you'd rather have it for all your operations.
405
406
 
@@ -417,7 +418,7 @@ class CreateNugget < Pathway::Operation
417
418
  end
418
419
 
419
420
  process do
420
- step :validate, with: { user_name: :current_user_name } # Inject :user_name to the form object using :current_user_name
421
+ step :validate, with: { user_name: :current_user_name } # Inject :user_name to the form object with the state's :current_user_name
421
422
  step :create_nugget
422
423
  end
423
424
 
@@ -28,13 +28,14 @@ module Pathway
28
28
  self.model_class = model_class
29
29
  self.search_field = search_by
30
30
  self.result_key = Inflector.underscore(Inflector.demodulize(model_class.name)).to_sym if set_result_key
31
- self.model_not_found = error_message || Inflector.humanize(Inflector.underscore(Inflector.demodulize(model_class.name))) + ' not found'
31
+ self.model_not_found = error_message || "#{Inflector.humanize(Inflector.underscore(Inflector.demodulize(model_class.name)))} not found".freeze
32
32
  end
33
33
 
34
34
  def inherited(subclass)
35
35
  super
36
- subclass.model_class = model_class
37
- subclass.search_field = search_field
36
+ subclass.model_class = model_class
37
+ subclass.search_field = search_field
38
+ subclass.model_not_found = model_not_found
38
39
  end
39
40
  end
40
41
 
@@ -1,3 +1,3 @@
1
1
  module Pathway
2
- VERSION = '0.6.1'
2
+ VERSION = '0.6.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pathway
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Herrero
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-16 00:00:00.000000000 Z
11
+ date: 2018-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-inflector