EastsideDev
EastsideDev

Reputation: 6659

Rails migration stopped, even though table does not exist

Rails 6
environment: local development on Mac OS
DB server: MySQL

I deleted all the tables from the DB, and the only tables left in the DB are:

schema_migrations
ar_internal_metadata

I made sure that schema_migrations has no data in it and looked into ar_internal_metadata, and that table has a single row in it, with the following values:

key: environment, value: development

I have several migrations, the most recent one, is devise_create_users.rb.

I am trying to run:

rake db:migrate

But I am getting the error message:

=> rake db:migrate
== 20200317184535 DeviseCreateUsers: migrating ================================
-- create_table(:users)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'users' already exists
/Users/dev/rails/myapp/db/migrate/20200317184535_devise_create_users.rb:5:in `change'

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'users' already exists
/Users/dev/rails/myapp/db/migrate/20200317184535_devise_create_users.rb:5:in `change'

Caused by:
Mysql2::Error: Table 'users' already exists
/Users/dev/rails/myapp/db/migrate/20200317184535_devise_create_users.rb:5:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Process finished with exit code 1


class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      t.datetime :remember_created_at

      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip


      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end

When I check the DB after this, I still don't see a users table, and the schema_migrations table is still empty. In addition, the DeviseCreateUsers migration is the most recent on, so why is it running first.

Any ideas?

Edit:

Based on a comment to the question, I looked at my database.yml file:

default: &default
  host: localhost
  database: <%= ENV['RAILS_DB_NAME'] %>
  username: <%= ENV['RAILS_DB_USER'] %>
  password: <%= ENV['RAILS_DB_PWD'] %>
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  socket: /tmp/mysql.sock

development:
  <<: *default

I made that change last night, and I forgot that my local ENV settings, were for a different project, so Rails was picking up the settings for that project, and was indeed correct, in that the users table is already there. The fix was for me to create project specific ENV settings, for my local development environment

Upvotes: 0

Views: 1246

Answers (2)

Rafayet Monon
Rafayet Monon

Reputation: 1179

When things like this happen it is needed to check the database.yml. As in most cases it happens because of some faulty configuration.

Good thing that just mentioning the database.yml in the comment section of the question helped to find the problem.

Upvotes: 1

Paulo Felipe Souza
Paulo Felipe Souza

Reputation: 386

Using rails console to make sure there is not any users table, try create a new instance of User User.new. If the object was instanciated, your User table is hidden in somewhere. It is not a problem, see all atributtes previously generated and just migrate new ones. I can see in your devise_create_user migration that you can just replace it with something like addColumnstoUser.rb. This will just add the apropriated columns necessary to let Devise runing well.

Choosing this way, inside your migration:

add_column :table_name, :fieldname, :type, in your case, using just one column as an example, it must be: def change add_column :users, :reset_password_token, :string end.

If you are using version controll, such as git, the migration might not know where you can rollback or go ahead. All the migration and rollbacks must stay on the same branch. For example:

1) Adding a new branch to handle user migration: git checkout -b generate-user-model, generating user model rails generate model User name:string email:string and running the migration rails db:migrate will create the users table and will update scheema.rb (check scheema file). Adding it to version controll git add . and `git commit -m "Migrating user model"

2) Moving to a new branch git checkout -b comments-controller, generating a new controller rails generate model Comment. And then migrating it rails db:migrate.

This second migration only teachs scheema.rb how to go ahead and how to rollback on this specifc migration. This last git branch doesn't know nothing about how to rollback the User model, unless you merge a branch inside another git merge generate-user-model.

After many migrations has been used, it's usefull keep using migrations to add or delete tables. Hence, If I had a table called users and I wanted to set it to handle Devise, I just need to generate a new migration with the columns I'd needed. Use https://sqlitebrowser.org/ to help you cheking your database tables and columns.

Upvotes: 0

Related Questions