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"