Rails 5.2 - как настроить отношения между родительской и типизированной дочерней моделью? - PullRequest
0 голосов
/ 21 июня 2019

У меня есть базовая структура модели, подобная этой:

Template - has_many :cards
Card - belongs_to :template, optional: true

Когда создается Card, пользователь выбирает Template и после его сохранения template_type устанавливается в 'список'.

A Card может иметь только один «список».

Как я могу создать отношение, которое даст мне метод на модели Template, который позволит, учитываяэкземпляр карты, что я могу сделать это:

my_card.list

и из данного экземпляра шаблона (то есть template_type 'список'):

this_template.card

Я думаю, чтотекущая проблема заключается в том, что столбец в шаблонной модели называется template_type, хотя, возможно, он должен был просто называться type.Он реализован в виде перечисления:

enum template_type: { template: 0, list: 1 }

Но также мне нужно определить типизированные отношения на моделях.

То, что я пробовал

Card.rb

  belongs_to :list, class_name: 'Template', optional: true, inverse_of: :owner

Template.rb

  belongs_to :owner, -> { where.template_type[:list] }, inverse_of: :lists

Хотя это позволяет мне сделать

my_card.list

это ноль (хотя m y_card.templateвозвращает шаблон с template_type из «контрольного списка»).

Я предполагаю, что потребуется миграция для добавления owner_id в таблицу шаблонов.Но это не кажется правильным, так как таблица карт уже является полем с именем 'template_id', поэтому все, что мне нужно, это чтобы Rails использовал его для доступа к шаблону (типа 'список'), который к нему принадлежит, через метод с именем checklist,И сделать обратное из шаблона (типа «контрольный список»), чтобы найти его «владеющую» карту.

В качестве второго вопроса, как я могу применить правило, согласно которому карта может иметь только один шаблон типа'list'?

EDIT

Я также прочитал этот вопрос и задаюсь вопросом, стоит ли мне устанавливать отдельную модель с именем List, которая инкапсулируетдомен лучше?

ОБНОВЛЕНИЕ в ответ на комментарий

Список структурно идентичен шаблону, за исключением того, что он может быть «завершен», а шаблон - нет.Пользователь может создать столько списков, сколько ему нужно, из одного шаблона, и каждый список связан с картой, которая отслеживает, что они делают со списком.

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

1 Ответ

0 голосов
/ 21 июня 2019

Для первого вопроса мне пришлось указать Rails использовать существующий внешний ключ:

card.rb

belongs_to :list, class_name: 'Template', foreign_key: 'template_id'

template.rb

has_one :card, inverse_of: :list

Теперь я могу ссылаться на карту из списка и список из карты.Никаких изменений базы данных не требуется.:)

Благодаря @CannonMoyer мне удалось добавить пользовательскую проверку для моего второго вопроса:

  validate :template_is_a_list

  def template_is_a_list
    errors.add(:template, 'must be of type list') unless
       template.template_type == Template.template_types[:list]
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...