Добавление столбца в существующую таблицу при миграции Rails

у меня есть модель пользователей, которым нужен :email столбец (я забыл добавить этот столбец во время начального эшафота).

Я открыл файл миграции и добавил t.string :email, сделал rake db:migrate и получил NoMethodError. Затем я добавил строку

add_column :users, :email, :string

снова rake db:migrate, снова NoMethodError. Я что-то пропустил?

Edit: вот файл миграции.

class CreateUsers < ActiveRecord::Migration  
  def self.up  
    add_column :users, :email, :string  
    create_table :users do |t|  
      t.string :username  
      t.string :email  
      t.string :crypted_password  
      t.string :password_salt  
      t.string :persistence_token  

      t.timestamps  
    end  
  end  

  def self.down  
    drop_table :users  
  end  
end

9 ответов


если вы уже запустили исходную миграцию (перед ее редактированием), то вам необходимо создать новую миграцию (rails generate migration add_email_to_users email:string сделает трюк). Тогда сделайте rake db:migrate и он будет запускать новую миграцию.

если вы еще не запустили исходную миграцию, вы можете просто отредактировать ее, как вы пытаетесь сделать. Переноса кода почти perfect: вам просто нужно удалить add_column строка полностью (этот код пытается добавить столбец в таблицу, прежде чем таблица будет создано, и ваш код создания таблицы уже обновлен, чтобы включить t.string :email в любом случае).


используйте эту команду в консоли rails rails generate migration add_fieldname_to_tablename fieldname:string

и

rake db:migrate для запуска этой миграции


вы также можете сделать

rake db:rollback

Если вы не добавили никаких данных в таблицы.Затем отредактируйте файл миграции, добавив в него столбец электронной почты, а затем вызовите

rake db:migrate

Это будет работать, если в вашей системе установлены rails 3.1.

гораздо более простой способ сделать это изменение пусть изменение в файле миграции будет как есть. использовать

$rake db:migrate:redo.

это приведет к откату последней миграции и перенести его снова.


иногда rails generate migration add_email_to_users email:string производит миграцию, как это

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
  end
end

в этом случае вам нужно вручную добавить дополнительную строку в change

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :email, :string
  end
end

и затем запустить rake db:migrate


чтобы добавить столбец, мне просто нужно было выполнить следующие шаги:

  1. rails generate migration add_fieldname_to_tablename fieldname:string

    альтернатива

    rails generate migration addFieldnameToTablename

    после создания миграции отредактируйте миграцию и определите все атрибуты, которые должны быть добавлены в этот столбец.

    Примечание: имена таблиц в Rails всегда множественное число (в соответствии с соглашениями БД). пример использования одного из упомянутых шагов ранее-

    rails generate migration addEmailToUsers

  2. rake db:migrate

или

  1. вы можете изменить схему с db/schema.rb, добавьте нужные столбцы в SQL-запрос.
  2. выполните эту команду: rake db:schema:load

    Предупреждение/Примечание

    имейте в виду, что работает rake db:schema:load автоматически стирает все данные в таблицах.


когда я это сделал, вместо того, чтобы возиться с исходной миграцией, я создаю новый с помощью только столбца add в разделе up и столбца drop в разделе down.

вы можете изменить оригинал и перезапустить его, если вы мигрируете между ними, но в этом случае я думаю, что это сделало миграцию, которая не будет работать должным образом.

В настоящее время опубликовано, вы добавляете столбец, а затем создать таблицу.

Если вы измените порядок, он может работать. Или, как вы изменяете существующую миграцию, просто добавьте ее в таблицу create вместо отдельного столбца add.


вы также можете заставить столбцы таблицы в таблице с помощью force: true, если таблица уже существует.

пример:

ActiveRecord::Schema.define(version: 20080906171750) do
  create_table "authors", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end

вы можете откатить последнюю миграцию на

rake db:rollback STEP=1

или откат это конкретные миграция по

rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>

и отредактируйте файл, затем запустить rake db:mirgate снова.


вы также можете сделать это .. rails G миграция add_column_to_users email: string

затем rake db: миграция также добавьте: email атрибут в вашем контроллере пользователя;

для более подробной проверкиhttp://guides.rubyonrails.org/active_record_migrations.html