Связывание нодов "многие ко многим" при помощи CCK
На семинаре по Друпалу я приводил пример связывания документов с помощью модуля CCK: есть ноды типа "авто", есть ноды типа "деталь для авто". Для всех авто можно указать список деталей, из которых автомобиль состоит, для всех деталей можно указать в каких автомобилях эта деталь используется. Далее, при просмотре соответствующего документа можно увидеть список все связанных нод.
Этот пример вызвал ряд вопросов, по этому здесь я более подробно опишу как реализовать такую связь.
1. Для начала нужно скачать модуль CCK и скопировать его в папку "sites/all/modules". Далее в меню "admin/build/modules" необходимо активировать модуль Content и Node Reference. Это минимально необходимые для моего примера модули, однако стоит активировать и все остальные пункты из группы CCK, так как они могут оказаться полезными для других целей.
2. Теперь нужно создать типы материалов, которые мы будем друг с другом связывать. Для этого в меню Content types ("admin/content/types") нужно выбрать таб "Add content type" и создать тип материала с человекопонятным именем (Name) "Автомобиль" и компьютеропонятным именем (Type) "auto", сохранить изменения и создать еще один тип контента с Name = "Деталь автомобиля" и Type = "auto_detail".
3. После того как мы создали новые типы материалов в них нужно добавить поля, которые свяжут автомобили и детали друг с другом. В меню Content types необходимо щелкнуть по ссылке"Edit" возле типа конетнта "Автомобиль", и выбрать таб "Add field". В строке "Name" надо задать машиннопонятное имя для создаваемого поля, например "auto_detail", а в качестве Field Type выбрать Node Reference, Autocomplete Text Field. После нажатия кнопки Create Field можно задать человекопонятное название для этого поля, выбрать будет ли поле обязательным и можно ли будет в него вносить несколько значений. Также надо указать, что это поле будет связано (Content types that can be referenced) с типом материала "Деталь автомобиля".
Те же действия, надо проделать и для типа "Деталь автомобиля", только в качестве машиннопонятного имени нового поля указать надо "auto", а в качестве типа связанного материала – "Автомобиль".
4. Вот и все. Теперь можно создать материал типа "Автомобиль" (пока привязывать его не к чему), затем создать материал типа "Деталь автомобиля" и привязать его к существующему авто. После того как "Деталь автомобиля" создана можно вернуться в наш первый "Автомобиль" и связать его с этой деталью.
5. Для того, чтобы кастомизировать стандартный вывод "связанных" ссылок, в папке темы скопируйте файл node.tpl.php под именем node-auto.tpl.php и используйте в нем переменные вида:
<?php
// Цикл по всем связанным нодам
for($i = 0; $i <= count($node->field_auto_detail) - 1; $i++){
print "nid = " . $node->field_auto_detail[$i]['nid'] . "
";
print "view = " . $node->field_auto_detail[$i]['view'] . "
";
}
?>
У этого примера есть один недостаток: если материал А связан с материалом Б, то это не значит, что материал Б связан с материалом А. Другими словами, если мы связали А с Б, но не связали Б с А, то на странице А будет ссылка на Б, но на странице Б не будет ссылки на А.
Если эту задачу решать с помощью Node API, то эту особенность CCK можно обойти.
update от direqtor:
Есть же тип поля для CCK - Node Referer вроде бы. Автоматом создает обратные ссылки на те материалы, которые ссылаются на данный: http://drupal.org/project/nodereferrer.
Так что проблема "односторонних" связей решена.
- Блог
- Войдите или зарегистрируйтесь, чтобы отправлять комментарии
Комментарии
http://drupal.ru/node/12245
У меня был случай, когда требовалось показать дом со всеми его характеристиками и выдать инфу обо всех квартирах в этом доме. Квартира представляла собой отдельный тип материала с CCK полями. Я задействовал такой же механизм, но использовал модуль для внедрения видов в ноду, с аргументом по NID. В результате, выводилась вся инфа по дому, а внизу был табличный вид с подробной инфой по квартирам.
Есть же тип поля для CCK - Node Referer вроде бы. Автоматом создает обратные ссылки на те материалы, которые ссылаются на данный.
Во, нашел http://drupal.org/project/nodereferrer
direqtor, спасибо Мне всегда как-то проще было нод апи использовать, по этому не знал о таком модуле...
Все уже придумано до нас!
http://drupal.ru/node/12423
Огаога, и версия там старая девелоперская.
Я таки жажду увидеть радостное альтернативное решение.. -)
>Если эту задачу решать с помощью Node API, то эту особенность CCK можно обойти.
А можно поподробнее на этом моменте?.. -)
Ромка, что-то такой способ не сильно хорош:
"Теперь можно создать материал типа "Автомобиль" (пока привязывать его не к чему), затем создать материал типа "Деталь автомобиля" и привязать его к существующему авто. После того как "Деталь автомобиля" создана можно вернуться в наш первый "Автомобиль" и связать его с этой деталью."
Не слишком много переходов туда сюда?
Стандартными средставми можно сделать только так, хотя при желании можно написать свой модуль, который реализует любую другую логику. Главное придумать какую. Ведь если ноды типа "деталь" еще нету, то и ссылаться из ноды типа "авто" не на что...
Следовало-бы сделать так:
Создаем авто, далее создаем деталь и указываем, что она относится к данному авто и при этом в материал авто также заносится ссылка на эту деталь(автоматически). Вот это удобно.)
Так это и делается при помощи Nodereferer, смотри обновление в первом посте.
Может я что-то не так понял.. но по ссылке из первого поста используется Node Reference, а Nodereferer это какой-то другой модуль.. -)
Если я прав, то скорее всего произошла путаница из-за похожего названия модулей..
Мдаа если ты сам заполняешь базу таким образом, оно может ещё и сойдёт, а вот пользователям такой механизм уже конечно не откроешь. -(
Мне как раз нужно разобраться как делать двойные связи и чтобы сцылки автоматом и там и там были, чтоб как по уставу. -)
По мне, так он просто не договорил, ибо имхо вся соль теммы в >Если эту задачу решать с помощью Node API, то эту особенность CCK можно обойти. -)
На мой взгляд здесь оочень многим необходим пример взаимного связывания документов за один заход.
Выше direqtor привел ссылку на модуль nodereferer, который как раз и реализует этот функционал. Ну а с использованием нод АПИ действительно можно сделать все по своему желанию, главное сформулировать это свое желание
Есть же модуль...
Ни к чему истреблять воробьев ядерными боеголовками.
Нет, ошибки нет. Node reference позволяет связать ноду А с нодой В, а Node referer автоматически свяжет ноду В с нодой А.
Чтобы пример был понятен приведу со своего проекта.
Тип материала Объявление
Одно: http://trade.asiadata.ru/ru/node/281
Второе: http://trade.asiadata.ru/ru/node/40
Внизу через Node REFERENCE показывается тизер фирмы его разместившей.
Тип материала: Фирма - http://trade.asiadata.ru/ru/node/37
Внизу список всех ее объявлений через поле Node REFERER
При размещении объявления выбирается Фирма, а ссылка в самой Фирме создается автоматом.
Применительно к автомобилям и деталям оба поля можно сделать многозначными.
Тогда в одной детали можно ссылаться на несколько авто. Тогда в каждом автомобиле можно видеть список запчастей.
Вообще, во-многом эта связка Reference - Referer выполняет таксономические задачи.
блин, давно надо было это.
ГЫ, а мне тут как раз сегодня поступил заказ на сайт для торговцев запчастями... Маленький, правда.
а может ли обычный пользователь создавать связь? или это прерогатива только админа? Например, связь со своей анкетой юзера и определенной нодой?
Да, может.
Модуль под 6й не работает?
Я правильно понял что для его использования нужен CKK + Node Reference + собственно он сам?
а Node Relativity не подошло?
А Node Relativity кстати говоря дурной совсем, я его тестировал...
Меню действий над дочерними нодами находиться прямо в ноде и там ссылки присоединения, ссылка там имеет вид, отличный от простого создания ноды добавлением к концу ссылки пометки принадлежности к нод релативити...
Так вот трабла заключается в том, что если создавать материал не с той менющки, то не будет возможности присоединить ноду, а зарегистрированный польщователь не видит этого меню и воспользоваться присоединением не может, что было для меня обломно.. хотя в той менюшке я видел ссылку как я понял на присоединения ноды, полагаю, что механизм макой - пользователь создаёт ноду обычным способом, а админ потом смотрит и присоединяет, жаль только у меня по этой ссылке не генерился список созданных и ещё не присоединённых нод..
Вобщем я опплевался. -)
Toshka, какую то ерунду вы пишете, вы видимо просто не поняли, что правом присоединенияк ноде имеет только хозяин НОДЫ - то есть вы создали Автомобиль - и только вы имеете право присоединить к ней детали, и никто другой. Чё вы понаписали - непонятно....
Так есть же уже модуль Node Relativity ! Смысл ?
Я использую для связей :
1) CCK ( http://drupal.org/project/cck ), поле node reference
2) Для обратной ссылки viewfiled ( http://drupal.org/project/viewfield ) и ReferencedByFilter ( http://drupal.org/project/ReferencedByFilter )
Этот подход не требует обратного связывания.
Вопрос к sas@drupal.org: можно уточнить ваши настройки view модуля ReferencedByFilter?
Если я правильно понял, то при передаче этому view номера ноды должен высыпаться список нод, которые на переданную ссылаются.
У меня при просмотре этого view с переданным номером ноды, на которую гарантированно ссылается лишь одна другая нода, вываливаются все опубликованные ноды. Хэлп по этому модулю куцый (только readme.txt), видимо я что-то не так прописал. Заранее благодарю!
realizator@drup..
Фильтруются материалы в которых используется поле reference - это фильтр для обратного выбора
А все таки как организовать ответную ссылку на 6 версии Drupal?
я для равнозначных связей использовал relateditems (в issues есть версия для 6 ветки)
Топик старый, но вдруг кому-то понадобиться.
На мой взгляд лучше честно, добавлять обратные ссылки, к текущим. Использую при этом стандартное, или почти стандартное cck поле (не заводя отдельных полей как в nodeReferrer).
Для этого в 6 есть 2 модуля, cnr и
backreference.
А для семерки эта проблема решается?
Corresponding node references решение проблемы для drupal 7
У меня такой вопрос, на который я до сих пор не могу найти ответ.
Допустим, все, что описано в топике - сделано.
Была создана страница с автомобилем MMW-320. Как сделать так, чтобы ЛЮБОЙ пользователь, нажав на специальную ссылку на этой странице, перейти к форме добавления Детали, конкретно к этому авто?
То есть, в ссылке на форму, очевидно, должен передаваться id ноды (bmw-320), это не сложно сделать. А вот как сделать, чтобы на странице добавления детали в поле выбора автомобиля автоматически выбирался пункт bmw-320?
Тут хуками или как решать задачу?
Через hook_form_alter
А можно пример какой-нить для тех, кто с хуками не разбирается, но очень хочет научиться?
Поищите «Темизация форм»
[module=nodereference_url]
за 3 года, по видимому, ничего не изменилось
У меня вот другой вопрос. Как на странице ноды получить список нод к которым привязана исходная (не наоборот). cnr не подходит, т.к. Обратная связь мне не нужна.
Твою же ж!........
СПАСИБО!
А каким образом вы связь осуществляли?
Мне как человеку, привыкшему работать с реляционными базами данных, описанный в статье способ представляется чудовищным. Обычно это делается следующим способом (попытаюсь объяснить это в терминах Drupal-а). Создаётся новый тип материала, который можно назвать "автомобиль-деталь" с двумя полями - ссылка на тип "автомобиль" и ссылка на тип "деталь". Разумеется, для этого нужно использовать модуль Node Reference (не понимаю, почему такого типа поля до сих пор нет в ядре). Чтобы привязать конкретный автомобиль к конкретной детали (или наоборот, что одно и то же), нужно создать новый узел типа "автомобиль-деталь" с указанием соответствующих полей. Разумеется, конечный пользователь не должен видеть ни типа "автомобиль-деталь", ни узлов этого типа.
Аналогичный способ реализован в модуле Relation. Но там больше вопросов, чем ответов.
Топикстартеру: добавьте еще один update от меня.
http://drupal.org/project/cnr - это то, что
директордоктор прописал. Делаем nodereference-поле с А на Б и nodereference-поле с Б на А. Потом через Corresponding node references связываем их вместе. Теперь связь можно видеть и редактировать как в А, так и в Б - поля синхронизируется автоматически.никакуих проблем не возникало? у меня почему-то никак не синхронизируются.