Добавление столбца в существующую таблицу при миграции Rails
У меня есть модель Users, которая нуждается в столбце :email
(я забыл добавить этот столбец во время начального эшафот).
Я открыл файл миграции и добавил t.string :email
, сделал rake db:migrate
и получил NoMethodError
. Затем я добавил строку
add_column :users, :email, :string
снова rake db:migrate
, снова NoMethodError
. Я пропустил здесь шаг?
Изменить: здесь файл миграции.
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
Ответы
Ответ 1
Если вы уже выполнили первоначальную миграцию (перед ее редактированием), вам необходимо сгенерировать новую миграцию (rails generate migration add_email_to_users email:string
выполнит трюк). Затем выполните rake db:migrate
, и он запустит новую миграцию.
Если вы еще не выполнили первоначальную миграцию, вы можете просто ее отредактировать, например, вы пытаетесь сделать. Ваш код перехода почти идеален: вам просто нужно полностью удалить строку add_column
(этот код пытается добавить столбец в таблицу, прежде чем таблица будет создана, и код создания таблицы уже был обновлен, включив в него t.string :email
).
Ответ 2
Используйте эту команду в консоли rails
rails generate migration add_fieldname_to_tablename fieldname:string
и
rake db:migrate
для выполнения этой миграции
Ответ 3
Вы также можете сделать
rake db:rollback
если вы не добавили никаких данных в таблицы. Затем отредактируйте файл миграции, добавив к нему столбец электронной почты, а затем вызовите
rake db:migrate
Это будет работать, если в вашей системе установлены направляющие 3.1.
Более простой способ сделать это - изменить, чтобы изменения в файле миграции были такими, какие есть.
используйте
$rake db:migrate:redo
.
Откроется последняя миграция и снова перенесется.
Ответ 4
Чтобы добавить столбец, мне просто нужно было выполнить следующие действия:
-
rails generate migration add_fieldname_to_tablename fieldname:string
Alternative
rails generate migration addFieldnameToTablename
Как только миграция будет сгенерирована, отредактируйте перенос и определите все атрибуты, которые вы хотите добавить в этот столбец.
Примечание. Названия таблиц в Rails всегда множественны (чтобы соответствовать соглашениям DB). Пример использования одного из шагов, упомянутых ранее -
rails generate migration addEmailToUsers
-
rake db:migrate
Или
- Вы можете изменить схему в
db/schema.rb
, добавить столбцы в SQL-запрос.
-
Запустите эту команду: rake db:schema:load
Предупреждение/Примечание
Имейте в виду, что при запуске rake db:schema:load
автоматически стираются все данные в ваших таблицах.
Ответ 5
Когда я это сделал, вместо того, чтобы запускать первоначальную миграцию, я создаю новую, только с столбцом добавления в разделе "вверх" и столбцом "drop" в нисходящем разделе.
Вы можете изменить оригинал и повторно запустить его, если вы переместитесь между ними, но в этом случае я думаю, что он сделал миграцию, которая не будет работать должным образом.
Как и в настоящее время, вы добавляете столбец, а затем создаете таблицу.
Если вы измените порядок, это может сработать. Или, изменив существующую миграцию, просто добавьте ее в таблицу create вместо отдельного столбца добавления.
Ответ 6
Вы можете отменить последнюю миграцию на
rake db:rollback STEP=1
или отмените эту конкретную миграцию
rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>
и отредактируйте файл, затем запустите rake db:mirgate
снова.
Ответ 7
Вы также можете это сделать. rails g migration add_column_to_users email: string
тогда rake db: migrate также добавьте в свой пользовательский контроллер атрибут email:
для более подробной информации http://guides.rubyonrails.org/active_record_migrations.html
Ответ 8
Вы также можете принудительно использовать таблицы в таблице с помощью 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