Search code examples
ruby-on-railsrubyactiverecordruby-on-rails-4postgresql-9.1

Accessing sql_type from Model.column_types


When using the column_types method from ActiveRecord::Base, I am able to retrieve the actual sql_type like so -

>> User.column_types.map{|k, v| [k, v.type, v.try(:sql_type)]}
[["id", :integer, "integer"],
 ["name", :string, "character varying(255)"],
 ["email", :string, "character varying(255)"],
 ["created_at", :datetime, nil],
 ["updated_at", :datetime, nil],
 ["password_digest", :string, "character varying(255)"],
 ["remember_token", :string, "character varying(255)"]] 

Notice that the :datetime fields, which are implemented in the database as timestamp without time zone, do not provide the sql_type method. However, oddly enough, it appears to exist here -

>> col = User.column_types['created_at']
#<ActiveRecord::AttributeMethods::TimeZoneConversion::Type:0x00000101a63130
    @column=..., @oid_type=..., @array=false, @name="created_at",
    @sql_type="timestamp without time zone", @null=true, @limit=nil, @precision=nil,
    @scale=nil, @type=:datetime, @default=nil, @primary=false, @coder=nil>>

But I can't access it!

>> col.sql_type
NoMethodError: undefined method `sql_type' for 
#<ActiveRecord::AttributeMethods::TimeZoneConversion::Type:0x00000101a63130>

Am I missing something here? Or is this a bug in ActiveRecord?


Solution

  • The sql_type attribute is not defined in ActiveRecord::AttributeMethods::TimeZoneConversion::Type but in its @column attribute.

    You can access to the sql_type via columns like this:

    User.columns.find{|c| c.name == 'created_at'}.sql_type