Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: ArgumentError - you can't define an already defined column

I have a Rails 6 app (6.0.0rc1). It has book and author models that have has_many :through associations. I created a join table with

rails g migration CreateJoinTableAuthorsBook author:references books:references

As you can see, I named the table incorrectly and I referenced the book incorrectly. I deleted the migration and created a new migration

rails g migration CreateJoinTableAuthorsBooks author:references book:references

Now when I run the migration, I get

ArgumentError: you can't define an already defined column 'author_id'.

I've searched my entire Rails app, but I can't find 'author_id' anywhere. I ran the previous migration (the one with the incorrect values). How can I delete the previous 'author_id' so I can successfully run the migration?

like image 664
hashrocket Avatar asked Oct 27 '25 03:10

hashrocket


2 Answers

UPDATE The problem likely lies in the new migration. In Rails 5.2 (I don't have Rails 6 handy) rails g migration CreateJoinTableAuthorsBooks author:references book:references produces a migration like so:

create_join_table :authors, :books do |t|
  t.references :author, foreign_key: true
  t.references :book, foreign_key: true
end

create_join_table :authors, :books already creates a table with references (although they're not declared foreign keys). t.references :author and t.references :book are redundant. In Rails 5.2 this redundancy is overlooked, but perhaps Rails 6 does not.

For this reason I'd recommend tweaking your migration so everything is properly declared and indexed.

create_join_table :authors, :books, column_options: { null: false, foreign_key: true } do |t|
  t.index [:author_id, :book_id]
  t.index [:book_id, :author_id]
end

The normal procedure for fixing a goofed migration is to first rollback the migration with rails db:rollback, then delete the bad migration file. Rolling back requires the migration you're rolling back still exists (and is reversible).

Otherwise, start with a fresh development database using the version in db/schema.rb with rails db:reset. Note this will blow away your dev and test databases; that shouldn't be an issue. Be sure your db/schema.rb doesn't contain changes from your goofed migration, usually you can assure this by checking it out from version control.

Finally if everything is really messed up including db/schema.rb, rails db:migrate:reset will re-run all your migrations, rebuild db/schema.rb fresh, and provide you with fresh development and test databases.

like image 100
Schwern Avatar answered Oct 29 '25 19:10

Schwern


create_join_table :authors, :books 

will fix it for you as rails 6 doesn't need those declarations.

like image 38
milaziggy Avatar answered Oct 29 '25 17:10

milaziggy