Mobility. Typed.
This gem contains plugin for Mobility translation framework. It provides type checking for attribute writers.
Motivation
Since Mobility supports different storage backends some of them will not
guarantee type safety of input data. For example Postgres
(Mobility::Backend::Jsonb
let us to save any kind of json-based data in single column.
class Offer < ApplicationRecord
# ...
translates :benefits
end
Offer.create!(benefits: ['fast', 'safe'])
Offer.create!(benefits: 'cheap')
Offer.find_each do |offer|
offer.benefits.each { |benefit| Customer.notify_by_benefit(benefit) }
# => NoMethodError (undefined method `each' for "cheap":String)
end
To prevent errors like this or at least detect them earlier we can add
:type option to attribute writer configuration:
class Offer < ApplicationRecord
# ...
translates :benefits, writer: { type: :array }
end
Offer.create!(benefits: ['fast', 'safe'])
Offer.create!(benefits: 'cheap')
# => MobilityTyped::Writer::TypeError ("benefits= called with string, array expected")
# now error exposed before database records was corrupted
# so we can fix it earlier and code below will executes safely
Offer.find_each do |offer|
offer.benefits.each { |benefit| Customer.notify_by_benefit(benefit) }
end
Installation
Add this line to your application's Gemfile:
gem 'mobility_typed'
And then execute:
$ bundle install
Then add plugin to your mobility initializer:
# your_rails_app/config/initializers/mobility.rb
Mobility.configure do
# ...
plugins do
# ...
typed_writer
# ...
end
# ...
end
And remove writer plugin from your model if you have it:
Mobility.configure do
# ...
plugins do
# ...
writer # <---- remove this line
# ...
end
# ...
end
Usage
Just add type option to attribute writer configuration:
class YourModel < ApplicationRecord
translates :your_attribute, writer: { type: :integer }
end
List of available writers types:
1) :string
2) :integer
3) :float
4) :bool
5) :array
6) :hash
Default Mobility::Plugins::Writer compatibility
To use typed_writer plugin you should remove writer plugin from your initializer.
But typed_writer plugin is backward compatible with writer plugin. You can translate attributes
without passing type option to writer configuration. In this case typed_writer will work just as writer plugin.
TODO:
1) Type checking for nested attributes, to check array and hash content
2) RBS generator