【问题标题】:How belongsTo works with mutiple hasMany in contain cakephp 3.xbelongsTo 如何与包含 cakephp 3.x 中的多个 hasMany 一起工作
【发布时间】:2016-03-25 04:07:25
【问题描述】:

我需要具有给定属性 ID 的用户,例如Property.id = $id

我想构建这个查询。

$sql = "SELECT p.address1, p.address2, p.address3, p.postcode,
               u.email, u.fullname
               c.company_name, 
               tc.created,
               tn.active
        FROM property AS p
        LEFT JOIN tenancy AS tc ON tc.property_id = p.id 
        LEFT JOIN tenant AS tn ON tn.tenancy_id = tc.id 
        LEFT JOIN users AS u ON u.id = tn.user_id 
        WHERE p.id = $id
            AND p.active = 1
            AND tc.active = 1
            AND tn.active = 1
            AND u.active = 1
        "; 

这是我的联想:

// Tenants
class TenantTable extends Table
{
public function initialize(array $config)
{
    $this->table('tenant');
    $this->displayField('id');
    $this->primaryKey('id');
    $this->addBehavior('Timestamp');
    $this->belongsTo('Users', [
        'foreignKey' => 'user_id',
        'joinType' => 'INNER'
    ]);
    $this->belongsTo('Tenancies', [
        'foreignKey' => 'tenancy_id',
        'className' => 'tenancy',
        'joinType' => 'INNER'
    ]);


// Users
class UsersTable extends Table
{

public function initialize(array $config)
{
    $this->table('users');
    $this->displayField('name');

    $this->hasMany('Tenants', [
        'foreignKey' => 'user_id',
        'foreignKey' => 'tenants'
    ]);
}


// Tenancies
class TenancyTable extends Table
{

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('tenancy');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');

    $this->belongsTo('Properies', [
        'foreignKey' => 'property_id',
        'className' => 'property'
    ]);

    $this->belongsTo('Company', [
        'foreignKey' => 'company_id'
    ]);

    $this->hasMany('Tenant', [
        'foreignKey' => 'tenancy_id',
        'className' => 'tenant'
    ]);


// Properties
class PropertyTable extends Table
{

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('property');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');

    $this->belongsTo('Company', [
        'foreignKey' => 'company_id'
    ]);

    $this->hasMany('Tenancies', [
        'foreignKey' => 'property_id',
        'className' => 'tenancy'
    ]);
}

我可以获取 hasMany 关联,但在获取用户的 belongsTo 时,它告诉我租户与用户没有关联。关联是如何设置的并且它们是正确的。我正在从 PropertyTable 运行以下 ORM。

$query = $this->find()
            ->select([ 
                'Property.id', 'Property.company_id', 'Property.address1', 'Property.address2', 'Property.address3','Property.postcode',
                'Tenancies.id', 'Tenancies.property_id', 'Tenancies.created', 'Tenancies.stage', 'Tenancies.landlord_offer_sent',
                'Company.id', 'Company.company_name',
                'Tenants.id', 'Tenants.user_id', 'Tenants.stage', 
                'Users.id', 'Users.email', 'Users.fullname'
            ])
            ->where(['Property.id' => $id])
            ->contain(['Company', 'Tenancies'])
            ->leftJoinWith('Tenancies', function(\Cake\ORM\Query $query) {
                return $query->where([
                    'Tenancies.active' => 1,
                ]);
            })
            ->contain(['Tenancies.Tenants'])
            ->leftJoinWith('Tenancies.Tenants', function(\Cake\ORM\Query $query) {
                return $query->where([
                    'Tenants.active' => 1,
                ]);
            }) 
 /*======= The problem starts from here  =========*/        
            ->contain(['Tenancies.Tenants.Users'])
            ->leftJoinWith('Tenancies.Tenants.Users', function(\Cake\ORM\Query $query) {
                return $query->where([
                    'Users.active' => 1,
                ]);
            });

请帮忙

【问题讨论】:

  • 仅仅因为您认为关联是正确的,并不意味着这一定是正确的。他们可能是正确的,也可能不是,这里的人不看他们就无法分辨。在编程的世界里,文字不值钱,代码才是最重要的,所以请始终包含所有相关代码!另外请分享您的调试尝试(例如您是否尝试过删除其他包含/加入?通过租户表包含/加入用户是否也会失败?等等...)。最后但并非最不重要的一点是,请始终提及您的确切 CakePHP 版本。
  • 谢谢你,伙计。当然我会更新答案
  • @ndm 关联已更新

标签: cakephp cakephp-3.x


【解决方案1】:

那么根据你提供给我们的,你有以下关系:

属性 hasMany Tenancies hasMany Tenants belongsTo Users 属性属于公司

假设您在表类中进行了设置,您可以使用包含类似于您在上面的操作的连接:

public function getExample($id) {
    return $this->find()
    ->contain([
        'Company' => function ($q) {
            return $q
                ->select(['id', 'company_name'])
                ->where(['Company.active = 1']);
        },
        'Tenancies' => function($q) {
            return $q
                ->select(['Tenancies.id','Tenancies.property_id','Tenancies.created',
                    'Tenancies.stage','Tenancies.landlord_offer_sent',
                    'Tenants.id','Tenants.stage', 'Tenants.user_id', 'Tenants.tenancy_id',
                    'Users.id', 'Users.email', 'Users.fullname'
                ])->leftJoin(['Tenants' => 'tenant'],[
                    'Tenants.tenancy_id = Tenancies.id'
                ])->leftJoin(['Users' => 'users'],[
                    'Users.id = Tenants.user_id'
                ])
                ->where([
                    'Tenancies.active = 1',
                    'Tenants.active = 1',
                    'Users.active = 1',
                ]);
        }
    ])
    ->where(['Property.active = 1', 'Property.id' => $id])
    ->toArray();
}

【讨论】:

  • 我编辑了这个,因为连接类型有一个小错误。它现在应该与左连接一起工作:)
  • 谢谢你,你是明星。我对查询做了一些更新。它现在像魅力一样工作
  • 为了符合 CakePHP 命名标准,你应该保持你的关系名称是复数的。只是一个建议:)
  • 克里斯,您可以编辑您的答案以显示这一点。 @Fury - 您应该将代码编辑留给帖子作者。
  • @chrisShick 我没有创建那些只是获取数据的表,这很痛苦,因为它不是复数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
  • 1970-01-01
相关资源
最近更新 更多