Как Полиморфная ассоциация работает с Ecto?
Ecto, похоже, поддерживает полиморфную ассоциацию, когда я читаю https://github.com/elixir-lang/ecto/issues/389 и связанные с ней связанные с ней проблемы.
Скажем, мне нужна ассоциация модели Comment на моделях задач и событий. Если мое понимание связи Ecto с пользовательским источником правильное, тогда нам нужны четыре таблицы и три модели,
Таблица
- Задачи
- События
- tasks_comments
- events_comments
Model
Модель задач и событий будет иметь ассоциацию has_many с пользовательским источником, как показано ниже.
defmodule ExampleApp.Task do
use ExampleApp.Web, :model
schema "tasks" do
field :title, :string
field :body, :string
has_many :comments, {"tasks_comments", Comment}
timestamps
end
end
defmodule ExampleApp.Event do
use ExampleApp.Web, :model
schema "events" do
field :title, :string
field :body, :string
has_many :comments, {"events_comments", Comment}
timestamps
end
end
Теперь, что я не понимаю, как выглядит модель комментария?
Как модель комментария обрабатывает две таблицы? и как он обрабатывает принадлежность к ассоциации с различными моделями?
Ответы
Ответ 1
Если вы идете с приведенным выше дизайном, модель комментария на самом деле не имеет таблицы, ее таблица определяется ассоциацией. Поэтому, чтобы получить все комментарии ко всем событиям, вы можете:
from c in {"events_comments", Comment}
В некоторых случаях это отличная методика, и это позволяет вам не связывать хранилище (таблицу) с моделью. Вы можете использовать ту же модель для разных таблиц.
Однако, если вы хотите получить все комментарии и связать их как с событиями, так и с задачами, вы можете использовать их через отношения. У вас будут "события" ↔ "events_comments" ↔ "комментарии" и "задачи" ↔ "tasks_comments" ↔ "comments".
Другой подход заключается в том, чтобы использовать метод Rails для создания полиморфных ассоциаций и определить столбец "kind" в модели Comment. Это нарушает ссылки на базу данных, но это еще один способ справиться с этим.
Я улучшу документы Ecto по этому вопросу, спасибо за отзыв!