user1431282
user1431282

Reputation: 6835

Rails Migration Not Matching Model

I'm having trouble understanding how migrations update themselves based on the model.

For instance, I have devise set up, and I want to remove the email field and only have a username and password field.

So, I did

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :username, :password
  # attr_accessible :title, :body
end

However, the migration file will not reflect these changes even after

rake db:migrate

or

 rake db:reset

The migration file still has email field

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      ## Database authenticatable
      t.string :email,              :null => false, :default => ""
      t.string :encrypted_password, :null => false, :default => ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, :default => 0
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at

      ## Token authenticatable
      # t.string :authentication_token


      t.timestamps
    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
    # add_index :users, :authentication_token, :unique => true
  end
end

I also trying removing the migration file so that Rails would hopefully know to create a new one. However, this did not work, and the migrations were still been run from somewhere? Where are these migrations been run from? Note that my db/migrate file was empty at the time.

-- create_table("users", {:force=>true})
   -> 0.2476s
-- add_index("users", ["email"], {:unique=>true, :name=>"index_users_on_email"})
   -> 0.1832s
-- add_index("users", ["reset_password_token"], {:unique=>true, :name=>"index_users_on_reset_password_token"})
   -> 0.1832s
-- initialize_schema_migrations_table()
   -> 0.3776s
-- assume_migrated_upto_version(20130320033132, ["/home/Portfolio Rails/portfolio/db/migrate"])
   -> 0.1532s

Upvotes: 0

Views: 209

Answers (2)

Richard Brown
Richard Brown

Reputation: 11436

The migration files are just a paper-trail of the modifications you've made to the schema. Modifying them does nothing to the database itself.

You need to create a migration that removes the email field:

rails generate migration remove_email_from_users email:string
rake db:migrate

Upvotes: 1

user229044
user229044

Reputation: 239301

You've got this all backwards. Migrations are files on disk. They never "update themselves", though you can ask Rails to generate them for you, but it does this based on your input, not on the state of your database or models.

Change doesn't flow from the models to the migrations, it flows from the migrations to the models, via the database. You, the developer, are responsible for causing change to the database by introducing new migrations. If you want to remove a field, you need to create a new migration which drops that column.

Running rake db:migrate does the opposite of what you think it does. It copies state from your migrations, not to them. It will look in db/migrate and see if there are any new files containing instructions on how to modify the state of the database.

Upvotes: 1

Related Questions