Typed Fields
Introduction
Using ActiveRecord to implement domain objects causes a lot of grief. Often it's just impossible as there is no table that you map your domain objects to.
ActiveModel is a big step forward and I highly recommend using it. It does a pretty good job doing what AR used to do but without coupling your domain objects to the database. One of a few things I miss though is typed fields. ActiveRecord takes care of all type conversations. You just pass a bunch of strings and it knows what to do with them. You need to do it manually if you use ActiveModel.
That's where the TypedFields gem comes into play. It allows you to specify types for your fields which eases the migration from ActiveRecord to ActiveModel.
How to use TypedFields
class Person
include TypedFields
string :first_name, :last_name
integer :age
decimal :income
def initialize params
initialize_fields params
end
end
As you can see from the example above including TypedFields adds several class methods (such as string, integer) and an instance method initializing fields.
Advanced Features
Using Custom Types
Besides having such basic types as integers, decimals, strings and booleans you can specify custom types.
module UppercaseString
def self.parse str
str.upcase
end
end
class Person
include TypedFields
custom :name, type: UppercaseString
end
p = Person.new
p.initialize_fields name: "abc" # @name == ABC
Arrays
class Service
include TypedFields
array_of_integers :object_ids
end
s = Service.new
s.initialize_fields object_ids => ["1", "2"] # @object_ids == [1,2]
Default Values
class Person
include TypedFields
string :name
integer :age, default: 100
end
p = Person.new
p.initialize_fields name: "John" #@name == "John", @age == 100
Using Proc as a Default Value
class Person
include TypedFields
string :name, default: Proc.new{"default value"}
end
p = Person.new
p.initialize_fields({}) #@name == "default_value"