By jaochoo on
Assume you have a website where people can posts events. After an event there might be articles reviewing the event. There might furthermore be people submitting photos from that event. Now if everyone posts these contents seperatedly someone browsing the events list would not be able to directly see related content to that event. So is there a way to create relationship between different content types? For example, the "event" content type has a field which is a list of "photo album" types (called "Photos from this event") and another field which is a list of "article" types (called "Event reviews").
Comments
I found some modules and
I found some modules and articles already:
- The CCK itself supports node-reference both referencing single nodes as well as a list of nodes (what I was looking for)
- NodeReferrer (http://drupal.org/project/nodereferrer) is an additional module to handle this
- Relativity (http://drupal.org/project/relativity) is another contributes module for the same task
- http://thereisamoduleforthat.com/content/translating-entity-relationship... describes how Drupal nodes, CCK and Views relate to traditional ER modelling
Does someone have more information about how to build complex data structures like in ER modelling with Drupal? I am thinking about building a company structure (Company--Subcompany--Department--Team--Employee) with content types but would like to make sure that I will not run into unexpected shortcomings..
_
After playing around with most of the node relationships modules, I find using nodereference fields (and optionally, nodereferrer fields as well) to be the best method. It's infinitely flexible and future proof (being part of cck). Plus there's a lot of modules that augment nodereference fields (ie nodereference_url, views_attach, nodereference_explorer, nodereference_views, etc.).
Thanks for sharing your
Thanks for sharing your experience. Two questions:
- How far does it make sense to use both the nodereference fields and noderefferer fields as well like you say? Isn't it duplicate functionality?
- Is there a way to relate a user to a certain node (user-->node), e.g. create an own content type "Company", then create some company-nodes ("IBM", "Microsoft", etc.) and have a user profile field for the company he works for ("John Doe" --> "IBM", "Bill Gates" --> "Microsoft")?
_
1) not duplicate functionality-- each type of field handles one side of the relationship. However, if you don't need the nodereferrer side, just don't use the module.
2) userreference field - part of the core cck package. However, to add nodereference fields to a 'user', you need to use the content_profile module which turns user profiles into nodes (core profile doesn't have nodereference fields).
1) I just played a little bit
1) I just played a little bit with CCK and the relationship fields (core Node reference and User reference as well as contributed Node referree field) and I am impressed how easy it was to create a simple organizational structure and employee directory. The referree field is a nice addition as now I can also from a user profile page to which department he belongs to, while before I would only see a list of employees on each department type content. However, as my structure can include departments referencing other departments (i.e. a department can have sub-departments) the user-profile will only show the department the user belongs to, but not all the parent departments (if there are). Example:
- IBM Ltd. (content type: company)
--- Human Resources (content type: department)
------ Training & Development Team (content type: department)
--------- John Doe (content type: user profile)
--------- Mary Ann (content type: user profile)
--- IT (content type: department)
--- Finance (conent type: department)
The profile page of "John Doe" will now show a list of "Departments" with "Training & Development Team" listed. I would like to make show a list showing "Human Resources, Training & Development Team", i.e. traversing all references.
Is that possible?
2) The user_reference field works fine itself; however, using the Content Profile I can define additional fields for that content type but when opening a user profile page it won't show these fields.
Subscribing, interested in ER
Subscribing, interested in ER moddeling also!
Let me add another
Let me add another question:
3) Given the wanted structure of Company--Department--Employee. How can I make sure that a Department belongs to only one Company, i.e. a node "Human Resources Department" (content type Department) is not added both to the nodes "IBM" and "Microsoft" (content type Company) but rather two different nodes (yet with the same title) "Human Resources Department" are created so that both companies have their own departments (1:n relationship)? If I just reference Company and Department then a user who edits a company will get the whole list of ever created departments including those nodes who already reference a company, i.e. a m:n relationship. As some department titles are rather generic (e.g. "Human Resources" is a department title which probably every company has) a user will tend to select the given department due its name even though it was actually created for another company node.
_
3) i'm not sure I understand -- just limit the nodereference field to one value (in the field settings).
3) You are right; I could
3) You are right; I could model it the other way round: Instead of giving a company node a list of department nodes I could simply give a department node a (1:1) limited field for a company node reference. That would at least be sufficient if you assume that there is only one level of departments below the company level, i.e. a department cannot have sub-departments.
If I want to model that a department can also have sub-departments, I tried to model it that way that a department has a (1:1) limited node reference of either company node OR department node, which might be called "Parent Organizational Unit". Actually that works fine, there is just one issue which I do not know how to solve:
Creating a new department, the user will get an aggregated list of all department and company nodes in the system. This isn't suitable because he might select a department which already was assigned to a different company. The better way would be to give him a list of the company nodes first where he has to select one. If that company node is the "Parent Organizational Unit" the new department node can be created, otherwise he will get a second list of all departments whose node_reference field ("Parent Organizational Unit") referes to the company node he selected from the first list, and so on. E.g.:
I tried usind the hierarchical_select module with the extension for node references but I cannot get it to work.
_
1) i would think it's just a matter of getting a view setup the way you want it (a view can traverse the whole tree). See the http://drupal.org/project/nodereference_views and http://drupal.org/project/views_attach to use a view to display a list of referenced nodes on the parent.
2) not sure what the problem could be-- content_profile works fine every time I use it.
I not found realy capacity
I not found realy capacity for Relationship between content types.
In the future there could be a following:
create table reference_between_content_type(
content_type_leader_code char(20),
content_type_slave_code char(20),
cck_field_leader char(20),
cck_field_slave char(20),
p_like char(1), -- type of SQL relationship:1-'like X%',2-'<=',3-'>=',4-'<',5-'>',other-'=';
p_slave_leader char(1), -- type of relationship: 1->many, many->1
p_integrity_audit char(1), --
-- 0-delete leader and do not touch slave
-- 1-do not delete leader if exist slave
-- 2-ask for delete leader if exists slave
-- 3-delete leader and slave even if exists slave
p_insert char(1), -- block insert in slave
p_update char(1), -- block update in slave
p_delete char(1), -- block delete in slave
p_default char(1) -- default slave
);
create unique index reference_between_content_type_key
on reference_between_content_type
(content_type_leader_code,content_type_slave_code,cck_field_leader,cck_field_slave);