Модельная ассоциация меняет производственную среду, в частности, преобразовывает модель в полиморфную? - PullRequest
1 голос
/ 12 мая 2010

Я надеялся, что смогу получить отзывы о серьезных изменениях в работе модели в уже запущенном приложении.

В моем случае у меня есть модель записи, которая имеет номера телефонов.

В настоящее время это типичная ассоциация has_many Proper_to с записью, имеющей много номеров телефонов.

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

Я мог бы просто добавить user_record_id к модели PhoneNumber, но не лучше ли, чтобы это была полиморфная ассоциация?

И если так, если вы измените способ ассоциирования модели, как, черт возьми, я буду обновлять производственную базу данных, не нарушая все? >. <</p>

В любом случае, просто ищите лучшие практики в такой ситуации.

Спасибо!

Ответы [ 2 ]

1 голос
/ 12 мая 2010

В этом вам могут помочь два подхода.

Одним из них является введение промежуточной модели, которая обрабатывает наборы телефонных номеров. Таким образом, ваши Record и UserRecord могут принадлежать к этой модели коллекции, и оттуда могут быть связаны номера телефонов и другая контактная информация. У вас получаются отношения, которые выглядят так:

class Record < ActiveRecord::Base
  belongs_to :address_book
  delegate :phone_numbers, :to => :address_book
end

class UserRecord < ActiveRecord::Base
  belongs_to :address_book
  delegate :phone_numbers, :to => :address_book
end

class AddressBook < ActiveRecord::Base
  has_many :phone_numbers
end

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

Альтернатива состоит в том, чтобы сделать UserRecord производным от STI типом записи, чтобы вам не приходилось иметь дело с двумя разными таблицами при определении связей.

class Record < ActiveRecord::Base
  has_many :phone_numbers
end

class UserRecord < Record
end

Обычно все, что вам нужно сделать, это ввести строковый столбец типа в вашу схему, и вы можете использовать STI. Если срок действия записей UserRecord истекает через определенное время, можно легко удалить их, используя что-то вроде:

UserRecord.destroy_all([ 'created_at<=?', 7.days.ago ])

Используя подход STI, вы должны быть осторожны, чтобы ограничить выбор, чтобы вы извлекали только постоянные или временные записи в зависимости от того, что вы собираетесь делать. Поскольку UserRecord является производным от Record, вы обнаружите, что они также загружаются при загрузках по умолчанию, таких как:

@records = Record.find(:all)

Если это вызывает проблему, вы всегда можете использовать Record в качестве абстрактного базового класса и создать производный класс PermanentRecord, чтобы исправить это:

class PermanentRecord < Record
end

Обновите во время миграции, используя что-то вроде:

add_column :records, :type, :string
execute "UPDATE records SET type='PermanentRecord'"

Тогда вы можете использовать PermanentRecord вместо Record для всего вашего существующего кода, и он не должен непреднамеренно извлекать записи UserRecord.

0 голосов
/ 12 мая 2010

Страница обслуживания - ваш ответ.

  1. Создание миграции, которая обновляет структуру таблицы и обновляет существующие данные. Если вы против обновления данных в миграциях - используйте rake task.
  2. Отключить веб-доступ (создать страницу обслуживания)
  3. Развертывание нового кода
  4. Запуск отложенных миграций
  5. Обновить данные
  6. Включить веб-доступ (удалить страницу обслуживания).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...