README.md in shallow_attributes-0.9.2 vs README.md in shallow_attributes-0.9.3
- old
+ new
@@ -1,6 +1,7 @@
# ShallowAttributes
+
[](https://travis-ci.org/davydovanton/shallow_attributes)
[](https://codeclimate.com/github/davydovanton/shallow_attributes)
[](https://coveralls.io/github/davydovanton/shallow_attributes?branch=master)
[](http://inch-ci.org/github/davydovanton/shallow_attributes)
@@ -12,17 +13,17 @@
to be defined with their types, for example: [virtus][virtus-link], [fast_attributes][fast-attributes-link]
or [attrio][attrio-link]. However, the disadvantage of these gems is performance or API. So, the goal
of `ShallowAttributes` is to provide a simple solution which is similar to the `Virtus` API, simple, fast,
understandable and extendable.
-This is [the performance benchmark][performance-benchmark] of ShallowAttributes compared to virtus gems.
+This is [the performance benchmark][performance-benchmark] of ShallowAttributes compared to Virtus gems.
## Installation
Add this line to your application's Gemfile:
-```ruby
+``` ruby
gem 'shallow_attributes'
```
And then execute:
@@ -31,24 +32,29 @@
Or install it yourself as:
$ gem install shallow_attributes
## Examples
+
### Table of contents
+
* [Using ShallowAttributes with Classes](#using-shallowattributes-with-classes)
* [Default Values](#default-values)
+* [Mandatory Attributes](#mandatory-attributes)
* [Embedded Value](#embedded-value)
* [Custom Coercions](#custom-coercions)
* [Collection Member Coercions](#collection-member-coercions)
* [Note about Member Coercions](#important-note-about-member-coercions)
* [Overriding setters](#overriding-setters)
-* [ActiveModel validation](#activemodel-validation)
+* [ActiveModel compatibility](#activemodel-compatibility)
+* [Dry-types](#dry-types)
### Using ShallowAttributes with Classes
+
You can create classes extended with Virtus and define attributes:
-```ruby
+``` ruby
class User
include ShallowAttributes
attribute :name, String
attribute :age, Integer
@@ -81,10 +87,35 @@
super_user = SuperUser.new
user.age = nil # => 0
```
+ShallowAttributes doesn't make any assumptions about base classes. There is no need to define
+default attributes, or even mix ShallowAttributes into the base class:
+
+``` ruby
+require 'active_model'
+
+class Form
+ extend ActiveModel::Naming
+ extend ActiveModel::Translation
+ include ActiveModel::Conversion
+ include ShallowAttributes
+
+ def persisted?
+ false
+ end
+end
+
+class SearchForm < Form
+ attribute :name, String
+end
+
+form = SearchForm.new(name: 'Anton')
+form.name # => "Anton"
+```
+
### Default Values
``` ruby
class Page
include ShallowAttributes
@@ -101,10 +132,12 @@
attribute :slug, String, default: lambda { |page, attribute| page.title.downcase.gsub(' ', '-') }
# default from a method name as symbol
attribute :editor_title, String, default: :default_editor_title
+ private
+
def default_editor_title
published ? title : "UNPUBLISHED: #{title}"
end
end
@@ -118,10 +151,26 @@
page.views # => 10
page.reset_attribute(:views) # => 0
page.views # => 0
```
+### Mandatory attributes
+You can provide `present: true` option for any attribute that will prevent class from initialization
+if this attribute was not provided:
+
+``` ruby
+class CreditCard
+ include ShallowAttributes
+ attribute :number, Integer, present: true
+ attribute :owner, String, present: true
+end
+
+card = CreditCard.new(number: 1239342)
+# => ShallowAttributes::MissingAttributeError: Mandatory attribute "owner" was not provided
+```
+
+
### Embedded Value
``` ruby
class City
include ShallowAttributes
@@ -258,11 +307,12 @@
# => }
```
### IMPORTANT note about member coercions
-ShallowAttributes performs coercions only when a value is being assigned. If you mutate the value later on using its own interfaces then coercion won't be triggered.
+ShallowAttributes performs coercions only when a value is being assigned. If you mutate the value
+later on using its own interfaces then coercion won't be triggered.
Here's an example:
``` ruby
class Book
@@ -308,15 +358,60 @@
user = User.new(name: "Godzilla")
user.name # => 'Can't tell'
```
-### ActiveModel validation
+### ActiveModel compatibility
+ShallowAttributes is fully compatible with ActiveModel.
+
+#### Form object
+
``` ruby
require 'active_model'
+class SearchForm
+ extend ActiveModel::Naming
+ extend ActiveModel::Translation
+ include ActiveModel::Conversion
+ include ShallowAttributes
+
+ attribute :name, String
+ attribute :service_ids, Array, of: Integer
+ attribute :archived, 'Boolean', default: false
+
+ def persisted?
+ false
+ end
+
+ def results
+ # ...
+ end
+end
+
+class SearchesController < ApplicationController
+ def index
+ search_params = params.require(:search_form).permit(...)
+ @search_form = SearchForm.new(search_params)
+ end
+end
+```
+
+``` erb
+<h1>Search</h1>
+<%= form_for @search_form do |f| %>
+ <%= f.text_field :name %>
+ <%= f.collection_check_boxes :service_ids, Service.all, :id, :name %>
+ <%= f.select :archived, [['Archived', true], ['Not Archived', false]] %>
+<% end %>
+```
+
+#### Validations
+
+``` ruby
+require 'active_model'
+
class Children
include ShallowAttributes
include ActiveModel::Validations
attribute :scream, String
@@ -327,10 +422,30 @@
user.valid? # => false
user.scream = 'hello world!'
user.valid? # => true
```
+### Dry-types
+You can use dry-types objects as a type for your attribute:
+```ruby
+module Types
+ include Dry::Types.module
+end
+
+class User
+ include ShallowAttributes
+
+ attribute :name, Types::Coercible::String
+ attribute :age, Types::Coercible::Int
+ attribute :birthday, DateTime
+end
+
+user = User.new(name: nil, age: 0)
+user.name # => ''
+user.age # => 0
+```
+
## Ruby version support
ShallowAttributes is [known to work correctly][travis-link] with the following rubies:
* 2.0
@@ -349,10 +464,9 @@
to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
-
[doc-link]: http://www.rubydoc.info/github/davydovanton/shallow_attributes/master
[virtus-link]: https://github.com/solnic/virtus
[fast-attributes-link]: https://github.com/applift/fast_attributes
[attrio-link]: https://github.com/jetrockets/attrio