Ruby on Rails - rake db:migrate不起作用

时间:2015-08-02 20:12:25

标签: mysql ruby-on-rails database

我正在使用def change作为模型。这是我的模型的迁移输出:

$ rake db:migrate
== 20150802221545 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.3319s
== 20150802221545 CreateUsers: migrated (0.3322s) =============================

== 20150802221550 CreatePages: migrating ======================================
-- create_table(:pages)
   -> 0.2457s
-- add_index(:pages, :subject_id)
   -> 0.2487s
-- add_index(:pages, :permalink)
   -> 0.2464s
== 20150802221550 CreatePages: migrated (0.7416s) =============================

== 20150802221558 CreateSubjects: migrating ===================================
-- create_table(:subjects)
   -> 0.2453s
== 20150802221558 CreateSubjects: migrated (0.2456s) ==========================

== 20150802221603 CreateSections: migrating ===================================
-- create_table(:sections)
   -> 0.2776s
-- add_index(:sections, :page_id)
   -> 0.2484s
== 20150802221603 CreateSections: migrated (0.5265s) ==========================

现在,我创建了一个名为 AlterUsers 的迁移,并编写了以下代码。

 - class AlterUsers < ActiveRecord::Migration
  def change
        reversible do |dir|
        dir.up {
            rename_table :users, :admin_users
            add_column :admin_users, :username, :string, :limit => 25
            #add_column("admin_users", "username", :string, :limit => 25)
            change_column :admin_users, :email, :string, :limit => 100
            #change_column("admin_users", "email", :string, :limit => 100)
            rename_column :admin_users, :password, :hashed_password
            #rename_column("admin_users", "password", "hashed_password")
            add_column :admin_users, :salt, :string, :limit => 40
            #add_column("admin_users", "salt", :string, :limit => 40)
            puts "*** about to add index ***"
            add_index :admin_users, :username
            #add_index("admin_users", "username")
        }

        dir.down{

            remove_index :admin_users, :username
            remove_column :admin_users, :salt
            rename_column :admin_users, :hashed_password, :password
            change_column :admin_users, :email, :string, :default=> "", :null => false
            remove_column :admin_users, :username, :string, :limit => 25
            raname_table :admin_users, :users
        }
    end
  end
end

我使用的是def change,因为我使用的是rails4。但是rake db:migrate不会影响数据库。然后我写了相同的代码作为教师的代码:

    class AlterUsers < ActiveRecord::Migration
  def self.up
        rename_table :users, :admin_users
        add_column :admin_users, :username, :string, :limit => 25
        change_column :admin_users, :email, :string, :limit => 100
        rename_column :admin_users, :password, :hashed_password
        add_column :admin_users, :salt, :string, :limit => 40
        puts "*** about to add index ***"
        add_index :admin_users, :username
    end

  def self.down
        remove_index :admin_users, :username
        remove_column :admin_users, :salt
        rename_column :admin_users, :hashed_password, :password
        change_column :admin_users, :email, :string, :default=> "", :null => false
        remove_column :admin_users, :username, :string, :limit => 25
        raname_table :admin_users, :users
  end
end

有效。完成所有这些迁移后,我尝试使用此命令rake db:migrate VERSION=0进行撤消。但它不起作用。这是db迁移状态:

$ rake db:migrate:status

database: mysqlapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20150802221545  Create users
   up     20150802221550  Create pages
   up     20150802221558  Create subjects
   up     20150802221603  Create sections
   up     20150802221735  Alter users

这里是rake db:migrate --trace输出

$ rake db:migrate --trace
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:migrate
** Invoke db:_dump (first_time)
** Execute db:_dump
** Invoke db:schema:dump (first_time)
** Invoke environment 
** Invoke db:load_config 
** Execute db:schema:dump

除了上述问题,我现在还有以下主要查询。 1)rake db:migrate在哪些情况下不影响? (我很困惑,因为它的工作行为) 2)如何重做撤消/回滚迁移?

1 个答案:

答案 0 :(得分:0)

您应该将其拆分为多个迁移。只需使用change并让rails处理创建反向迁移。

<强>假设:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :email
      t.string :password
      t.timestamps null: false
    end
  end
end

<强>迁移

class ChangeUsersTable < ActiveRecord::Migration
  def change
    rename_table :users, :admin_users
  end
end
class AddHashedPasswordToAdminUsers < ActiveRecord::Migration
  def change
     # you should not just migrate the plaintext passwords!
    remove_column :admin_users, :password, :string
    add_column :admin_users, :password_hash, :string
    add_column :admin_users, :salt, :string, limit: 40
  end
end
class AddUserNameToAdminUser < ActiveRecord::Migration
  def change
    add_column :admin_users, :username, :string
  end
end

<强>结果:

ActiveRecord::Schema.define(version: 20150802210303) do   
  create_table "admin_users", force: :cascade do |t|
    t.string   "email"
    t.datetime "created_at",               null: false
    t.datetime "updated_at",               null: false
    t.string   "password_hash"
    t.string   "salt",          limit: 40
    t.string   "username"
  end
end

不要滚动自己的密码加密!

我还建议您使用has_secure_password而不是滚动自己的密码加密。它很容易弄乱它。

在这种情况下,迁移将是:

class AddPasswordDigestToAdminUsers < ActiveRecord::Migration
  def change
     # you should not just migrate the plaintext passwords!
    remove_column :admin_users, :password, :string
    add_column :admin_users, :password_digest, :string 
    # has_secure_password concatenates the salt into the digest.
    # no salt column needed.
  end
end