Will
Cannings

Postgres has support for 8 byte integers with bigint’s, and ActiveRecord natively supports reading & writing these values in Postgres (both on 32 and 64 bit machines, thanks to Fixnum and Bignum). Using them in AR migrations is actually pretty easy as well, but there’s some fudgery required to use 8 byte ints as an id if we don’t want to patch AR.

To create an 8 byte field:

create_table :example do |t|
  t.integer  :eight_byte_integer, :limit => 8
end

To create a table with an 8 byte id without patching:

create_table :example do |t|
  ... fields
end

change_column :example, :id, :integer, :limit => 8

Note: id sequences are automatically created as bigint’s, so all we’re doing here is allowing the table’s id field to store all the values the sequence will create.

Alternatively, we can patch ActiveRecord to automatically make all primary keys bigserial’s. It’s better to patch a frozen version of Rails (in your vendor folder) than your installed gem.

file: vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -283,7 +283,7 @@

       def native_database_types #:nodoc:
         {
-          :primary_key => "serial primary key",
+          :primary_key => "bigserial primary key",
           :string      => { :name => "character varying", :limit => 255 },
           :text        => { :name => "text" },
           :integer     => { :name => "integer" },