Defining multiple associations to the same model

This recipe shows how to set up more than one association from one model to the same model, a need that normally arises on most applications.

Getting ready

To go through this recipe we need some sample tables to work with.

  1. Create a table named addresses, using the following SQL statement:
    CREATE TABLE `addresses`(
    `id` INT UNSIGNED AUTO_INCREMENT NOT NULL,
    `address` TEXT NOT NULL,
    `city` VARCHAR(255) default NULL,
    `state` VARCHAR(255) NOT NULL,
    `zip` VARCHAR(10) NOT NULL,
    `country` CHAR(3) NOT NULL,
    PRIMARY KEY(`id`)
    );
    
  2. Create a table named users, using the following SQL statement:
    CREATE TABLE `users`(
    `id` INT UNSIGNED AUTO_INCREMENT NOT NULL,
    `billing_address_id` INT UNSIGNED default NULL,
    `home_address_id` INT UNSIGNED default NULL,
    `name` VARCHAR(255) NOT NULL,
    `email` VARCHAR(255) NOT NULL,
    PRIMARY KEY(`id`),
    KEY `billing_address_id`(`billing_address_id`),
    KEY `home_address_id`(`home_address_id`),
    CONSTRAINT `addresses__billing_address_id` FOREIGN KEY(`billing_address_id`) REFERENCES `addresses`(`id`),
    CONSTRAINT `addresses__home_address_id` FOREIGN KEY(`home_address_id`) REFERENCES `addresses`(`id`)
    );
    
  3. Add some sample data, using the following SQL statements:
    INSERT INTO `addresses`(`id`, `address`, `city`, `state`, `zip`, `country`) VALUES
    (1, '123 Street', 'Palo Alto', 'CA', '94310', 'USA'),
    (2, '123 Street', 'London', 'London', 'SE10AA', 'GBR'),
    INSERT INTO `users`(`billing_address_id`, `home_address_id`, `name`, `email`) VALUES
    (1, 2, 'John Doe', '[email protected]'),
    
  4. Now we need to create the main model. Create a file named user.php and place it in your app/models folder with the following contents:
    <?php
    class User extends AppModel {
    }
    ?>
    

How to do it...

Edit the User model, and add the binding definitions to include both references to the Address model:

<?php
class User extends AppModel {
public $belongsTo = array(
'BillingAddress' => array(
'className' => 'Address'
),
'HomeAddress' => array(
'className' => 'Address'
)
);
}
?>

If we issue a find operation to fetch the User, we would obtain the following data structure:

array(
'User' => array(
'id' => '1',
'billing_address_id' => '1',
'home_address_id' => '2',
'name' => 'John Doe',
'email' => '[email protected]',
),
'BillingAddress' => array(
'id' => '1',
'address' => '123 Street',
'city' => 'Palo Alto',
'state' => 'CA',
'zip' => '94310',
'country' => 'USA'
),
'HomeAddress' => array(
'id' => '2',
'address' => '123 Street',
'city' => 'London',
'state' => 'London',
'zip' => 'SE10AA',
'country' => 'GBR'
)
)

There's more...

In this example, the naming convention we used for the bindings is the standard CakePHP uses for field names, where each uppercase letter is prefixed by an underscore sign, everything is converted to lowercase, and the suffix _id is added. Thus, the standard field name the binding named BillingAddress is billing_address_id.

However there are times where we need to use a field name that does not comply with this standard. In that case, we can use the foreignKey binding setting to specify the field name. For example, we could change the User model definition so the name of the HomeAddress becomes Address, which would make the User model look like this:

<?php
class User extends AppModel {
public $belongsTo = array(
'BillingAddress' => array(
'className' => 'Address'
),
'Address' => array(
'className' => 'Address',
'foreignKey' => 'home_address_id'
)
);
}
?>

Note

When we use different aliases to refer to the same model, certain model callback implementations, such as beforeSave, will need to be changed to avoid using the name of the model directly, and instead use the property alias, available in all models. More information about this can be obtained from Nick Baker's article available at http://www.webtechnick.com/blogs/view/230/The_Power_of_CakePHP_aliases.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.186.219