Skip to content

Instantly share code, notes, and snippets.

@cookrn
Created Apr 10, 2012
Embed
What would you like to do?
A Reasonable `to_map` for `ActiveRecord::Base`

to_map

A to_map function is very useful when you want to convert models to PLAIN OLD DATA. Think presenters, conductors, APIs, JSON, etc...

Installation

Add this monkey-patch to your Rails project and call it on your model instances.

Example Models

class DogWalker < ActiveRecord::Base
  has_many :dogs
end
class Dog < ActiveRecord::Base
  belongs_to :dog_walker
end

Example Usage

1- Load a DogWalker

dw = DogWalker.first

__END__

  DogWalker Load (0.2ms)  SELECT "dog_walkers".* FROM "dog_walkers" LIMIT 1
=> #<DogWalker id: 1, name: "Johnny Cash", created_at: "2012-04-10 01:24:01", updated_at: "2012-04-10 01:24:01">

2- Call to_map

dw.to_map

__END__

  Dog Load (0.1ms)  SELECT "dogs".* FROM "dogs" WHERE "dogs"."dog_walker_id" = 1
=> {"id"=>1,
 "name"=>"Johnny Cash",
 "created_at"=>Tue, 10 Apr 2012 01:24:01 UTC +00:00,
 "updated_at"=>Tue, 10 Apr 2012 01:24:01 UTC +00:00}

3- Call to_map passing true to load w/ associations

dw.to_map true

__END__

  Dog Load (0.1ms)  SELECT "dogs".* FROM "dogs" WHERE "dogs"."dog_walker_id" = 1
=> {"id"=>1,
 "name"=>"Johnny Cash",
 "created_at"=>Tue, 10 Apr 2012 01:24:01 UTC +00:00,
 "updated_at"=>Tue, 10 Apr 2012 01:24:01 UTC +00:00,
 "dogs"=>
  [{"id"=>1,
    "name"=>"Chester",
    "dog_walker_id"=>1,
    "created_at"=>Tue, 10 Apr 2012 01:24:01 UTC +00:00,
    "updated_at"=>Tue, 10 Apr 2012 01:24:01 UTC +00:00}]}
module ActiveRecord
class Base
def to_map( include_related = false )
attrs = attributes
reflections.each do | key , reflection |
associated = send key
case
when reflection.collection?
attrs[ key ] = associated.map { | related | related.attributes }
else
attrs[ key ] = associated.attributes
end
end if include_related
Map.new attrs
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment