README.md in rails-patterns-0.2.0 vs README.md in rails-patterns-0.3.0
- old
+ new
@@ -115,8 +115,61 @@
```ruby
user_activation = ActivateUser.call(user)
user_activation.result # <User id: 5803143, email: "tony@patterns.dev ...
```
+## Collection
+
+### When to use it
+
+One should consider using collection pattern when in need to add a method that relates to the collection a whole.
+Popular example for such situation is for paginated collections, where for instance `#current_page` getter makes sense only in collection context.
+Also collections can be used as a container for mapping or grouping logic (especially if the mapping is not 1-1 in terms of size).
+Collection might also act as a replacement for models not inheriting from ActiveRecord::Base (e.g. `StatusesCollection`, `ColorsCollection` etc.).
+What is more, collections can be used if we need to encapsulate "flagging" logic - for instance if we need to render a separator element between collection elements based on some specific logic, we can move this logic from view layer to collection and yield an additional flag to control rendering in view.
+
+### Assumptions and rules
+
+* Collections include `Enumerable`
+* Collections can be initialized using `.new`, `.from` and `.for` (aliases)
+* Collections have to implement `#collection` method that returns object responding to `#each`
+* Collections provide access to consecutive keyword arguments using `#options` hash
+* Collections provide access to first argument using `#subject`
+
+### Examples
+
+#### Declaration
+
+```ruby
+class ColorsCollection < Patterns::Collection
+ AVAILABLE_COLORS = { red: "#FF0000", green: "#00FF00", blue: "#0000FF" }
+
+ private
+
+ def collection
+ AVAILABLE_COLORS
+ end
+end
+
+class CustomerEventsByTypeCollection < Patterns::Collection
+ private
+
+ def collection
+ subject.
+ events.
+ group_by(&:type).
+ transform_values{ |event| event.public_send(options.fetch(:label_method, "description")) }
+ end
+end
+```
+
+#### Usage
+
+```ruby
+ColorsCollection.new
+CustomerEventsCollection.for(customer)
+CustomerEventsCollection.for(customer, label_method: "name")
+```
+
## Further reading
* [7 ways to decompose fat active record models](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/)