Gordon Isnor
Gordon Isnor

Reputation: 2105

Rails + UUID generated schema assumes UUID is an integer rather than a string

I’m trying to use a UUID as the primary key for a Rails app, and am running into problem after problem.

I am specifying in migration this: create_table :users, :id => false do |t| then this: execute("ALTER TABLE users ADD PRIMARY KEY(uuid)")

In my user model: set_primary_key "uuid"

Using the UUID tools to generate the UUID.

This is all working great, the problem I currently have is that the schema.rb that gets generated looks like this:

create_table "users", :primary_key => "uuid", :force => true do |t|

Which assumes that the primary key column is an 11 character integer rather than a 36 character string, so running migrations produces a correct database, but test database is generated incorrectly, and if I were to run rake db:schema:load, it would fail as well...

Need to figure out how to override the way that schema.rb assumes that if there’s a primary key column that it will be an integer....

Upvotes: 6

Views: 1816

Answers (3)

cailinanne
cailinanne

Reputation: 8372

I think the best approach is to switch from managing your schema in Ruby (schema.rb) to managing it in SQL (development_structure.sql).

To do this:

  1. In application.rb set config.active_record.schema_format = :sql
  2. Delete your schema.rb file.
  3. Every time you run rake db:migrate, run rake db:dump:structure as well. That will dump your schema to db/development_structure.sql. When you run rake db:test:prepare it will now use the development_structure.sql file instead of the scheam.rb file.

You can read more about this in section 6.2 of the migrations guide (http://guides.rubyonrails.org/migrations.html).

Upvotes: 3

Gnomet
Gnomet

Reputation: 966

We have been using UUID as the primary key for a long time (currently with Rails 3.0.0), but so far have not found a way to make Schema dumper understand that there is no integer id.

So our solution has been fixing the schema by hand, when needed. For example always after rake db:migrate. :D

We just change the line

create_table "people", :force => true do |t|

to

create_table "people", :id => false, :force => true do |t|

t.string   "id", :limit => 22,  :null => false

It's rather annoying but then everything works. So the problem is not in Rails not allowing UUID primary keys, but schema dumper not understanding those.

Upvotes: 1

sethvargo
sethvargo

Reputation: 26997

I ran into this problem. As far as i can tell, it's impossible to override rails' requirement that the PK be an integer. What i did to bypass this was add a key to unique on the database and then setup my default scopes on each model to search via my unique string instead of the regular integer

Upvotes: 0

Related Questions