Миграция Rails: используйте другой столбец в качестве идентификатора - PullRequest
1 голос
/ 11 июля 2011

Я только начинаю изучать миграции на Rails.У меня есть таблица с именем tags со столбцом name [строка] (и с автоматически сгенерированным столбцом id).Я хочу перенести его так, чтобы таблица использовала столбец name в качестве id и первичный ключ.Как мне сделать так, чтобы все существующие записи работали с новой схемой?

1 Ответ

3 голосов
/ 11 июля 2011

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

  1. Убедитесь, что ваш столбец имени уникален для всех записей
  2. Найдите все другие объекты, которые хранят ссылку на ваш объект, и измените их с id на name.

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

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

В качестве примера предположим, чтоэто ваша модель вокруг таблицы тегов:

class Tag < ActiveRecord::Base
end

Предположим, у вас есть по крайней мере эта другая модель, Thing, которая имеет простую связь с моделью тегов:

class Thing < ActiveRecord::Base
   has_one :tag
end

Естьстолбец tag_id в таблице вещей.Я бы добавил столбец с именем tag_name, изменил бы ассоциацию, чтобы иметь внешний ключ, указывающий на этот новый столбец ...

class Thing < ActiveRecord::Base
  has_one :tag, :foreign_key => "tag_name"
end

Это говорит Rails, что связь между этими вещами происходит через новый столбец.По соглашению он будет искать «tag_id».

Учитывая это изменение, вы можете перейти к миграции и:

add_column :things, :tag_name, :string

Thing.all.each do |thing| 
  if thing.tag
    thing.tag_name = thing.tag.name
  end
end

remove_column :things, :tag_id

Это быстрый и грязный пример, и я мог что-то пропустить.Ключевым моментом является добавление нового столбца, перемещение ассоциации, удаление старого столбца.

Существуют и другие сценарии, например, случай, когда модель участвует в ассоциации «многие ко многим» или в некоторой полиморфной ассоциации, нообщий подход был бы аналогичным в этих случаях.

...