简体   繁体   中英

How belongsTo works with mutiple hasMany in contain cakephp 3.x

I need the users for with given property id eg Property.id = $id

I want to build this query.

$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
        "; 

Here is my associations:

// 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'
    ]);
}

I can get the hasMany associations but when it comes to get belongsTo for Users it tells me Tenants is not associated with Users. How ever the associations are set and they are correct. I am running the following ORM from PropertyTable.

$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,
                ]);
            });

Any help pelase

Well according to what you have provided us, you have the following relationships:

Properties hasMany Tenancies hasMany Tenants belongsTo Users Properties belongsTo Companies

Assuming you have that set up in your Table Classes, you can use joins with contains similar to how you did it above:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM