I have a somewhat unusual data structure that I could sure could use some advise for building my models. Before I show you by db structure let me explain what it is I'm trying to do.
I am building an in-house cms (mainly for the experience) and I want my content to be very flexible making use of "custom fields" like in Wordpress, ExpressionEngine, Drupal, etc. (closer to EE than the others). BUT, I'm not particularly fond of EE's way of doing custom fields, in that EE has to add columns to a table. It just feels messy to me.
Please note, my examples below have been extremely simplified and stripped of non relevant tables and columns. For example, I do not mention anything of content categories but, be assured, I have them in my real data structure.
Here are my tables:
4 tables:
content_types, content_type_fields, content_entries, content_entry_data
Content_types could be likened to EE's channels or Wordpress' post types. Some examples of different content types are: events, news, employees, etc. Content_type_fields contain the custom fields for each content_type. For example, the "events" content_type could have fields like 'location', 'rsvp_notes', 'coordinator', and so on. Content_entries are... well, entries. For example, there could be an entry called "Community Outreach" and it would belong to the 'events' content_type. The content_entries only holds the title (I'm assuming all entries should have a title) and it's relationship with a content_type. Lastly, the content_entry_data will hold the custom field data for the entry.
Here's the db structure:
content_types
- id
- name
content_type_fields
- id
- name
- label
- content_type_id
content_entries
- id
- title
- content_type_id
content_entry_data
- id
- data
- content_field_id
- content_entry_id
Here is what some sample data might look like:
Table: content_types
id | name
1 | events
2 | news
Table: content_type_fields
id | name | label | content_type_id
1 | location | Location | 1
2 | rsvp_notes | RSVP Notes | 1
3 | coordinator | Coordinator | 1
4 | description | Description | 1
5 | excerpt | Excerpt | 2
6 | body | Body | 2
Table: content_entries
id | title | content_type_id
1 | Community Outreach | 1
2 | Baby Shower | 1
3 | Lunar Eclipse Coming | 2
Table: content_entry_data
id | data | content_field_id | content_entry_id
1 | Community Center | 1 | 1
2 | Rsvp with @someone | 2 | 1
3 | John Smith | 3 | 1
4 | We are going to give back ... | 4 | 1
5 | Ashley's House | 1 | 2
6 | Call Ashley's Mom at (321)... | 2 | 2
7 | Jane Smith | 3 | 2
8 | Ashley's have a baby and y... | 4 | 2
9 | There's an eclipse coming! | 5 | 3
10 | A luner eclipse only happe... | 6 | 3
Hopefully, that paints a pretty good picture of what I've got going on here. Now, on to the fun part...
I want, in a view or template, to be able to have code like this:
// event_info.php (getting one row)
<h1><? echo $entry->title; ?></h1>
<p>Location: <? echo $entry->location; ?></p>
<p>Coordinator: <? echo $entry->coordinator; ?></p>
<p>RSVP Info: <? echo $entry->rsvp_notes; ?></p>
<p>Event Description: <? echo $entry->description; ?></p>
// event_listing.php (getting multiple rows)
<? foreach($entries as $entry): ?>
<h1><? echo $entry->title; ?></h1>
<p>Location: <? echo $entry->location; ?></p>
<p>Coordinator: <? echo $entry->coordinator; ?></p>
<p>RSVP Info: <? echo $entry->rsvp_notes; ?></p>
<p>Event Description: <? echo $entry->description; ?></p>
<? endforeach; ?>
I figured I'd need to override the __get() and __set() methods in my entry model to make this happen.
One problem I'm facing is, I want to be able to have _some_ (not all) of the custom fields in the entry listing in the backend. So, I could add another column to the content_type_fields table that will be set to a 1 or 0. Like this:
content_type_fields
- id
- name
- label
- content_type_id
- admin_list
BUT, the problem is I don't know how the view would look like for the backend entry listing. I figure something like doing a foreach on the entries to make the (html) table rows, then an inner foreach on each entry's fields to get the cells, then somehow get the fields data for the entry... sounds messy and very slow to me.
I completely agree that I may have to change my data structure because of the amount of queries (or joins) it would take to get the data. But I would sooo appreciate if anyone has already been in my shoes to let me know what options you considered and what you ended up doing.
Thanks in advance guys!
I would reconsider the option of adding fields to a table, it doesn't have to be messy so long as you keep a hold of it. Plus, from a speed point of view, it'll be quicker for the database to process.
Yeah, I agree about it being performance hit to keep with what I have. But with it comes a lot of flexibility.
Just out of curiosity, how would you go about that scenario in fuel? I guess you wouldn't be able to use $_properties in the model since the columns would not be constant. What else?