Drupal best practice for complex relationships - drupal

I'm designing a Drupal 7 website where nodes/entites have complex relationships (1-many, many-to-many). For example:
Student (registered user) can belong to one ore more classes
Student can take one or more exams each semester
Teacher will take a note about each student in his class after each semester
My main concern is about:
Performance: queries should be fast and simple when rendering pages
Relationship: need to have two way relationship ( => can list related content based on content or vise versa)
Views Integration: should be fieldable and easy to list related content in Views
==> I come up with 2 solutions:
Method 1: the Drupal way
I know that there are some modules like EntityReference, Field Collection,... but don't know how to use, mix them the right way. Let's say how to create content type for a class, it's fields that link to user table and then easy to show the list of students on a given class?
===> The question is: What is the best practice for my case and what modules I should use and mixing together to solve this problem. What content type, it's field, and relationship I should create?
Method 2: could be not the Drupal way
Normally, I will design some tables in 3rd normal form (3NF) for those entities and their relationship: student, teacher, class, exam...I mean that this approach could be not the Drupal way as normal with field_xxx magical tables for each field of an custom content type, right? Hereunder are example of them:
Student table ( uid, name, full_name, other meta data columns) , of course the uid is foreign key point to Drupal user table
Class table (id, name, code_name,...)
Student_Class junction table (student_id, class_id, semester_id)
etc,.....
===> The question is: If I do it this way, is there any module which support to auto generated create CRUD forms, or API to create form to manipulate those tables, easy to allow field-able with Views module.
Please correct me for any misunderstanding and your ideas are welcome.
Thanks

The Drupal way with Entity Reference, Views, Field Collection (I would add Inline Entity Form, Views Bulk Operations, Views Megarow) is, in my opinion, the good one : you will be able to create back-office (and front end) screens very (I mean very) quickly using Views, related content (using Entity Reference) can be fetched both way, Inline Entity Form allows you to set up creation forms containing the related entity creation form (so create an entity and its related entity at the same time). Drupal Commerce is a good example of what you can do with these modules (see this entity relationship model). Rules can help to set up your business logic. So points 1 & 2 are (can be), in my humble opinion, satisfied with the Drupal way.
BUT...
This flexibility comes at the cost of complex requests, and eventually bad performance. You'll find all over the web posts about how Drupal is slow, and when you start playing around with a complex setup, it can be a serious problem. But with a good server configuration (cache, proxy...) and no PHP in Views :), it can be done (I run several Drupal Commerce sites, with a good server and a good sysadmin it's ok).
And you'll have to dive into Drupal logic, Views logic, Rules logic, which can be frustrating at some points : something you would code in a few PHP lines will take you a lot of clicks in Drupal interface. Of course, for tricky things, you can always build a small custom module doing just what you need.
About the second solution, I have no experience to share on Drupal and custom data model, but I guess you should consider applications frameworks (Symfony, Zend, CakePHP...) if you want to be free for the DB design.
Good luck

Related

How to create the best Drupal 7 structure as a site builder - via Entity type or Content type?

Just started using Drupal and tried to understand the core concepts. I have a developer background but I would like to use Drupal as a site builder and not digging into the code.
I'm trying to build a website which lists various vendors. One could be a Restaurant, another can be Photographer and other possible services (I have like 15 different ones).
They all have some things in common like Title, a Location (used Taxonomy/Vocabulary for that), description, image gallery, address, website, office hours and so on.
But they also have some custom fields. Restaurants can have fields like Facility options:Parking, Smoking area, etc or Capacity; Photographers can have others.
So there are lots of fields which are common for each vendor and some are are unique per each vendor.
What's the best way to implement this kind of structure as a Site builder?
I tried using Entities via ECK (Entity Construction Kit) and defining Entity types (as Vendor) and Bundles (as specific Vendors) but then I'm really limited in defining the common fields on Entity type level since Properties does not seem to be flexible in this regard, meaning that I cannot define them as normal fields and can't associate to them various widgets but only as a text input. Not sure if this a limitation of ECK or of Drupal 7 itself?
On the other hand I see the option of creating normal Content types for each kind of vendor which seems like alot of repetitive work, not sure if this is the right way (that's my only option at the moment)?
Maybe I should start learning more of Drupal and do some coding to create specific entity types? - but this means being more than a site builder. Since it will be a big project will this save me of some trouble later on or you see that I can accomplish the task easily without this extra effort?
Also by coding I'm not sure if there are easy ways of defining fields/widgets for Entity type Properties.
I would later on want to use faceting as well for filtering which will be based both on the fields which are common and unique for each vendor type, not sure if this is an important factor when creating the structure.
Any feedback is appreciated!

How can I implement additional entity properties for Entity Framework?

We have a requirement to allow customising our core product and adding additional fields on a per client basis e.g. People entity some client wants to record their favourite colour etc. As far as I know we can't add properties to EF at runtime as it needs classes defined at startup. Each customer has their own database but we are deploying the same solution to all customers with all additional code. We are then detecting which customer they are and running customer specific services etc.
Now the last thing I want is to be forking my project or alternatively adding all fields for all clients. This would seem likely to become a nightmare. Also more often than not the extra fields would only be required in a very limited amount of place. Maybe some reports, couple of screens etc.
I found this article from Jermey Miller http://codebetter.com/jeremymiller/2010/02/16/our-extension-properties-story/ describing how they are adding extension properties and having them go from domain to the web front end.
Has anyone else implemented anything similar using EF? How did it work out? Are there any blogs/samples that anyone has seen? I am not sure if I am searching for the right thing even if someone could tell me the generic name for what we want to do that would help. I'm guessing it is a problem that comes up for other people.
Linked question still requires some forking or implementing all possible extensions in single solution because you are still creating strongly typed extensions upfront (= you know upfront what extensions customer wants). It is not generally extensible solution. If you want generic extensible solution you must leave strongly typed world and describe extensions as data.
You will need to use some metamodel. Your entity classes will contain only properties used by all customers and navigation property to special extension entity (additional table per every extensible entity) where you will be able to put additional properties as name / value pair (you can add other columns like type, validation, etc. if needed).
This will in general moves part of your model from hardcoded scenario to configuration based scenario and your customers will even be allowed to define extensions at runtime (if you implement such feature).

Drupal7 : content type with many fields

what's the best way in Drupal 7 to handle many fields (> 40).
I've to handle hostels content-type.
D7 creates as many mysql tables as fields count, so I fear for the performances, but maybe it's not a problem.
Do I have to create entity and sub-entities or create modules to store some data in the same table (a field for equipments, a field for services, a field for activites, etc.)
or other solution ?
Many thanks for your advices !
40 fields are not that bad as I have seem plenty db tables with more fields.
Drupal is not really that good in OO and normalization but you can:
Create multiple custom content type and link them via Corresponding Node References to mimic the entity relationship, foreign key.
use taxonomy
write you own module never hurts as it help you learn the Druapl way.
Hope that helps
You can leave it as is, because, you know, between performance and flexibility, Drupal chose flexibility:)
if you want to have all these stored in 1 table, it's possible to write module that implements custom fieldset, like this: http://www.lullabot.com/articles/creating-custom-cck-fields
however, it's for D6 - I haven't done similar thing for D7 with cck fields in core, so can't give you direction here.
I guess, this and particularly this might help.

When not to use a Drupal node?

I've recently created a very simple CRUD table where the user stores some data. For the data, I created a custom node. The functionality works great for creating, editing, and deleting data in the CRUD table using the basic node functionality (I'm actually amazed how fast and easy it was to program the basic functionality with proper access controls using only a tiny bit of code)....
Since the data isn't meant to be treated the same way as 'content' such as a blog post (no title, no body, no commments, no revisions, shouldn't show up on ?q=node page, no previews, no teasers, etc)... I find that I'm spending most of my time 'turning off' and modifying the stuff that drupal does automatically for nodes.
I know its a matter of taste, but where should one draw the line on what should be treated as a node and what shouldn't? In other words, would it be better to program this stuff from scratch without using nodes?
Using nodes for custom data has quite some additional benefits besides easy edit/update/delete functionality:
possible categorization via taxonomy
implicit 'ownership' via author tracking
implicit tracking of creation/modification time
basic access control by default, expandable by a huge selection of modules
flexible query generation/listing/filtering via views
possible ad hoc extensions/annotations via CCK fields
possible definition of workflows, actions and the like
a huge number of hooks to programmatically intercept/adjust almost every usage aspect/scenario
commenting, voting, rating and tons of other functionality provided by all contributed modules that work on/with nodes ...
Given all this, I'd say you need a very good reason to not use nodes to store data in Drupal. Nodes are simply the fundamental building blocks for just about everything in the Drupal ecosystem, and the overhead of removing some unwanted default 'features' seems pretty small in comparison to the gains.
That said, one possible reason/argument to handle data separate from the node system might be if that data is directly aimed at annotating other nodes (think taxonomy). But since you can easily reference nodes from other nodes (with lots of different options on how to do this), the argument is not to strong.
Another (much stronger) argument would be data integrity - Drupal is not very strong (to put it politely) concerning normalized, relational data storage, referential integrity, transaction handling and other related topics. If you have requirements in that direction, you might have no choice but to skip the node concept and create and maintain a separate data island within the system on your own.
It helps to think also that a node doesn't need to be public either. Some nodes are private/internal and can be controlled further with access controls. The way you are doing it, whatever you're doing, makes all the scalability and extending it on your shoulders.
I would probably approach it with CCK/Taxonomy depending on what I was doing. That way, I get the added benefit of Views/Panels/etc module integration without writing any additional code.

moving database schema over to drupal

I'm creating a web application and I just want to know how to think about Drupal's db coming from an MVC background.
I have tables to represent people's data such as SSN, First Name, Last Name, Zip Code, Address, Language, Location. Now on the front end I want to create a form to populate this information for a bunch of subjects (people). I have my database normalized so the Zip Code has its own table (with a foreign key link to the person table). The "person" table has stuff such as First Name, Last Name, Address etc... and the "language" table will have the different language abbreviations (again with a foreign key back to the person table).
I would like to know how to move something like this to drupal's schema. I know I could create my own tables and link them back to the "node" table and then I guess build my forms to accept user input...but is this the suggested way to do it? I was looking at webform, but it seems this should be used for simpler forms where the database isn't normalized and everything is just stored in one large table. I'm not sure, but I would definitely love to hear what you guys think...and if you could point me to some resources that'd be great.
Drupal is flexible enough that you can create whatever tables you want and then write code to link them back to the node table. However doing this will mean that you end up with a lot of code which is very specific to your schema, and is not very interoperable with other Drupal modules.
You will find that you get on better with Drupal if you mostly do things the Drupal way. And only go for a very customized solution where you are doing something which isn't covered by standard Drupal modules.
For example you may find that the profile module fits your needs as far as standard information about people goes. The location module (specifically user location) will cover users addresses. By using these modules you are more likely to find other modules which work with them in future and overall you will find you have less code to write.
One thing you may find useful is the migrate module for getting your existing data into Drupal.
It sounds like you're just storing information and the subjects (people) won't be users of the Drupal site.
Leveraging the node and CCK modules to make this happen would remove most of the development work. For example, each of your tables (e.g. Person, Zip Code, Language) could be represented by a content type with a number of fields. The foreign keys would be represented by node reference fields. So the Person content type may have one or more node references to nodes of type, Language.
The migrate module seems well used (626th most popular of 4000+ modules used in at least 10 distinct Drupal sites), but it may be easier to whip up your own migration script, but I'm not familiar with either your situation, your familiarity with Drupal's API, or the migrate module.
Node reference fields display as links to the referenced nodes by default, but can be themed to load and display the referenced node instead (e.g. displaying Language information in a Person node). There's a handy screencast that illustrates how to go about theming node reference fields to load and selectively display the referenced nodes' contents.
Coming from an MVC background you may not like how Drupal stores data in the DB.
Profile module was mentioned, but I find I get more flexibility with Content Profile and CCK combined.
I've written some migration scripts before from Coldfusion to Drupal, and it's not too involved.

Resources