1

I'm working on a Rails 4.2.5 app that allows to upload videos using Paperclip. It works fine except for very large files. Using a video that is over 3GB I get the following error:

RangeError (3283091012 is out of range for ActiveRecord::Type::Integer with limit 4)

Now I can tell that 3283091012 is the size of the file so I ithought this happens when MySQL is trying to save that value for the file_size field created by paperclip and I could fix it by increasing the limit in the database or even better using a migration file, but I thought I'd check the table structure before and I was surprised with the following:

mysql> describe formats;
+-------------------+--------------+------+-----+---------+----------------+
| Field             | Type         | Null | Key | Default | Extra          |
+-------------------+--------------+------+-----+---------+----------------+
| id                | int(11)      | NO   | PRI | NULL    | auto_increment |
| video_id          | int(11)      | YES  | MUL | NULL    |                |
| name              | varchar(255) | YES  |     | NULL    |                |
| quality           | varchar(255) | YES  |     | NULL    |                |
| created_at        | datetime     | NO   |     | NULL    |                |
| updated_at        | datetime     | NO   |     | NULL    |                |
| file_file_name    | varchar(255) | YES  |     | NULL    |                |
| file_content_type | varchar(255) | YES  |     | NULL    |                |
| file_file_size    | int(11)      | YES  |     | NULL    |                |
| file_updated_at   | datetime     | YES  |     | NULL    |                |
| trailer           | tinyint(1)   | YES  |     | 0       |                |
+-------------------+--------------+------+-----+---------+----------------+

As you can see file_file_size is an int(11) not 4 as claimed by the error. Any idea what is causing this?

Note: I do not have any fancy validations on the model (just forcing the presence of a couple of attributes) and the controller action is a regular create action.

Julien
  • 2,217
  • 2
  • 28
  • 49

3 Answers3

1

According to the MYSQL documentation an integer have a range from -2147483648 to +2147483647. So your number is to big for this type.

Update your column and use the parameter limit to indicate that you want to have a bigint.

class ChangeIntegerLimitInYourTable < ActiveRecord::Migration
  def change
    update_column :your_table, :your_column, :integer, limit: 8
  end 
end
souravlahoti
  • 716
  • 2
  • 8
  • 29
1

The 11 in int(11) and the 20 in int(20) are the display widths for those columns. They do not reflect the number of bits used to the store the integer; rather, they can be used for the purpose of zero-padding.

11 is the default for INT because the maximum width for a signed 4-byte integer is -2147483648. Similarly, 20 is the default for BIGINT because the maximum width for an 8-byte integer is -9223372036854775808.

In fact, I would expect file_file_size to be a bigint(20) after updating the column.

There's a good explanation here. https://blogs.oracle.com/jsmyth/what-does-the-11-mean-in-int11

alenz
  • 84
  • 8
0

Being Srv's answer was giving me an undefined method 'update_column' error when running the migration, but this worked:

class ChangeIntegerLimitInFormats < ActiveRecord::Migration
  def self.up
    change_table :formats do |t|
      t.change :file_file_size, :integer, limit: 8
    end
  end
  def self.down
    change_table :formats do |t|
      t.change :file_file_size, :integer, limit: 4
    end
  end
end

Inspecting the table structure after running the migration shows that the column file_file_size is now an Int(20) instead of Int(11) like it was before, not sure how the 4 translates to 11 and the 8 translates to 20 though, which was the source of confusion to start with, if anybody has info on that please add a comment.

Julien
  • 2,217
  • 2
  • 28
  • 49