如何在CakePHP 3中的单个对象/数组中返回从包含和左连接中找到的数据?

时间:2014-09-18 16:36:09

标签: join cakephp-3.0

到目前为止,我的数据库中设置了3个表:

Users / User_Profiles / Addresses

地址表用于存储来自用户以及最终来自公司等的地址。 User_Profiles表包含有关不涉及地址的用户的更多信息。

Users Table:

id | username | password | etc....


User_Profiles:

id | user_id | phone | website | bio | address_id | shipping_address_id


Addresses

id | address | city | state | zip | etc...

这是我的问题。我想通过id找到一个用户,然后返回他的所有信息 - 他的信息来自user_profiles,他的信息来自地址(address_id和shipping_address_id指向地址表)。

在我的模型中,我目前有这个:

 public function getUserInfo($user_id){

     return $this->find()
        ->contain(['user_profiles'=>['fields'=>['user_id','phone_number', 'website', 'bio', ]]])
        ->where(['id' => $user_id])
        ->first();
 }

这很简单并返回我的user_profile信息。现在我需要加入地址表(两次,我猜?)来获取送货地址和常规地址(通过shipping_address_id和address_id)。

我该怎么做?我想我可以使用TableRegistry加载user_profiles表来存储address_id和shipping_address_id作为变量,然后从那里开始工作,但它似乎过于复杂。

理想情况下,我希望在对象中返回所有信息 - user_profile信息以及相关的任何地址。

2 个答案:

答案 0 :(得分:1)

首先是

您需要告诉Cake您的表格如何相互关联 在UsersTable.php文件中,添加以下方法:

public function initialize(array $config)
    $this->hasOne('UserProfiles');
}

Now Cake知道在从Users表中检索内容时如何在UserProfiles表上查找信息。只要您遵循conventions,这对于简单关联就足够了。

现在,在UserProfilesTable.php文件中,我们可以定义稍微复杂的关联。

public function initialize(array $config)

    $this->belongsTo('Users');

    $this->belongsTo('Address', [
        'className' => 'Addresses',
        'foreignKey' => 'address_id',
        'property_name' => 'address'
    ]);

    $this->belongsTo('ShippingAddress', [
        'className' => 'Addresses',
        'foreignKey' => 'shipping_address_id',
        'property_name' => 'shipping_address'
    ]);
}

第一个关联非常简单。它告诉Cake,UserProfiles表指向Users表中的记录 只要你遵循惯例,这里应该没有问题。

接下来的两个协会需要更多的工作 由于您需要将UserProfiles与Addresses关联两次,因此您必须为每个关联定义别名。这个别名是在contains方法中识别你的关联的。

这应该足以使您的find方法按预期工作。

您可以在this section of the book了解有关协会的更多信息。

检索您的数据

public function getUserInfo($user_id){
    return $this->find()
        ->contain([
            'UserProfiles', 'UserProfiles.Address', 'UserProfiles.ShippingAddress'
        ])
        ->where(['id' => $user_id])
        ->first();
}

现在,只有一次使用find方法检索有关Users,UserProfiles,Address和ShippingAddress的所有信息。
您还可以按照this part of the book中的说明将参数和定义条件传递给每个关联。

希望这可以帮助将来面临同样问题的人。

答案 1 :(得分:0)

使用

$hasOne
$hasMany

CakePHP模型中的属性

http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html

如果您遵循CakePHP名称约定,您应该能够通过编写3行代码来建模这些关系。