README.md in u-attributes-0.14.0 vs README.md in u-attributes-1.0.0
- old
+ new
@@ -1,30 +1,35 @@
-[![Build Status](https://travis-ci.com/serradura/u-attributes.svg?branch=master)](https://travis-ci.com/serradura/u-attributes) [![Maintainability](https://api.codeclimate.com/v1/badges/b562e6b877a9edf4dbf6/maintainability)](https://codeclimate.com/github/serradura/u-attributes/maintainability)
+[![Gem](https://img.shields.io/gem/v/u-attributes.svg?style=flat-square)](https://rubygems.org/gems/u-attributes)
+[![Build Status](https://travis-ci.com/serradura/u-attributes.svg?branch=master)](https://travis-ci.com/serradura/u-attributes)
+[![Maintainability](https://api.codeclimate.com/v1/badges/b562e6b877a9edf4dbf6/maintainability)](https://codeclimate.com/github/serradura/u-attributes/maintainability)
+[![Test Coverage](https://api.codeclimate.com/v1/badges/b562e6b877a9edf4dbf6/test_coverage)](https://codeclimate.com/github/serradura/u-attributes/test_coverage)
μ-attributes (Micro::Attributes)
================================
This gem allows defining read-only attributes, that is, your objects will have only getters to access their attributes data.
## Table of contents
-- [μ-attributes (Micro::Attributes)](#%CE%BC-attributes-MicroAttributes)
- - [Table of contents](#Table-of-contents)
- - [Installation](#Installation)
- - [Usage](#Usage)
- - [How to require?](#How-to-require)
- - [How to define attributes?](#How-to-define-attributes)
- - [How to define multiple attributes?](#How-to-define-multiple-attributes)
- - [How to define attributes with a constructor to assign them?](#How-to-define-attributes-with-a-constructor-to-assign-them)
- - [How to query the attributes?](#How-to-query-the-attributes)
- - [Built-in extensions](#Built-in-extensions)
- - [ActiveModel::Validations extension](#ActiveModelValidations-extension)
- - [Diff extension](#Diff-extension)
- - [Initialize extension](#Initialize-extension)
- - [Development](#Development)
- - [Contributing](#Contributing)
- - [License](#License)
- - [Code of Conduct](#Code-of-Conduct)
+- [μ-attributes (Micro::Attributes)](#%ce%bc-attributes-microattributes)
+ - [Table of contents](#table-of-contents)
+ - [Installation](#installation)
+ - [Usage](#usage)
+ - [How to require?](#how-to-require)
+ - [How to define attributes?](#how-to-define-attributes)
+ - [How to define multiple attributes?](#how-to-define-multiple-attributes)
+ - [How to define attributes with a constructor to assign them?](#how-to-define-attributes-with-a-constructor-to-assign-them)
+ - [How to inherit the attributes?](#how-to-inherit-the-attributes)
+ - [How to query the attributes?](#how-to-query-the-attributes)
+ - [Built-in extensions](#built-in-extensions)
+ - [ActiveModel::Validations extension](#activemodelvalidations-extension)
+ - [Diff extension](#diff-extension)
+ - [Initialize extension](#initialize-extension)
+ - [Strict initialize extension](#strict-initialize-extension)
+ - [Development](#development)
+ - [Contributing](#contributing)
+ - [License](#license)
+ - [Code of Conduct](#code-of-conduct)
## Installation
Add this line to your application's Gemfile:
@@ -196,14 +201,45 @@
# If you pass a value different of a Hash, an ArgumentError will be raised.
#
# Person.new(1)
# ArgumentError (argument must be a Hash)
-################
-# Inheritance #
-################
+#--------------------#
+# Strict initializer #
+#--------------------#
+# Use .to_initialize! to forbids an instantiation without all keywords.
+
+class StrictPerson
+ include Micro::Attributes.to_initialize!
+
+ attributes :age, name: 'John Doe'
+end
+
+StrictPerson.new({})
+
+# The code above will raise:
+# ArgumentError (missing keyword: :age)
+
+person_without_age = StrictPerson.new(age: nil)
+
+p person_without_age.name # "John Doe"
+p person_without_age.age # nil
+
+# Except for this validation when initializing,
+# the `to_initialize!` method will works in the same ways of `to_initialize`.
+```
+
+### How to inherit the attributes?
+
+```ruby
+class Person
+ include Micro::Attributes.to_initialize
+
+ attributes :age, name: 'John Doe'
+end
+
class Subclass < Person # Will preserve the parent class attributes
attribute :foo
end
instance = Subclass.new({})
@@ -320,15 +356,15 @@
end
# Note:
# If `Micro::Attributes.features()` be invoked without arguments, a module with all features will be returned.
-# --------------------------------------------------------------------#
-# Using the .with() method alias and adding the initialize extension. #
-# --------------------------------------------------------------------#
+#----------------------------------------------------------------------------#
+# Using the .with() method alias and adding the strict initialize extension. #
+#----------------------------------------------------------------------------#
class Job
- include Micro::Attributes.with(:initialize, :diff)
+ include Micro::Attributes.with(:strict_initialize, :diff)
attributes :id, state: 'sleeping'
end
# Note:
@@ -336,19 +372,31 @@
#
# class Job
# include Micro::Attributes.with() # ArgumentError (Invalid feature name! Available options: diff, initialize, activemodel_validations)
# end
+#===================================#
+# Alternatives to the methods above #
+#===================================#
+
#---------------------------------------#
# Via Micro::Attributes.to_initialize() #
#---------------------------------------#
class Job
- include Micro::Attributes.to_initialize(diff: false, activemodel_validations: true)
+ include Micro::Attributes.to_initialize(diff: true, activemodel_validations: true)
- attributes :id, state: 'sleeping'
- validates! :id, :state, presence: true
+ # Same of `include Micro::Attributes.with(:initialize, :diff, :activemodel_validations)`
end
+
+#----------------------------------------#
+# Via Micro::Attributes.to_initialize!() #
+#----------------------------------------#
+class Job
+ include Micro::Attributes.to_initialize!(diff: false, activemodel_validations: true)
+
+ # Same of `include Micro::Attributes.with(:strict_initialize, :activemodel_validations)`
+end
```
### ActiveModel::Validations extension
If your application uses ActiveModel as a dependency (like a regular Rails app). You will be enabled to use the `actimodel_validations` extension.
@@ -426,18 +474,23 @@
1. Creates a constructor to assign the attributes.
2. Adds methods to build new instances when some data was assigned.
```ruby
class Job
- # include Micro::Attributes.features(:initialize)
# include Micro::Attributes.with(:initialize)
# include Micro::Attributes.feature(:initialize)
+ # include Micro::Attributes.features(:initialize)
include Micro::Attributes.to_initialize
attributes :id, :state
end
+job_null = Job.new({})
+
+p job.id # nil
+p job.state # nil
+
job = Job.new(id: 1, state: 'sleeping')
p job.id # 1
p job.state # "sleeping"
@@ -464,9 +517,53 @@
other_job = job.with_attributes(id: 2, state: 'killed')
puts other_job.id # 2
puts other_job.state # killed
puts other_job.equal?(job) # false
+```
+
+### Strict initialize extension
+
+1. Creates a constructor to assign the attributes.
+2. Adds methods to build new instances when some data was assigned.
+3. **Forbids missing keywords**.
+
+```ruby
+class Job
+ # include Micro::Attributes.with(:strict_initialize)
+ # include Micro::Attributes.feature(:strict_initialize)
+ # include Micro::Attributes.features(:strict_initialize)
+ include Micro::Attributes.to_initialize!
+
+ attributes :id, :state
+end
+#----------------------------------------------------------------------------#
+# The strict_initialize extension will require all the keys when initialize. #
+#----------------------------------------------------------------------------#
+
+Job.new({})
+
+# The code above will raise:
+# ArgumentError (missing keywords: :id, :state)
+
+#---------------------------#
+# Samples passing some data #
+#---------------------------#
+
+job_null = Job.new({})
+
+p job.id # nil
+p job.state # nil
+
+job = Job.new(id: 1, state: 'sleeping')
+
+p job.id # 1
+p job.state # "sleeping"
+
+
+# Note:
+# This extension works like the `initialize` extension.
+# So, look at its section to understand all the other features.
```
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.