SimpleValue
A tiny Ruby gem for using value objects in your models. Create a plain Ruby class to represent the value object. Then easily use it in a model by extending SimpleValue::Model
and using the value_object
macro.
Installation
Add this line to your application's Gemfile:
gem 'simple_value'
And then execute:
$ bundle
Or install it yourself as:
$ gem install simple_value
Usage
Let's suppose that we have a User
model with a phone
attribute. Currently, User
validates the format of the phone number, which is stored as a string in the database.
class User < ApplicationRecord
before_validation :format_phone
validate :phone_validation
private
def format_phone
# logic for formatting the phone number
end
def phone_validation
# complicated validation logic
end
end
The rest of the application is already written to use a string when interacting with a User
. We can still move the validation and whatever other logic related to the phone number into a separate class.
Moving the logic into its own class also prevents duplication in case another model needs to have a phone number. It can then simply use the same value object.
class Phone
include ActiveModel::Validations
attr_reader :value
validate :validate_number
def initialize(value)
@value = format_number value
end
private
def format_number(number)
# logic for formatting the phone number
end
def validate_number
# complicated validation logic
end
end
We can use the same DSL for validations in any class just by including ActiveModel::Validations
. This way it is possible to easily move the phone validation from the User
model to the new Phone
class.
Currently this gem works for value objects that take a single required argument in their initializer. The value object also needs an attr_reader
for its value (value is the default name, but it can be sometihng else).
The only thing left to do is to make the User
model use the new value object. It needs to extends SimpleValue::Model
in order to get access to the value_object
macro.
class User < ApplicationRecord
extend SimpleValue::Model
value_object :phone, Phone, validate: true
end
The first argument of value_object
is a symbol with the name of the attribute used to initialize the value object. The second arument is the class used for the value object.
There are also two optional parameters for value_object
. validate
is set to false by default, if set to true, it will use whatever validations are in the value object and add the errors to the base of the model's errors.
The second optional parameter is the name of the attr_reader
used to get the value from the value object. By default it is set to :value
.
License
The gem is available as open source under the terms of the MIT License.