Rails: додавання індексу після додавання стовпця


119

Припустимо, я створив таблицю tableв додатку Rails. Через деякий час я додаю стовпчик, що працює:

rails generate migration AddUser_idColumnToTable user_id:string. 

Тоді я розумію, що мені потрібно додати user_idяк індекс. Я знаю про add_indexметод, але де слід називати цей метод? Я повинен запустити міграцію (якщо так, то яку?), А потім додати цей метод вручну?

Відповіді:


235

Ви можете запустити ще одну міграцію, лише для індексу:

class AddIndexToTable < ActiveRecord::Migration
  def change
    add_index :table, :user_id
  end
end

4
Тому я просто запускаюсь у своїй консолі: рейки генерують міграцію AddIndexToTable?
користувач1611830

3
Так, ви можете це зробити, але вам доведеться згодом відредагувати цю міграцію, щоб відобразити наведений вище код.
Jaap Haagmans

Чи: таблиця повинна бути множиною?
гробниця

1
@tomb Я використав приклад з оригінального запитання. :tableце фактичне ім'я таблиці, так і в разі usersтаблиці, потрібно замінити :usersна :table.
Jaap Haagmans

65

Якщо вам потрібно створити, user_idтоді було б обґрунтованим припущенням, що ви посилаєтесь на таблицю користувачів. У цьому випадку міграція повинна бути:

rails generate migration AddUserRefToProducts user:references

Ця команда генерує таку міграцію:

class AddUserRefToProducts < ActiveRecord::Migration
  def change
    add_reference :user, :product, index: true
  end
end

Після запуску rake db:migrateобидва user_idстовпця та індексу будуть додані до productsтаблиці.

У разі , якщо вам просто потрібно додати індекс до існуючого колонку, наприклад , nameз userтаблиці, наступний метод може бути корисним:

rails generate migration AddIndexToUsers name:string:index створить таку міграцію:

class AddIndexToUsers < ActiveRecord::Migration
  def change
    add_column :users, :name, :string
    add_index :users, :name
  end
end

Видаліть add_columnрядок і запустіть міграцію.

У описаному випадку ви могли б видати rails generate migration AddIndexIdToTable index_id:integer:indexкоманду, а потім видалити add_columnрядок із створеної міграції. Але я рекомендую скасувати початкову міграцію та замість цього додати посилання:

rails generate migration RemoveUserIdFromProducts user_id:integer
rails generate migration AddUserRefToProducts user:references

Дякую Вадиму за повну відповідь. Останнє питання: чому ви рекомендуєте скасувати початкову міграцію? Чи є якісь проблеми ефективності, пов’язані з додаванням індексу згодом?
Флавіо Уенше

2
Для @fwuensche: пізніше за додавання індексу не передбачено покарання за ефективність. Логіка домену буде менш зрозумілою. Наприклад, якщо згодом ви вирішите розірвати / абстрагуватись тощо, вам потрібно буде мати справу з двома окремими міграціями, які справді повинні були бути єдиними ...
Вадим Тиєміров,

6
УВАГА: Зауважте, що index: true працює лише під час міграції create_table. Міграція буде виконуватися, але індекс не буде створений. Дивіться makandracards.com/makandra/…
rmcsharry

9

Додати в створену міграцію після створення стовпця наступне (приклад)

add_index :photographers, :email, :unique => true

ти маєш на увазі щось подібне: def self.up add_column ... end add_index ...?
користувач1611830

5

За довідками можна зателефонувати

rails generate migration AddUserIdColumnToTable user:references

Якщо в майбутньому вам потрібно додати загальний індекс, ви можете запустити його

rails g migration AddOrdinationNumberToTable ordination_number:integer:index

Створити код:

class AddOrdinationNumberToTable < ActiveRecord::Migration
  def change
   add_column :tables, :ordination_number, :integer
   add_index :tables, :ordination_number, unique: true
  end
end

0

Ви можете використовувати це, просто подумайте, що Job - це назва моделі, до якої ви додаєте індекс cader_id :

class AddCaderIdToJob < ActiveRecord::Migration[5.2]
  def change
    change_table :jobs do |t|
      t.integer :cader_id
      t.index :cader_id
    end
  end
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.