Замена устаревшей модели на новую с тем же именем - PullRequest
1 голос
/ 12 февраля 2020

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

Я хочу сделать его полностью невидимым для внешних целей, JSON API, желательно даже уровень контроллера, чтобы эти модели не имели имени таблицы по умолчанию. Но я не могу понять окончательный кусок головоломки. наложение внешних ключей без создания цепочки и разрыва всего этого.

Итак, у меня есть две таблицы. Старая таблица perfections, с которой я буду мигрировать, но, к сожалению, не в одну go. Затем новая таблица imperfections, которая будет вступать во владение.

Я могу легко замаскировать имена таблиц:

class Perfection < ApplicationRecord
  self.table_name = "imperfections"
end
class LegacyPerfection < ApplicationRecord
  self.table_name = "perfections"
end

Хотя модели с внешним ключом к ним. Это моя проблема. На самом деле у меня есть одна проблемная модель. Это относится к обеим этим моделям. Я могу присвоить псевдониму только один из внешних ключей, чтобы он выглядел так, как я хочу, извне, но, совмещая оба, я получаю цепочку псевдонимов из-за общего имени. , Псевдонимы фактически делают эквивалент этого (и больше для получателей и прочего)

class OtherThing < ApplicationRecord
  belongs_to :perfection, foreign_key: :imperfection_id
  belongs_to :legacy_perfection, foreign_key: :perfection_id, optional: true

  def legacy_perfection_id=(value)
    self.perfection_id = value
  end
  def perfection_id=(value)
    self.imperfection_id = value
  end
end

Если я позвоню other_thing.legacy_perfection_id = 1, это число будет сохранено в imperfection_id.

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

Пока я сделаю преобразование в контроллере, но я бы хотел, чтобы оно было еще чище.

1 Ответ

2 голосов
/ 12 февраля 2020

Входные параметры, передаваемые вашей модели, на самом деле не связаны с ее атрибутами или столбцами - они связаны с методами установки. assign_attributes в основном просто делает:

attributes.each do |k, v|
  send("#{k}=", v)
end

Таким образом, если вы хотите, чтобы модель принимала new_attribute в качестве входных данных, но все же присваивает старый атрибут, вы можете сделать это с помощью:

def new_attribute=(value)
  self.old_attribute = value
end

В некоторых случаях может быть полезно иметь адаптеры. Например, если API v1 принимает old_attribute, а API v2 принимает new_attribute. Чтобы разница не просочилась в слой модели, вы добавляете адаптер, который преобразует параметры перед их назначением. На самом деле это проблема контроллера в MVC, так как контроллер отвечает за принятие пользовательского ввода и передачу его моделям.

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