0

See this answer for how I implemented string primary keys in my rails app: https://stackoverflow.com/a/1434819/4585520

In the migrations, id: false is specified and some custom postgres execution code is added (i.e. execute "ALTER TABLE users ADD PRIMARY KEY (uid);" where uid is a string). Also, in the models, self.primary_key = :uid is usedThe result is that I have no 'id' columns, just 'uid' columns which are all strings.

However, when I deploy this to Heroku and run my seed generation, I get errors because of duplicate uids. I notice that the added uid values are integers. Perhaps the string values I'm providing are being converted to integers (I have UIDs in a JSON file and am importing those, so no uid generation is occurring), which would explain why they're producing duplicate values.

Why are my uids integers on heroku when they're correctly running as strings in development?

Community
  • 1
  • 1
maxple
  • 311
  • 2
  • 6

1 Answers1

0

I don't believe this is a Heroku issue, but rather an issue with how the migration tweaked the database.

I've got a Rails app that uses UUID's for primary keys as well. Here's a look at my DB on Heroku Postgres:

   Column   |            Type             |                 Modifiers
------------+-----------------------------+-------------------------------------------
 id         | uuid                        | not null default uuid_generate_v4()
 data       | json                        | not null

Here was my migration:

enable_extension 'uuid-ossp'
create_table :notifications, id: :uuid  do |t|
  t.json :data, null: false
end

I'm guessing that the column type may not have been set correctly in your migration. Take a look at your DB on heroku (heroku pg:psql) -- is the uid column an integer that's using a sequence? Do you see something like nextval('users_uid_seq'::regclass)? If so, this requires the column to be an integer. I'd try the following migration to modify your database:

enable_extension 'uuid-ossp'
remove_column :users, :uid 
add_column :users, :uuid, :uuid, default: 'uuid_generate_v4()'

This will:

  1. ensure that UUID generation for PG is enabled
  2. remove the current uid column (just to get proper naming)
  3. create a new uuid column, with the type set as uuid and the generation handled on the PG side.

If you're already using Rails to generate UUID's (not recommended, though), you could just go into your database and change the column type from integer to string.

I hope that helps!

jmccartie
  • 4,956
  • 8
  • 50
  • 71
  • awesome, i had no idea about the json or uid datatypes. Thanks and i'll try this – maxple Oct 27 '15 at 23:04
  • Ah yes! Both are great new additions. Here's a blog post on UUID's http://blog.arkency.com/2014/10/how-to-start-using-uuid-in-activerecord-with-postgresql/ and one on JSON https://blog.codeship.com/unleash-the-power-of-storing-json-in-postgres/ and you'll have the ability to default to UUID's (if you want) in Rails 5: http://blog.mccartie.com/2015/10/20/default-uuid's-in-rails.html – jmccartie Oct 27 '15 at 23:14
  • Max - did this answer help? If so, please accept the answer. Thanks! – jmccartie Oct 28 '15 at 22:34
  • I haven't had time to test it. – maxple Nov 01 '15 at 03:15