Как мне управлять отношениями M: N Post-Tag (например, Редактировать / Удалить) - PullRequest
1 голос
/ 29 июля 2010

когда я начал пытаться реализовать это, я застрял.

некоторые бизнес-правила

1 сообщение может иметь много тегов. 1 тег может иметь много сообщений

база данных будет выглядеть так.

  • Посты (id, title, body, ...)
  • Posts_Tags (пост, тег)
  • Теги (id, тег, ...)

когда я вставить - просто

  • теги будут поступать от пользователя как значения, разделенные запятыми
  • explode($tags) для получения отдельных тегов
  • foreach $ tag
    • проверить, существует ли тег
    • если да, получить идентификатор
    • если нет, вставьте тег и получите идентификатор
  • вставить сообщение с тегами

Мне интересно, это лучший способ? могу ли я покончить с циклом chk, если теги существуют? или упростить это в 1 запрос?

обновление пост, abit hardder

  • как я могу проверить, обновил ли пользователь какие-либо теги. другой цикл? но на этот раз будут некоторые изменения (курсив)

  • explode($tags) для получения отдельных тегов

  • foreach $ tag
    • проверьте, был ли этот пост отмечен этим тегом
    • если нет,
      • тег существует?
        • да, получить идентификатор
        • нет, вставьте и получите идентификатор
    • если да, получить идентификатор
  • обновить пост с тегами

хм, ... обновление более запутанно, как вы это реализуете?

Я использую PHP 5.3, Zend Framework 1.10, Doctrine 2

Ответы [ 5 ]

2 голосов
/ 29 июля 2010

Я делаю тэги, очень похожие на ваш обновленный psuedocode, за исключением одного добавленного шага.Вы должны проверить, чтобы убедиться, что для поста нет тегов, которых нет в пользовательском вводе.Например, если сообщение помечено как «php, sql, doctrine», а пользователь меняет тег на «c #, sql, doctrine», вам также необходимо знать, чтобы удалить тег php.

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

2 голосов
/ 29 июля 2010

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

Вставить : сделать то же самое, что вы делаете сейчас, за исключением того, что вы можете получить все теги в одном запросе:

SELECT name FROM tags WHERE name IN ($tags)

Обновление : Самый простой выход: удалить все текущие теги, вставить теги, как будто они все новые. Или ...

$tags = explode(',' $_POST['tags']); // remove whitespaces

# delete all current tags that were not included in the edit
DELETE FROM post_tags WHERE post_id=$post_id AND tag_id NOT IN ($tags)

# find out what the current tags are, use a JOIN to find out their labels
SELECT tag_id FROM post_tags WHERE post_id=$post_id
fetch results, remove found tags from $tags, then
foreach new $tag, insert as if they were new
2 голосов
/ 29 июля 2010

Идея для обновления:

  • Сохранить значение для пользователя JS включено / отключено в скрытом значении
  • Свяжите событие onchange со входом тегов, затем установите для скрытой переменной значение true, чтобы вы знали, что теги изменились
  • Если JS включен и теги изменены, удалите все теги, принадлежащие этому сообщению, затем вставьте фактические теги (как в первую очередь)
    • Откат: если JS отключен, вам нужно проверить представленные теги по сохраненным.
0 голосов
/ 29 июля 2010

Я думаю, что в Учении есть поведение Taggable.Посмотрите на это, это может помочь.

0 голосов
/ 29 июля 2010

Для вашего первого вопроса вы можете упростить вещи в один запрос. SQL (не параметризованный) будет выглядеть примерно так:

SELECT * FROM Tags WHERE name='foo' OR name='bar' OR name='etc'
/* and so on and so forth */

Затем вы можете перебрать свой код PHP, чтобы проверить, какие теги были возвращены; Я бы использовал key_exists ("имя ключа", $ associativeArrayConistingQueryResults).

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

...