Orm

Orm 是 物件關聯對映(Object Relational Mapper) 的简寫,它做兩件事:
對應你資料庫裡的資料列到物件, 并能让你在这些物件之間建立關係。
它緊隨 活动記錄模式( Active Record Pattern),但也受到其他系统的影響。

關聯:Many to Many

Specifies a many-to-many relationship to another model. The target model will have the same type of relationship in the other direction. To allow for these relations you need a table in between with just the 2 IDs from both sides of the relation as dual-primary key.

保持值的關聯

If you need to save values with the relationship table you don't want to use ManyMany but create a model in between instead which belongs to both sides of what you would otherwise call the ManyMany relationship. It is described under "Usage with nested relationships how you can fetch all this.

配置選項

ManyMany 關聯比起其他關聯有三个額外的配置選項。 在使用最常用的命名慣例時,三者仍然是選擇性的。

選項 預設 註釋
table_through Calculated from model_to and model_from alphabetically ordered This is the table that connects the 2 models and has both their IDs in it. For 2 models like Model_User and Model_Post it will be named posts_users by default (both plural).
key_through_from Calculated from the current model name The key that matches the current model's primary key. If your current model is Model_Post this will be post_id by default
key_through_to Calculated from the related model name The key that matches the related model's primary key. If your related model is Model_User this will be user_id by default

Ordering on a column in the through table

In addition to the normal default order you can define in a relationship definition, you can also define now the records from table_through need to be ordered:

protected static $_many_many = array(
	'users' => array(
		'table_through' => 'posts_users', 	// both models plural without prefix in alphabetical order
		'order_by' => array(
			'posts_users.status' => 'ASC'	// define custom through table ordering
		),
	)
);
// other fields that may be required have been ommitted for this example

Example

Let's say we have a model Model_Post and it has many and belongs to many Model_Users. The ID of the Model_Post is along with the ID of the Model_User in a table called posts_users (default order is alphabetical). That table has just 2 columns: post_id and user_id which are together the primary key of that table.
If you keep to the defaults all you need to do is add 'users' to the $_many_many static property of the Model_Post:

protected static $_many_many = array('users');

And you need to add a table like this one to your SQL:

CREATE TABLE IF NOT EXISTS `posts_users` (
  `post_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`post_id`,`user_id`)
);

Below are examples for establishing and breaking has-many relations:

// 主要及關聯物件兩者都是新的:
$post = new Model_Post();
$post->users[] = new Model_User();
$post->save();

// both main and related object already exist
$user = Model_User::find(8);
$user->posts[1] = Model_Post::find(1);
$user->save();

// break the relationship established above
$post = Model_Post::find(1);
unset($post->users[8]);
$post->save();

Full config example with defaults as values

// 在有并屬於多个 Users 的 Model_Post 中
// = multiple posts per user and multiple users (authors) per post
protected static $_many_many = array(
	'users' => array(
		'key_from' => 'id',
		'key_through_from' => 'post_id', // column 1 from the table in between, should match a posts.id
		'table_through' => 'posts_users', // both models plural without prefix in alphabetical order
		'key_through_to' => 'user_id', // column 2 from the table in between, should match a users.id
		'model_to' => 'Model_User',
		'key_to' => 'id',
		'cascade_save' => true,
		'cascade_delete' => false,
	)
);