Search code examples
rubyrails-activerecordpadrino

Type Casting a Column to bigint in Padrino Active Record


I have upgraded to the latest Ruby on a Padrino application and I am having errors with active record when creating a new object. It's validating a number (an ISBN) as 4 bytes. The error is:

9781407005416 is out of range for ActiveRecord::Type::Integer with limit 4

How do I tell a Ruby active record class to use 8 byte limit?

I am not talking about running a migration, the table is already bigint(20).

I thought the following would work:

class Book < ActiveRecord::Base
    attribute :isbn, :integer, :limit => 8
end

I then get errors on find_by and as_json for the ISBN field:

#<NoMethodError: undefined method 'type_cast_for_database' for :integer:Symbol

I turned the 'isbn' method into a new instance variable instead of changing the column of the attribute created by the active record adapter.

I know the column has a limit, but not sure how to access the type of the column to update it.

Falling a solution to the type setting is there a way to skip the validation that is now happening in the active record ensure_in_range.

Is there a way to change the built in DEFAULT_LIMIT = 4 of class Integer < Value from my app? This is related to the following changes in Ruby but I have no access to changing the Padrino source.


Solution

  • How do I tell a Ruby active record class to use 8 byte limit? AFAIK, AR should figure this out directly from the database metadata.

    First, restart the app if not done already - column types are cached. Next, I would verify that AR actually sees the column as you expect. Try this to make sure it is doing what you think:

    p Book.columns.select{ |col| col.name == 'isbn'}
    

    Look at the @range and @limit under @cast_type.

    I turned the 'isbn' method into a new instance variable instead of changing the column of the attribute created by the active record adapter.

    Does this mean that you overrode the isbn getter? If so, what exactly does that code look like?