README.md in rails-patterns-0.4.0 vs README.md in rails-patterns-0.4.1

- old
+ new

@@ -2,11 +2,11 @@ A collection of lightweight, standardized, rails-oriented patterns. - [Query - complex querying on active record relation](#query) - [Service - useful for handling processes involving multiple steps](#service) -- [Collection - when in need to add a method that relates to the collection a whole](#collection) +- [Collection - when in need to add a method that relates to the collection as whole](#collection) - [Form - when you need a place for callbacks, want to replace strong parameters or handle virtual/composite resources](#form) ## Installation ```ruby @@ -80,21 +80,25 @@ ## Service ### When to use it Service objects are commonly used to mitigate problems with model callbacks that interact with external classes ([read more...](http://samuelmullen.com/2013/05/the-problem-with-rails-callbacks/)). -Service objects are also useful for handling processes involving multiple steps. E.g. a controller that performs more than one operation on its subject (usually a model instance) is a possible candidate for Extract ServiceObject (or Extract FormObject) refactoring. +Service objects are also useful for handling processes involving multiple steps. E.g. a controller that performs more than one operation on its subject (usually a model instance) is a possible candidate for Extract ServiceObject (or Extract FormObject) refactoring. In many cases service object can be used as scaffolding for [replace method with object refactoring](https://sourcemaking.com/refactoring/replace-method-with-method-object). ### Assumptions and rules * Service objects are always used by calling class-level `.call` method * Service objects have to implement `#call` method * Calling service object's `.call` method executes `#call` and returns service object instance * A result of `#call` method is accessible through `#result` method * It is recommended for `#call` method to be the only public method of service object (besides state readers) * It is recommended to name service object classes after commands (e.g. `ActivateUser` instead of `UserActivation`) +### Other + +A bit higher level of abstraction is provided by [business_process gem](https://github.com/Selleo/business_process). + ### Examples #### Declaration ```ruby @@ -160,11 +164,11 @@ def collection subject. events. group_by(&:type). - transform_values{ |event| event.public_send(options.fetch(:label_method, "description")) } + transform_values{ |events| events.map{ |e| e.public_send(options.fetch(:label_method, "description")) }} end end ``` #### Usage @@ -181,18 +185,19 @@ Form objects, just like service objects, are commonly used to mitigate problems with model callbacks that interact with external classes ([read more...](http://samuelmullen.com/2013/05/the-problem-with-rails-callbacks/)). Form objects can also be used as replacement for `ActionController::StrongParameters` strategy, as all writable attributes are re-defined within each form. Finally form objects can be used as wrappers for virtual (with no model representation) or composite (saving multiple models at once) resources. In the latter case this may act as replacement for `ActiveRecord::NestedAttributes`. +In some cases FormObject can be used as scaffolding for [replace method with object refactoring](https://sourcemaking.com/refactoring/replace-method-with-method-object). ### Assumptions and rules * Forms include `ActiveModel::Validations` to support validation. * Forms include `Virtus.model` to support `attribute` static method with all [corresponding capabilities](https://github.com/solnic/virtus). * Forms can be initialized using `.new`. * Forms accept optional resource object as first constructor argument. * Forms accept optional attributes hash as latter constructor argument. -* forms have to implement `#persist` method that returns falsey (if failed) or truthy (if succeeded) value. +* Forms have to implement `#persist` method that returns falsey (if failed) or truthy (if succeeded) value. * Forms provide access to first constructor argument using `#resource`. * Forms are saved using their `#save` or `#save!` methods. * Forms will attempt to pre-populate their fields using `resource#attributes` and public getters for `resource` * Form's fields are populated with passed-in attributes hash reverse-merged with pre-populated attributes if possible. * Forms provide `#as` builder method that populates internal `@form_owner` variable (can be used to store current user).