Ecto.Migration с ограничением - ребенок / родитель - PullRequest
0 голосов
/ 16 мая 2018

У меня есть приложение в Elixir с новостями, которое пользователь должен иметь возможность комментировать.Вот моя миграция для создания функциональности комментариев:

def change do
  create table(:news_comments, primary_key: false) do
    add :id, :uuid, primary_key: true
    add :news_id, references(:news, type: :uuid, on_delete: :nilify_all)
    add :comment_id, references(:comments, type: :uuid, on_delete: :nilify_all)
    add :parent_comment_id, references(:comments, type: :uuid, on_delete: :nilify_all)
  end
end

Я хочу разрешить комментарии к комментариям и делаю это с ограничением.Пользователь может комментировать новости, отправив news_id и comment_id.Я хочу разрешить отправлять подкомментарии, которые я хочу разрешить только для тех же новостей.Так что мне нужно уникальное ограничение для news_id и comment_id, никаких проблем до сих пор.Но когда пользователь отправляет подкомментарий, я хочу заверить, что подкомментарий содержит news_id и parent_comment_id, которые уже сохранены в базе данных.Допустим, я получил news_comment с news_id = 1 и comment_id = 1, база данных должна разрешать только вставки с news_id = 1 и parent_comment_id = 1.Я не хочу обрабатывать этот случай в коде, потому что я думаю, что база данных может справиться с этим.Не будет проблем с хранимой процедурой, но должен быть способ достичь этого с ограничением, но не знаю, как.

Следующий случай, который должно обрабатываться ограничением, - разрешить только комментарии к комментариям без комментариев.parent_comment_id, потому что я не хочу разрешать под-комментарии для под-комментариев, например, комментировать youtube.Несколько ограничений в порядке, просто нужно решение, иначе мне нужно обработать его внутри моего кода с помощью некоторых запросов к базе данных, которых я бы хотел избежать.

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 мая 2018
def up do
  execute "ALTER TABLE news_comments 
  ADD CONSTRAINT uc_news_comment UNIQUE (news_id, comment_id);"

  execute "ALTER TABLE news_comments 
  ADD FOREIGN KEY (news_id, parent_comment_id) 
  REFERENCES news_comments(news_id, comment_id);"
end

сделал работу.

0 голосов
/ 16 мая 2018

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

Вместо того чтобы идти ...

news <- news_comments -> comment <- news_comments -> comment

... вы могли бы пойти ...

news <- comment <- subcomment

... у которых были бы таблицы как ...

def change do
  create table(:comments, primary_key: false) do
    add :id, :uuid, primary_key: true
    add :news_id, references(:news, type: :uuid, on_delete: :nilify_all)
    add :body_text_or_whatever, :text
  end

  create table(:subcomments, primary_key: false) do
    add :id, :uuid, primary_key: true
    add :comment_id, references(:comments, type: :uuid, on_delete: :delete_all)
    add :body_text_or_whatever, :text
  end
end

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

...