class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.integer :link_id
t.text :body
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
add_index :comments, :link_id
end
end
I was deploying my app to heroku and had to redo the database in Pg insteand of sqlite 3. When I migrate my database I am gettting this
NameError: uninitialized constant CreateCommments
I have been search SO all day and tried many of the solutions but to no avail. I have searched spelling errors, dropped, recreated the database. My database.yml is up to date and gem and gemlock are clean of sqlite, but it will not stop yelling at me. Thank you in advance.
The error is because the filename is incorrect. It has to be a timestamp with the class name then in snake case, like
20170602175844_create_comments.rb
You can of course do this manually and just change the filename, or run in the console and get a new migration
rails g migration create_comments
Note:
It doesn't have to be a timestamp though, that's just the way the rails rake task does it. You can also use a numerical sequence like if you create your files manually. This is just done to be able to see what migrations have already run and to be able to rollback to a specific version. Also so that the migrations run in a specific order.
1_create_comments.rb
Related
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?
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.
create_join_table :authors, :books
will fix it for you as rails 6 doesn't need those declarations.
I had this same issue when working on a Rails 6 application.
== 20200711132707 CreateProducts: migrating ===================================
-- create_table(:products)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
you can't define an already defined column 'voltage'.
Here’s how I fixed it:
The issue was that I defined a model attribute twice, which in this case was voltage:decimal. So when I run rails db:migrate it throws the error.
I fixed by first deleting the migration file for products.
And then recreating the migration for products.
This time when I ran rails db:migrate everything worked well.
That's all.
I hope this helps
I had the same issue,
you do NOT need anymore the references:
# remove these:
t.references :author, foreign_key: true
t.references :book, foreign_key: true
Note: you can still use the options used in t.references with create_join_table, using the column_options arg.
For example:
create_join_table :authors, :books, column_options: { type: :uuid, null: false, index: true, foreign_key: true } do |t|
...
end
So I'm working with a colleague who added some additional migration files and per normal procedure once I pulled their version I ran rails db:migrate. I end up getting the following errors:
Index name 'index_authorizations_on_user_id' on table 'authorizations' already exists
ArgumentError: Index name 'index_authorizations_on_user_id' on table 'authorizations' already exists
So I went and checked the schema and the table is already present. So why is it failing? Typically in the past it only generates new table entries/updates when doing a migration so why isn't it just ignoring it?
I've tried doing a rollback and get:
This migration uses remove_columns, which is not automatically reversible.
I've tried doing bin/rails db:migrate RAILS_ENV=development and I get the same errors.
I've done a db:reset, db:drop, and it all comes back to an issue with pending migrations that I cannot get to run. What am I doing wrong?
They added the following migration: 20171024074328_create_authorizations.rb
class CreateAuthorizations < ActiveRecord::Migration[5.1]
def change
create_table :authorizations do |t|
t.string :provider
t.string :uid
t.references :user, foreign_key: true
t.timestamps
add_index :authorizations, :user_id
add_index :authorizations, [:provider, :uid], unique: true
end
end
end
This:
t.references :user, foreign_key: true
adds an index on authorizations.user_id for you. If you check the references documentation it will point you at add_reference and that says:
:index
Add an appropriate index. Defaults to true. [...]
So index: true is the default when you call t.references :user and that creates the same index that add_index :authorizations, :user_id creates.
So the only thing that I've found that "worked" was to actually delete the migration files then run rails db:migrate. Didn't catch on anything, no errors.
Not a fan of the fact that this worked.
Check if it's a table or a changed table, most times you need to drop the table or delete the column then run the migration again and it'll be good to go
EDIT: This is not a dupe of Can't migrate after scaffold in Hartl's tutorial! I have Arel updated in my Gemfile just in case, but it makes no difference. Also, this is POST-migration, the rake finished just fine. However after the rake, when I try to query the association via the console, that is when I get the error!
I have two models with a simple one-to-many association between them. After adding the second model and raking the db, I opened rails console to test some stuff out, and I get an error every time I try to use the association in a query.
Here are the classes:
class Startup < ActiveRecord::Base
has_many :reqs
end
class Req < ActiveRecord::Base
belongs_to :startup
end
This is the migration for the Reqs table:
class CreateReqs < ActiveRecord::Migration
def change
create_table :reqs do |t|
t.string :title
t.text :desc
t.integer :sort
t.references :startup, index: true
t.timestamps null: false
end
end
end
And here is the simple test I'm trying to test in the console afterwards:
> startup = Startup.first
> startup.reqs ## Generates ArgumentError
> startup.reqs.build ## Generates same error
And here is the beginning of the error:
ArgumentError: wrong number of arguments (1 for 0)
from /usr/local/rvm/gems/ruby-2.1.4#rails4/gems/activerecord-4.2.0.beta4/lib/active_record/connection_adapters/abstract_adapter.rb:271:in
`initialize'
from /usr/local/rvm/gems/ruby-2.1.4#rails4/gems/activerecord-4.2.0.beta4/lib/active_record/connection_adapters/abstract_adapter.rb:271:in
I'm still getting the hang of a lot of the details of RoR, so please hang with me! But from what I thought I knew, this association seems so basic that I have no idea where to start fixing it. Thanks for your help!
I think this may have been some sort of fluke or bug in Rails. I tried again this morning and the rails console was still giving me the same error. Then just for kicks I tried adding another model that was the same, just with a different name:
class CreateSkills < ActiveRecord::Migration
def change
create_table :skills do |t|
t.string :title
t.text :desc
t.integer :sort
t.references :startup, index: true
t.timestamps
end
end
end
After adding the has_many skills to Startup.rb, I went back into Rails console and now BOTH of the associations (Startup.skills and Startup.reqs) work just fine. Out of curiosity, I did a db:rollback and destroyed the Skill model and then went back into the console. Startup.reqs still works fine even though Skill is not there anymore.
I have no idea why this would make a difference, but wanted to post what worked for me in case someone else runs into a similar issue. Try generating another model to kind of "reset" the db and then you can roll it back and everything may work for you.
I have created a database with devise and the nifty generator. I'm trying to make a new database with the nifty generator (rails g nifty:scaffold Asset user_id:integer), but when I try to migrate the database (rake db:migrate), I get the following error:
charlotte-dator:showwwdown holgersindbaek$ rake db:migrate
== DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'users' already exists: CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `email` varchar(255) DEFAULT '' NOT NULL, `encrypted_password` varchar(128) DEFAULT '' NOT NULL, `reset_password_token` varchar(255), `reset_password_sent_at` datetime, `remember_created_at` datetime, `sign_in_count` int(11) DEFAULT 0, `current_sign_in_at` datetime, `last_sign_in_at` datetime, `current_sign_in_ip` varchar(255), `last_sign_in_ip` varchar(255), `name` varchar(255), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
I'm following a tutorial and have quite a hard time understanding why this happens. Can anyone explain what is going on?
In your create_users migration (APP_ROOT/db/migrate/..), add drop_table :users right before create_table :users and run rake db:migrate. It will remove the users table before recreating it. You can remove that line of code after running this migration so it doesn't give you errors later on. Just a small fix if you dont have UI access to a database (on heroku, for example).
You need to drop that table from the sql lite console (You will lost all the data contained in it)
Access the sql lite console, type in terminal
mysql <DB NAME HERE>
Drop table (dont forget the last ; (semicolon))
drop table table_name;
run db:migrate again
bin/rake db:migrate
Hope it helps, it worked for me
If you wanna play safe and don't want to lose any data then you can check if the table exists in your database.
class DeviseCreateUsers < ActiveRecord::Migration
def up
if table_exists?(:users)
# update or modify columns of users table here accordingly.
else
# create table and dump the schema here
end
end
def down
# same approach goes here but in the reverse logic
end
end
The migration is trying to create a table that already exists in your database.
Try to remove the user table from your database. Something went wrong with you migration process. You should also compare your schema.rb version with your db/migrate/*.rb files.
Clarification:
It seems that many SO users don't agree with my reply, either because they consider it inaccurate or not recommended.
Removing a table is always destructive, and I think that everyone understands that.
I should have mentioned add_column, since the table was being created in another migration file.
If you know the database was created properly, you can just comment out the creation part of the migration code. For example:
Class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
# create_table :votes do |t|
#
# t.references :votable, :polymorphic => true
# t.references :voter, :polymorphic => true
#
# t.boolean :vote_flag
#
# t.timestamps
# end
#
# add_index :votes, [:votable_id, :votable_type]
# add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
If the table was created, but later commands weren't completed for some reason, you can just leave the later options for example:
Class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
# create_table :votes do |t|
#
# t.references :votable, :polymorphic => true
# t.references :voter, :polymorphic => true
#
# t.boolean :vote_flag
#
# t.timestamps
# end
add_index :votes, [:votable_id, :votable_type]
add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
If you don't have any significant data in your database to preserve however you can just have it drop the table and all the data and create it fresh. For example (notice the "drop_table :votes", in the self.up):
class ActsAsVotableMigration < ActiveRecord::Migration
def self.up
drop_table :votes
create_table :votes do |t|
t.references :votable, :polymorphic => true
t.references :voter, :polymorphic => true
t.boolean :vote_flag
t.timestamps
end
add_index :votes, [:votable_id, :votable_type]
add_index :votes, [:voter_id, :voter_type]
end
def self.down
drop_table :votes
end
end
Don't delete tables. Data > migrations!
The version of the database already reflects the changes the error-causing migration is trying to add. In other words, if the migration could be skipped, then everything would be fine. Check the db_schema_migrations table and try inserting the version of the erroneous migration (e.x, 20151004034808). In my case this caused subsequent migrations to execute perfectly and everything seems fine.
Still not sure what caused this problem.
If your app is new and you don't care about the data in your database, simply:
rake db:reset
I think this is an issue unique or more common to mysql in rails, possible having to do with the mysql2 gem itself.
I know this because I just switched from sqlite to mysql and just started having this problem systematically.
In my case, I simply commented out the code that had already run and ran the migration again (which I'm not adding more detail to because it looks like the guy above me did that).
I had a similar problem when trying to add Devise authentication to an existing Users table.
My solution: I found that I had two migrate files, both trying to create the Users table. So rather than deleting the table (probably not the best habit to form), I commented out the first (original) migrate file that created the Users table and then left the Devise migrate file as-is. Re-ran the migration and it worked fine.
As it turns out, the Devise file wasn't causing the problem; I can see that it is "changing" the table, not "creating it", which means that even without the devise installation, a db:migrate probably would have caused the same issue (though I haven't tested this).
If you want to keep your data, rename the table, but do it in the migration to save time, then remove it once the migration has ran.
Place at the top part of the up section of the migration file.
rename_table :users, :users2
First
ruby script/generate model Buyer id:integer name:string
after generating Buyer model, I did
rake db:migrate
it was working fine.
After 1 day I have executed below command
ruby script/generate model Seller id:integer seller_name:string
after generating Seller model, I did
rake db:migrate
I got an error, that Buyer table is already exists. why? we have different timestamp file.
class CreateBuyer < ActiveRecord::Migration
def self.up
create_table :buyer do |t|
t.string :name
t.text :description
t.decimal :price
t.integer :seller_id
t.string :email
t.string :img_url
t.timestamps
end
end
def self.down
drop_table :ads
end
end
and another one is
class CreateSellers < ActiveRecord::Migration
def self.up
create_table :sellers do |t|
t.integer :nos
t.decimal :tsv
t.decimal :avg_price
t.timestamps
end
end
def self.down
drop_table :sellers
end
end
I used Rails 2.3.11 and rake 0.8.7
Are you sure there were no errors generated when you ran the first migration? If an error is encountered while running a migration, the parts that were already run will still be in the database, but schema_migrations won't be updated with the migration timestamp. Therefore, the next time you try to run migrations, it'll try to re-run the first part of the failed migration, which will generate errors since it's already been run.
Updated: If you look in the error output you added (by the way, please add to the question rather than a comment, so it's formatted and the whole thing is included) you can see that the first Execute db:migrate is running the migration CreateBuyer. This confirms that your migration did not complete the first time you ran it or has since been unsuccessfully rolled back. To fix this, manually drop the buyer table, then rerun your migrations.
As a note, there's at least a couple issues in your CreateBuyers migration:
The table name should be buyers (plural) rather than buyer (singular)
The down part of the migration is dropping the table ads instead of buyers
The second problem there could explain why you're having trouble running migrations now, actually. If you rolled back the CreateBuyers migration, it would have dropped your ads table and left buyers in place.