【问题标题】:CakePHP associations: handle null idCakePHP 关联:处理空 id
【发布时间】:2020-05-19 07:23:14
【问题描述】:

我有这个模型:

Proforma
  ->hasMany('ItemProformas', ['foreignKey' => 'proforma_id']);
  ->belongsTo('Customers', ['foreignKey' => 'customer_id']);
  ->belongsTo('ProformaStates', ['foreignKey' => 'proforma_state_id']);
  ->hasMany('Invoices', ['foreignKey' => 'proforma_id']);

ItemProformas
  ->belongsTo('Proformas', ['foreignKey' => 'proforma_id', 'joinType' => 'INNER']);
  ->belongsTo('ItemDeliveryNotes', ['foreignKey' => 'item_delivery_note_id']);

ItemDeliveryNotes
    ->belongsTo('DeliveryNotes', ['foreignKey' => 'delivery_note_id', 'joinType' => 'INNER']);
    ->belongsTo('ItemOrders', ['foreignKey' => 'item_order_id']);
    ->belongsTo('ItemOrdersTypes', ['foreignKey' => 'item_orders_type_id']);
    ->belongsTo('Products', ['foreignKey' => 'product_id']);

每个ItemProforma 可能有一个ItemDeliveryNotes,否则外键将是null。这是我的paginate 电话:

$this->paginate = [
    'contain' => [
        'Customers',
        'ProformaStates',
        'ItemProformas' => ['ItemDeliveryNotes' => ['DeliveryNotes']]
    ]
];

有了这个模型,我得到了 拥有 item_delivery_note_id 集的所有itemProforma。相反,即使item_delivery_note_idnull,我也很想得到它们。

我不确定belongsTo 在这里是否正确(我的意思是在ItemProformas 定义中)。但是hasOne 暗示它一个关联的行,而不是可能有一个。

检索 all itemProformas 的正确语法是什么,即使它们没有关联任何 ItemDeliveryNote?但如果他们有,我还需要检索 ItemDeliveryNote 对象。

【问题讨论】:

    标签: php sql cakephp associations


    【解决方案1】:

    关联类型取决于您的架构。如果外键在源表中,则为belongsTo,如果外键在目标表中,则为hasOne

    是否必须存在相关记录也主要取决于架构,而不是关联类型。如果外键可以为空,则相关记录是可选的。如果以及如何在应用程序级别执行该约束则是另一回事。

    话虽如此,ItemDeliveryNotesDeliveryNotes 都是 belongsTo,默认情况下将使用连接,因此两个关联将连接到同一个查询中,并且由于您已将 DeliveryNotes 关联配置为使用INNER 连接,它将排除不存在DeliveryNotes 的行,当然也有不存在ItemDeliveryNotes 的情况。

    假设您的架构被正确/正确地建模,例如,您可以更改关联配置以在适用的情况下默认使用 LEFT 连接,或者您可以根据每个查询更改包含的配置(即手动,或使用自定义查找器):

    $this->paginate = [
        'contain' => [
            'Customers',
            'ProformaStates',
            'ItemProformas' => [
                'ItemDeliveryNotes' => [
                    'DeliveryNotes' => [
                        'joinType' => \Cake\Database\Query::JOIN_TYPE_LEFT,
                    ],
                ],
            ],
        ],
    ];
    

    更改ItemDeliveryNotes 的获取策略也可以工作(尽管根据记录的数量可能会很费力),即使用select 策略而不是join 策略,然后是关联的ItemDeliveryNotes记录是在单独的查询中检索的,因此不会影响ItemProformas 的检索:

    $this->paginate = [
        'contain' => [
            'Customers',
            'ProformaStates',
            'ItemProformas' => [
                'ItemDeliveryNotes' => [
                    'strategy' => \Cake\ORM\Association::STRATEGY_SELECT,
                    'DeliveryNotes',
                ],
            ],
        ],
    ];
    

    【讨论】:

    • 谢谢,我把模型中的join类型改成了LEFT,因为错了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多