Home » Ruby » Getting types of the attributes in an ActiveRecord object

Getting types of the attributes in an ActiveRecord object

Posted by: admin November 30, 2017 Leave a comment


I would like to know if it is possible to get the types (as known by AR – eg in the migration script and database) programmatically (I know the data exists in there somewhere).

For example, I can deal with all the attribute names:

ar.attribute_names.each { |name| puts name }

.attributes just returns a mapping of the names to their current values (eg no type info if the field isn’t set).

Some places I have seen it with the type information:

in script/console, type the name of an AR entity:

>> Driver
=> Driver(id: integer, name: string, created_at: datetime, updated_at: datetime)

So clearly it knows the types. Also, there is .column_for_attribute, which takes an attr name and returns a column object – which has the type buried in the underlying database column object, but it doesn’t appear to be a clean way to get it.

I would also be interested in if there is a way that is friendly for the new “ActiveModel” that is coming (rails3) and is decoupled from database specifics (but perhaps type info will not be part of it, I can’t seem to find out if it is).



In Rails 3, for your model “Driver”, you want Driver.columns_hash.

Driver.columns_hash["name"].type  #returns :string

If you want to iterate through them, you’d do something like this:

Driver.columns_hash.each {|k,v| puts "#{k} => #{v.type}"}

which will output the following:

id => integer
name => string
created_at => datetime
updated_at => datetime


You can access the types of the columns by doing this:

Driver.columns.each {|c| puts c.type}

If you want to get a list of all column types in a particular Model, you could do:

Driver.columns.map(&:type) #gets them all
Driver.columns.map(&:type).uniq #gets the unique ones


In Rails 5, you can do this independently of the Database. That’s important if you use the new Attributes API to define (additional) attributes.

Getting all attributes from a model class:

pry> User.attribute_names
=> ["id",

Getting the type:

pry> User.type_for_attribute('email')
=> #<ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString:0x007ffbab107698

That’s sometimes more information than needed. There’s a convenience function that maps all these types down to a core set (:integer, :string etc.)

> User.type_for_attribute('email').type
=> :string 

You can also get all that data in one call with attribute_types which returns a 'name': type hash.


In rails 5 this will give you a list of all field names along with their data type:

Model_Name.attribute_names.each do |k| puts "#{k} = #{Model_Name.type_for_attribute(k).type}" end


This snippet will give you all the attributes of a model with the associated database data types in a hash. Just replace Post with your Active Record Model.

Post.attribute_names.map {|n| [n.to_sym,Post.type_for_attribute(n).type]}.to_h

Will return a hash like this.

=> {:id=>:integer, :title=>:string, :body=>:text, :created_at=>:datetime, :updated_at=>:datetime, :topic_id=>:integer, :user_id=>:integer}