- CakePHP 1.3 Application Development Cookbook
- Mariano Iglesias
- 817字
- 2021-04-09 22:04:17
This recipe shows how to use Containable
to change some of the parameters that affect model bindings.
To go through this recipe, we need some sample tables to work with.
- Create a table named
users
, using the following SQL statement:CREATE TABLE `users`( `id` INT UNSIGNED AUTO_INCREMENT NOT NULL, `name` VARCHAR(255) NOT NULL, `email` VARCHAR(255) NOT NULL, PRIMARY KEY(`id`) );
- Create a table named
profiles
, using the following SQL statement:CREATE TABLE `profiles`( `id` INT UNSIGNED AUTO_INCREMENT NOT NULL, `user_id` INT UNSIGNED NOT NULL, `website` VARCHAR(255) default NULL, `birthdate` DATE default NULL, PRIMARY KEY(`id`), KEY `user_id`(`user_id`), CONSTRAINT `profiles__users` FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) );
- Create a table named
articles
, using the following SQL statement:CREATE TABLE `articles`( `id` INT UNSIGNED AUTO_INCREMENT NOT NULL, `user_id` INT UNSIGNED NOT NULL, `title` VARCHAR(255) NOT NULL, `body` TEXT NOT NULL, `published` TINYINT NOT NULL default 1, `created` DATETIME NOT NULL, `modified` DATETIME NOT NULL, PRIMARY KEY(`id`), KEY `user_id`(`user_id`), CONSTRAINT `articles__users` FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) );
- Add some sample data, using the following SQL statements:
INSERT INTO `users`(`id`, `name`, `email`) VALUES (1, 'John Doe', 'john.doe@example.com'), (2, 'Jane Doe', 'jane.doe@example.com'); INSERT INTO `profiles`(`user_id`, `website`, `birthdate`) VALUES (1, 'http://john.example.com', '1978-07-13'), (2, NULL, '1981-09-18'); INSERT INTO `articles`(`user_id`, `title`, `body`, `published`, `created`, `modified`) VALUES (1, 'John\'s Post 1', 'Body for John\'s Post 1', 1, NOW(), NOW()), (1, 'John\'s Post 2', 'Body for John\'s Post 2', 1, NOW(), NOW()), (1, 'John\'s Post 3', 'Body for John\'s Post 3', 0, NOW(), NOW()), (1, 'John\'s Post 4', 'Body for John\'s Post 4', 1, NOW(), NOW()), (2, 'Jane\'s Post 1', 'Body for Jane\'s Post 1', 1, NOW(), NOW());
- Add the
Containable
behavior to all your models by following the recipe Adding Containable to all models. - Now we need to create the main model. Create a file named
user.php
and place it in yourapp/models
folder with the following contents:<?php class User extends AppModel { public $hasOne = array('Profile'); public $hasMany = array('Article'); } ?>
If we want to obtain the first User
record together with the Article
records that the User
owns, but ordered by latest articles first, we use the order
binding setting (we also use the fields
setting to limit the fields returned for each Article
):
$user = $this->User->find('first', array(
'contain' => array(
'Article' => array(
'fields' => array('Article.title'),
'order' => array( 'Article.created' => 'desc', 'Article.id' => 'desc' )
)
)
));
Using our sample data, the above query will result in the following array structure:
array( 'User' => array( 'id' => '1', 'name' => 'John Doe', 'email' => 'john.doe@example.com', ), 'Article' => array( array( 'title' => 'John\'s Post 4', 'user_id' => '1' ), array( 'title' => 'John\'s Post 3', 'user_id' => '1' ), array( 'title' => 'John\'s Post 2', 'user_id' => '1' ), array( 'title' => 'John\'s Post 1', 'user_id' => '1' ) ) )
If we want to get the same data, but make sure we only obtain the latest Article
a User
has written, we use the limit
binding setting:
$user = $this->User->find('first', array(
'contain' => array(
'Article' => array(
'fields' => array('Article.title'),
'order' => array(
'Article.created' => 'desc',
'Article.id' => 'desc'
),
'limit' => 1
)
)
));
Using our sample data, the above query will result in the following array structure:
array( 'User' => array( 'id' => '1', 'name' => 'John Doe', 'email' => 'john.doe@example.com', ), 'Article' => array( array( 'title' => 'John\'s Post 4', 'user_id' => '1' ) ) )
Another option that is useful on some scenarios is offset
, applicable to the hasMany
and hasAndBelongsToMany
bindings. Using the example above, we now want to obtain the two most recent articles a User
created, after the latest Article
.
$user = $this->User->find('first', array(
'contain' => array(
'Article' => array(
'fields' => array('Article.title'),
'order' => array(
'Article.created' => 'desc',
'Article.id' => 'desc'
),
'limit' => 2, 'offset' => 1
)
)
));
The returned data structure now looks like this:
array( 'User' => array( 'id' => '1', 'name' => 'John Doe', 'email' => 'john.doe@example.com', ), 'Article' => array( array( 'title' => 'John\'s Post 3', 'user_id' => '1' ), array( 'title' => 'John\'s Post 2', 'user_id' => '1' ) ) )
The Containable
behavior uses the built-in bindModel()
method defined in CakePHP's Model
class to alter the binding settings defined in the contain
find setting.
It goes through the defined bindings and checks to see whether there are defined binding settings. If there are, it passes them to the bindModel()
method for each of the specified bindings.
Some binding settings make sense only on some relationship types. For example, the limit
setting used previously would not be useful on belongsTo
or hasOne
relationships.
The following list includes which settings can be specified for each relationship type:
belongsTo: className, conditions, foreignKey, order
.hasOne: className, conditions, foreignKey, order
.hasMany: className, conditions, finderQuery, foreignKey, limit, offset, order
.hasAndBelongsToMany: associationForeignKey, className, conditions, deleteQuery, finderQuery, foreignKey, insertQuery, joinTable, limit, offset, order, unique, with
.
- Beginning Swift
- Word-Excel-PowerPoint 2010三合一從新手到高手(超值版)
- Photoshop CC中文版基礎與實例教程(第7版)
- CorelDRAW服裝設計實用教程(第四版)
- AutoCAD 2014電氣設計從入門到精通
- 圖像處理中的數學修煉(第2版)
- Photoshop+Adobe Camera Raw+Lightroom(攝影后期照片潤飾實戰)
- SketchUp/Piranesi印象彩繪表現項目實踐
- Drupal: Creating Blogs, Forums, Portals, and Community Websites
- Unity 3D\2D手機游戲開發:從學習到產品(第4版)
- 零基礎學會聲會影2018(全視頻教學版)
- SolidWorks2016中文版從入門到精通/CAX工程應用叢書
- 抖音+剪映+Premiere短視頻制作從新手到高手(第2版)
- Learning the Yahoo! User Interface library
- 中文版3ds Max 2014-VRay效果圖制作完全自學教程