Drupal7 : content type with many fields - drupal

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.

Related

Drupal best practice for complex relationships

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

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!

Field data in one table, not many. for drupal7

I am working with the commerce module to create an online store. I am modifying the products .install file to create a content type (as I have been told this is required) and as part of that content type, I need to create lots of fields. The list will be around 50-60 different pieces of information.
Ideally I would like to store these in a single table with the productID at the beginning and all the other information along, but this doesn't seem to be the case; all the fields are stored in different tables.
I noticed that the "Address" module that is also used with commerce creates a field-type that has about 15 different values all stored in the same box. How is this possible? I noticed that if I set the cardinality up to 5 for example, it creates different rows. I just want a table with the following:
ID - value1 - value2 - value3 etc etc.
I also don't need any modules/extensions as this all needs to be written in the files. I also don't think that changing to the mongoDB ( I think ) is an option, so what are my options in this situation?
That's not how the Drupal field system works I'm afraid, one field == one table (well actually 2 tables if you include the revision table for each field).
The Address module uses hook_field_schema() to define several columns for that particular field (have a look in address.install and you'll see what I mean).
So if you want to put everything in one table you'll simply have to define your own field type (see the examples module, specifically field_example for help with that).
Bear in mind though that the number of columns you define in hook_field_schema() will be static once the module is installed, and the only way you're going to be able to increase/decrease it is with an _update hook for your custom module.
Also, if you're hacking at files that are included in the Commerce module...stop!: Commerce is still very much in it's infancy and you will likely have to update it soon...once you've done that your code changes will be gone and there's a good chance your site will be in an inconsistent state.
The whole point to Drupal is that everything is hooked/farmed out so that it can be altered by other parts of the system. There's nothing you can change in product.install that can't be done by implementing a Drupal hook in another module.
If you're unsure, post another question detailing what you're trying to accomplish by directly editing a contrib module file and one of the Drupal gurus on SO will point you in the right direction :-)
EDIT
Just to say I've been working with Ubercart in Drupal 7 for quite some time now and find it a very, very good solution (a lot of Commerce contributed modules are still in dev/alpha/beta; this is less so for Ubercart contributed modules). It might be worth a look.
Some more info
I think you've basically got two options here but either way you'll need to create a custom module (excellent set of instructions here).
Option 1: Create a custom field
If you're a Drupal coding beginner I'd suggest this is probably the easiest way to accomplish what you want, but it's still not totally straight forward. Grab the field_example module from the Drupal Examples module link above and have a look in the .install file, specifically the field_example_field_schema() function. That defines the columns that will be in the table for that field. Then have a look in field_example.module...pretty much every function that's commented with Implements hook_x is one that you're going to want to copy into your module and tweak for your own needs.
I think this will be easier because Drupal will handle the table/form field creation for you
so you don't have to mess with the database, schema or form APIs.
Option 2: Create a custom module
This option involves implementing your own table (like you suggest in your comment) where the primary key would be the entity ID of the product and would also contain all of your custom columns. (See the Schema API documentation for help with this).
Then you'd implement hook_form_alter() to add the form fields necessary for a user to input the data, and then implement hook_node_insert() and hook_node_update() to persist this data to your database table. It's quite hard to go into any more detail without actually writing code and it's quite a bit of code!
Hope that helps, sorry I can't be any more specific but it's not easy without knowing all the ins and outs of the situation

How do I do this in Drupal?

Im currently evaluating Drupal to see if we can use it to replace our framework. My problem is I have this legacy tables which I would want to try to reflect in Drupal. It involves a join table. There's quite a lot of this kind of relationship in our existing web app so I am looking for possible ways to solve it.
Thank you for your insight!
There are several ways to do this, and it's hard to know which is best with no context about what you're actually doing with the data, but here are some options:
One way to do this is to make a content type representing each table (using CCK) with the foreign keys represented by type-specific node reference fields. Doing everything as nodes gives you a bunch of prebuilt functionality around nodes, but has a bit of overhead you may want to avoid.
Another option is to leave your database just like it is now. Drupal can do direct database queries, or you can use Data to expose your tables to Views.
Another option, if those referenced tables really only have 1 non-ID field, is to do the project_companies_assignments as nodes and do the other 3 as taxonomies. But this won't work if those are really more complex entities, and wouldn't be very flexible if they might become more complex.
What about using hook_views_api and exposing your legacy tables in hook_views_data? i tried something like this myself - not sure if that is what you want...
try and let me know if that works for you.
http://drupalwalla.blogspot.com/2011/09/how-do-you-expose-your-legacy-database.html
Going with Views and CCK, optionally with the additional Data module has one huge disadvantage: it comes with complexity.
My preferred alternative, is to write your own module. Drupal offers little help wrt database abstraction, it comes not with a proper ORM or such. But with some simple CRUD functions for the data in the database, a few simple forms in front, and a menu-callback with some pages to present the data, you can -quite often- get your datamodel worked out much faster then going the route of the overly complex, often poorly documented CCK and views modules. KISS.

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