4

I'm with the same problem of this post. But I'm using Rails and don't know how to do this workaround in activerecord.

I'm inserting some data using seeds.rb:

device_platforms = DevicePlatform.create([{id: 1, name: 'Android'}, {id: 2, name: 'IOS'}, {id: 3, name: 'Windows Phone'}])

When I insert another DevicePlatform, I get this exception:

Failure/Error: @device_platform = FactoryGirl.create(:device_platform)
 ActiveRecord::RecordNotUnique:
   PG::UniqueViolation: ERRO:  duplicar valor da chave viola a restrição de unicidade "device_platforms_pkey"                                                                 
   DETAIL:  Chave (id)=(2) já existe.
   : INSERT INTO "device_platforms" ("created_at", "name", "updated_at") VALUES ($1, $2, $3) RETURNING "id"        

The message is in portuguese, it says that a row with that ID already exists.

Thanks.

10
  • Why are you specifying the id? Commented Sep 12, 2014 at 17:32
  • 1
    Don't include ids in your seeds. If you must include ids in your seeds then you'll have to connection.execute the SQL in the other question after adding your seeds. Commented Sep 12, 2014 at 17:40
  • 2
    Thanks for including the exact text of the error. I'd +100 if I could. Commented Sep 12, 2014 at 17:53
  • 1
    @muistooshort You think include ids on seeds file is a bad practice? Commented Sep 12, 2014 at 18:03
  • 1
    Depending on ids being anything in particular is a bad practice. You can do it if you need to but you will need to run some SQL to patch up the sequences that are used to supply id values. Commented Sep 12, 2014 at 18:10

2 Answers 2

6

I believe that although this is a bad habit, many times it is the only resort

You can define this method :

def fix_self_increment(model)
  ActiveRecord::Base.connection.execute(
    "BEGIN; " \
    "LOCK TABLE #{model.table_name} IN EXCLUSIVE MODE; " \
    "SELECT setval('#{model.table_name}_id_seq', COALESCE((SELECT MAX(id)+1 FROM #{model.table_name}), 1), false); " \
    "COMMIT;"
  )
end 

and then call

fix_self_increment(DevicePlatform)

Enjoy

Sign up to request clarification or add additional context in comments.

1 Comment

I'd put this code in every migration of data that does this kind of insert rather than having a method that does it. It quickly teaches you it's a bad idea to specify id. This is the correct answer btw.
-3

According to the comments, using id in seed is a bad practice. I'm avoiding bad practices and that's enough for me. Changed my code to avoiding this.

2 Comments

There are still valid use cases where this can happen (for example, reading in a CSV file in your rake task), so it'd be nice to see a valid answer for how to solve this.
Please accept the answer above as it does answer the question you have asked, even though it is a bad idea. Sometimes doing bad things is necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.