Додавання стовпця до існуючої таблиці під час міграції Rails


340

У мене є модель "Користувачі", яка потребує :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

Відповіді:


573

Якщо ви вже запустили оригінальну міграцію (перед її редагуванням), тоді вам потрібно буде генерувати нову міграцію ( rails generate migration add_email_to_users email:stringзробить фокус). Він створить файл міграції, що містить рядок: add_column :users, email, string Потім зробіть a rake db:migrateі запустіть нову міграцію, створивши новий стовпець.

Якщо ви ще не виконали оригінальну міграцію, ви можете просто її відредагувати, як це намагаєтесь зробити. Ваш міграційний код майже ідеальний: вам просто потрібно видалити add_columnрядок повністю (цей код намагається додати стовпчик до таблиці, перш ніж таблиця буде створена, а ваш код створення таблиці вже оновлено, щоб t.string :emailвсе-таки включити його ).


6
Просто, щоб було зрозуміло, ми використовуємо множину? Так це add_email_to_usersі НЕ add_email_to_user?
Purplejacket

9
Правильно. Назви таблиць у Rails завжди множинні (щоб відповідати умовам DB).
camdez

2
Ви також можете використовувати rails db:migrateдля завершального кроку.
Ділан Вандер Берг

Чи можливо створити новий стовпчик на певній позиції в таблиці. Наприклад, якщо я хочу створити нове поле "статус" відразу після наявного поля "електронна пошта"?
neeraj

2
@neeraj у вас, мабуть, є відповідь на даний момент, але для інших шукачів, так, ви можете, як, наприклад, t.string :column_x, limit: 10, after: :column_y(як мінімум, для Rails 4)
244,

123

Використовуйте цю команду на консолі рейок

rails generate migration add_fieldname_to_tablename fieldname:string

і

rake db:migrate

запустити цю міграцію


57

Іноді відбувається rails generate migration add_email_to_users email:stringтака міграція

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

В цьому випадку вам доведеться вручну , то add_columnдля change:

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

А потім біжи rake db:migrate


1) Чи слід rails generate migration add_email_to_users email:stringце запускати після bundle exec rails cабо просто в терміналі? 2) Де розміщується створений файл, коли ми виконуємо запит?
sofs1

28

Ви також можете зробити

rake db:rollback

якщо ви не додали жодних даних до таблиць. Потім відредагуйте файл міграції, додавши до нього стовпець електронної пошти, а потім зателефонуйте

rake db:migrate

Це буде спрацьовувати, якщо у вашій системі встановлені рейки на 3.1.

Набагато простіший спосіб зробити це - зміни, нехай зміна файлу міграції буде такою, якою вона є. використання

$rake db:migrate:redo

Це відкатить останню міграцію та перенесе її знову.


21

Щоб додати стовпець, я просто повинен був виконати наступні кроки:

  1. rails generate migration add_fieldname_to_tablename fieldname:string

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

    rails generate migration addFieldnameToTablename

    Після створення міграції відредагуйте міграцію та визначте всі атрибути, які ви хочете, щоб цей стовпець був доданий.

    Примітка : Імена таблиць у Rails завжди множинні (щоб відповідати умовам DB). Приклад, використовуючи один із згаданих раніше кроків-

    rails generate migration addEmailToUsers

  2. rake db:migrate

Або

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

    Попередження / Примітка

    Майте на увазі, що запуск rake db:schema:loadавтоматично видаляє всі дані у ваших таблицях.


Я це зробив, але це не переробило "риштування" та додало новий стовпчик. Як я можу це зробити "автоматично"?
Джон Вутен

@John Wooten, ви можете видалити ешафот і знову пройти його. Скасуйте відповідні міграції теж.
Afolabi Olaoluwa Akinwumi

щоб додати примітку: зміна схеми без зміни міграції може створити проблеми з іншими розробниками, які підтримують додаток.
BKSpurgeon

3

Коли я це зробив, замість того, щоб замінювати оригінальну міграцію, я створюю новий із стовпцем "Додавання" у верхньому розділі та "Спадним стовпцем" у нижньому розділі.

Ви можете змінити оригінал і повторно запустити його, якщо ви переходите між ними, але в цьому випадку я думаю, що це зробило міграцію, яка не працюватиме належним чином.

Як опубліковано наразі, ви додаєте стовпець, а потім створюєте таблицю.

Якщо ви зміните замовлення, воно може працювати. Або, змінюючи існуючу міграцію, просто додайте її до таблиці створення замість того, щоб робити окремий стовпець для додавання.


1

Ви також можете змусити 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


0

Ви можете відкатати останню міграцію до

rake db:rollback STEP=1

або відкат цієї конкретної міграції на

rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>

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


0

Ви також можете це зробити .. rails g міграція add_column_to_users email: string

потім Rake db: migrate також додає: атрибут електронної пошти у вашому контролері користувача;

для більш детальної інформації див. http://guides.rubyonrails.org/active_record_migrations.html


0

Ви також можете додати стовпець до певної позиції, використовуючи перед стовпцем або після стовпця, наприклад:

rails generate migration add_dob_to_customer dob:date

Файл міграції генерує наступний код, за винятком після:: email. потрібно додати після:: електронну пошту або раніше:: електронну пошту

class AddDobToCustomer < ActiveRecord::Migration[5.2]
  def change
    add_column :customers, :dob, :date, after: :email
  end
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.