Many-to-many: Defining and using many-to-many associations
Two types of records are related with a many-to-many associations if they both define matching properties with "has_many" keys.
Porte provide two strategies to internally store "many-to_many" associations:
- Using a join table
- Using a list of foreign keys stored in a text column
Plural and singular conversion of the properties are automatically handled.
Methods available with a "has_many" association
- Method get{Records}
Retrieve the associated records.- return PorteIterator
- Method add{Records}
Add one or more associated record to the current record. It either accept an array of new or saved record, an array of integer or string primary keys or a string with a list of primary keys separated by commas. Calling the save method on the current record will also save the provided associated records.- param mixed (PorteRecord, int, string)
The associated record or its primary key value - return PorteRecord
The current record
- param mixed (PorteRecord, int, string)
- Method add{Record}
Add an associated record to the current record. It either accept a new record, a saved record or the primary key value of a saved record. Calling the save method on the current record will also save the provided associated record.- param PorteRecord || int || string
The associated record or its primary key value - return PorteRecord
The current record
- param PorteRecord || int || string
- Method delete{Records} Break all the associations of a record without deleting the associated records from the database.
- *return PorteRecord*
The current record
- Method delete{Record} Break all the associations of a record without deleting the associated records from the database.
- *param mixed(PorteRecord, int, string)*
The record witch should no longer be associated
- *return PorteRecord*
The current record
Differentiate the "join table" and the "foreign key column" storages
Let's take an exemple: a group can have many users, and a user can be member of different groups. There are 2 strategies to manage this kind of relationship in the database: using a join table or with a list of primary keys stored in a text column. Both strategies are implemented, it just depend on the way you declare the has_many property when configuring your properties. The codes below show the differences in the database structure.
join table
CREATE TABLE `Users` ( `id` int(11) NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `Groups` ( `id` int(11) NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `Groups_Users` ( `id` int(11) NOT NULL auto_increment, `group` int(11) NOT NULL, `user` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
list of foreign keys stored in a text column
CREATE TABLE `Users` ( `id` int(11) NOT NULL auto_increment, `groups` text, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `Groups` ( `id` int(11) NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8