У меня есть модель Tag
, и может существовать иерархия из нескольких Tag
s: то есть некоторый Tag
может быть супер- или субтегем другого тега и т. Д.Rails: проверка группы элементов
Примечание: есть не одно большое дерево тегов; это всего лишь несколько отдельных тегов, а иногда один тег - супер-тег для другого одного или нескольких тегов. Он отлично работает.
Каждый Tag
также belongs_to :user
.
Существует ограничение: все Tag
s в иерархии должны принадлежать одному и тому же User
. Я попытался реализовать это ограничение с помощью системы проверки Rails, но мне не удалось. Давайте посмотрим, почему:
Чтобы проверить владельца каждого тега в иерархии, я должен рекурсивно извлекать все супер- и подтеги конкретного тега перед его сохранением.
Предположим, что мы имеем простую иерархию 3 теги:
tag1 -> tag2 -> tag3
Каждый из этих тегов принадлежит одному и тому же пользователю (например, «user1»).
В один прекрасный день мне нужно сменить владельца на «user2». На самом деле невозможно, чтобы пользователи проверяли всю иерархию перед сохранением каждого тега.
Скажем, я пытаюсь сделать что-то вроде этого:
tag1.owner = user2
tag2.owner = user2
tag3.owner = user2
, а затем сохранить каждую метку. Но когда я пытаюсь сохранить первый тег, все остальные еще не сохранены, а пользователь, хранящийся в БД для этих тегов, - «user1». Проверка не выполняется.
Решение может заключаться в том, чтобы сохранить сразу все теги (как одну «транзакцию»), а затем проверить все теги, затронутые этой транзакцией, и если все они действительны, то совершите транзакцию; в противном случае откат. Это было бы просто идеально, и это может выглядеть синтаксически как-то так:
tag1.owner = user2
tag2.owner = user2
tag3.owner = user2
transaction do
tag1.save
tag2.save
tag3.save
end
И это все! Но, насколько я знаю, в Rails ничего подобного не поддерживается. Но какова лучшая практика для того, чтобы делать то, что мне нужно? В настоящее время я просто отключил эту проверку, но мне не очень нравится это «решение».