Best Way to handle Relational Data in CodeIgniter? - php

When creating a CodeIgniter project, what is the best way to handle relations between models? Should models contain other models that they are related to, should this be handled in the controller, or is there some other way to handle these scenarios? I'm thinking about one-to-one, one-to-many, or many-to-many relationships.
example: let's say I have a blog post, which has a many-to-many with tags, and a one-to-many with comments. What would be best practices for getting the tags and comments when getting blog posts?

Good question but there's no easy answer.
One project of mine uses a lot of database joins in its queries. So the correspondence is more one controller to one model, and that model then calls on a bunch of different tables.

Related

Where to put SQL queries that join on multiple tables?

I am using an MVC framework and have a photo SQL table and an album SQL table. Queries for the photo table go in the photoTableModel class, and queries for album table go in the albumTableModel class.
Where do I put queries that use both tables?
For example, the following query uses both tables. Do I place the query in the photoTableModel, albumTableModel, a new table model altogether, or maybe even a service?
SELECT `photo`.`id`
, `photo`.`name`
FROM `photo`
JOIN `album`
ON `album`.`album_id` = `photo`.`album_id`
AND `album`.`album_id` = 1
;
The center of the architecture is models, not tables. Semantically, which model is being described or operated on here?
This appears to be retrieving a list of photos, with some album information included in the elements of that list. So I suspect that this is related to the Photo logical model. So wherever you put this in your architecture and framework, it should be semantically related to that model.
How your framework defines things is up to that framework, so I really can't be more specific. Different frameworks do different things in different ways. In general, however, in the MVC pattern you want to build your logic and architecture around the models. And what you get from this query is a list of photos (with some extra information), so it's related to the Photo model.
Models can be direct one-to-one representations of tables. But they don't need to be. It looks like you're artificially limiting your models to be exactly that, which has led to this issue. Maybe you extend the Photo model concept to include album information? Maybe you create a DTO that's a hybrid of the two? Maybe you add an Album property to your Photo model? There are many ways to go about organizing models. The point is to keep the semantics of those models clear. Models represent domain concepts (like Photo), not database tables (like photoTableModel). The database tables simply persist the model information to be re-constructed later. As such, the database is an edge concern for the domain, not a central one.

Doctrine2 and polimorphic relationship

I have an entity called Document. I'd like to make this entity related (many to one) to few other entities (let's say User, Invoice and Transaction). In Laravel I could easily achieve that by using polymorphic relations.
Is there any (easy) way to accomplish the same with Doctrine?
This might be what you're looking for http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html

Clean way to implement eager loading in Active Record style ORM?

I'm in the process of writing a very light-weight ActiveRecord implementation in PHP. I have the basics working, but I want to implement eager loading of at least the one-to-one relationships. I've been brainstorming on a clean way to do this.
If I'm eager loading a single one-to-one relationship, I will have to know the columns for both tables and will have to alias the columns following some convention that will allow me to map the results back into the correct objects.
I'm looking for suggestions on how to alias the columns from each table such that mapping them back to their respective objects is as painless as possible.
My initial thoughts are to alias the base table's columns as "base_column_name" and the related tables columns as "user_email" (if "User" is the name of the related object). Is there a better way to do this that I'm overlooking?
A second option I have considered is to get all of the objects off of the base table, and then gather the related objects in one "WHERE IN" using the keys from the base table. But, would this cause performance problems?
CakePHP uses php's flexible associative arrays in its ActiveRecord implementation. So a one to many relationship could be
array('Tablename'=>array('columnname'=>'columnvalue'),
'AssociatedTable'=>array('0',
array('columnname'=>'columnvalue')));
It does put one more layer in everything so you have to do $data['tablename']['columnname'];

Many to Many Relationships

I'm seeing all sorts of different ways to handle many to many relationships in Yii. However, the examples I'm seeing aren't fully fleshed out and I feel like I'm missing something.
For instance, Larry Ullman's tutorial doesn't use the self::MANY_MANY relation - http://www.larryullman.com/2010/08/10/handling-related-models-in-yii-forms/
So as far as adding and retrieving records, whats the standard way for handling Many to Many in the Model, Controller and View?
clarification: I suppose Im looking for an example involving 2 tables, related by many-to-many, where I can see not only both models, but controllers and views as well so I can fully understand whats going on.
You actually need the 3 tables (so an extra model for the pivot table), but once you have it you can actually use the regular yii relation functionality.
For example a project of mine has a many-to-many relation between a Purchase and a Transaction (please don't ask why :) ). So there is a Purchase model, a Transaction model and a PurchaseToTransaction model that establishes links between them. I can just do a $oPurchase->transactions and Yii will handle the many-to-many part using the relation, it is defined as follows:
'transactions' => array(self::MANY_MANY, 'Transaction', 'PurchaseToTransaction(purchaseId, transactionId)')
Note that for the Transactions, the same applies but the other way around:
'purchases' => array(self::MANY_MANY, 'Purchase', 'PurchaseToTransaction(transactionId, purchaseId)'),
So both $oPurchase->transactions and $oTransaction->purchases are automatically handled by Yii.
In conclusion it can indeed handle Many-to-Many using relations (at least the reading part, for writing you still need arbitrary solutions).
I am just using Yii. Just a basic idea. If you thought One to Many is not a problem then you need to create a middle table in between like for Users and Orders, create a UsersOrders table to map those keys. Then create function to get those related tables in the class like $this->UsersOrders->Orders() for function Orders in User class, vice versa.
Many to Many is actually groundup by 3 tables. 2 tables but plus hidden table in the middle.

Yii framework Many to Many relationships

What is the method to save and update Many to Many relationship in Yii framework?
There is a better implementation as behavior.
http://www.yiiframework.com/forum/index.php?/topic/6905-please-test-my-ar-enhancement-automatically-sync-many-many-table-when-calling-save/
Unless you create a model for the table between the two main tables, your only option is to use DAO (Database Access Object) and specify SQLs with it.
Have a look at how blog demo accomplishes this task.
use MANY_MANY relationship type to setup many to many connection between Models (An associative table is needed to break a many-to-many relationship into one-to-many relationships)
And now you can use all relational functions of Active Records
Yii Framework - The Definitive Guide to Yii: Working with Databases-Relational Active Record
The following extension does what you want...
Yii Framework - Extension: cadvancedbehavior
An important thing to note: On each update, the extension clears all previous records and creates new ones. So I wouldn't use it when the intermediatry table contains extra data other than the foreign keys.
you could set that up in mysql level..by going to relational view under each table in phpmyadmin and provide necessary relational condition..and use MANY_MANY in the model class inside relations..
The question is too common.
Usually data components with MANY to MANY relationships appear sequentially and independently. So you just need to do one insert action after another.
If your relationship needs dependent update you should user SQL triggers on the DataBase level. That'll ensure integrity of data and give a quite good separation in business logic of the application.
CREATE TRIGGER some_trigger
AFTER UPDATE ON some_table
...
END IF;
A similar way is to incapsulate relational data in one logical model on PHP level (and e.g. manipulate with 2-3 AR models there) and emulate SQL triggers logic in it.

Categories