Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting types of the attributes in an ActiveRecord object

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).

Thanks.

like image 387
Michael Neale Avatar asked Mar 08 '10 05:03

Michael Neale


People also ask

What are attributes in Rails?

In Rails 5, model attributes go through the attributes API when they are set from user input (or any setter) and retrieved from the database (or any getter). Rails has used an internal attributes API for it's entire lifetime. When you set an integer field to “5”, it will be cast to 5.

What is an ActiveRecord object?

In Active Record, objects carry both persistent data and behavior which operates on that data. Active Record takes the opinion that ensuring data access logic as part of the object will educate users of that object on how to write to and read from the database.

What is attribute in Ruby?

Attributes are specific properties of an object. Methods are capabilities of an object. In Ruby all instance variables (attributes) are private by default. It means you don't have access to them outside the scope of the instance itself. The only way to access the attribute is using an accessor method.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.


2 Answers

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 
like image 184
Grant Birchmeier Avatar answered Sep 21 '22 00:09

Grant Birchmeier


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",  "firstname",  "lastname",  "created_at",  "updated_at",  "email",... 

Getting the type:

pry> User.type_for_attribute('email') => #<ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString:0x007ffbab107698  @limit=255,  @precision=nil,  @scale=nil> 

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.

like image 39
Matthias Winkelmann Avatar answered Sep 23 '22 00:09

Matthias Winkelmann