实体虚拟字段在不同视图中的工作方式不同 - CakePHP 4

Entity Virtual Fields works differently in different views - CakePHP 4

我在数据库中有 3 个表:

一种产品包含许多配方,其数量相应,例如:

// in src/Model/Table/ProductsTable.php
public function initialize(array $config): void
{
    $this->belongsToMany('Recipes', [
        'foreignKey' => 'product_id',
        'targetForeignKey' => 'recipe_id',
        'joinTable' => 'Dishes',
    ]);
    $this->hasMany('Dishes');
}

// in src/Model/Table/RecipesTable.php
public function initialize(array $config): void
{
    $this->belongsToMany('Products', [
        'foreignKey' => 'recipe_id',
        'targetForeignKey' => 'product_id',
        'through' => 'Dishes',
    ]);        
    $this->hasMany('Dishes');
}

// in src/Model/Table/DishsTable.php
public function initialize(array $config): void
{
    $this->belongsTo('Products', [
        'foreignKey' => 'product_id',
        'joinType' => 'INNER',
    ]);
    $this->belongsTo('Recipes', [
        'foreignKey' => 'recipe_id',
        'joinType' => 'INNER',
    ]);
}

我创建了一个虚拟字段来计算单个产品所有配方的总成本:

// in src/Model/Entity/Product.php
class Product extends Entity
{
    protected $_accessible = [
        'title' => true,
        'unit' => true,
        'price' => true,
        'dishes' => true,
        'created' => true,
        'modified' => true,
    ];

    protected function _getTotalCost()
    {
        $dishes = $this->dishes;
        $total_cost = 0;

        foreach ($dishes as $dish) {                // <--- this is line 44
            $input_price = $dish->recipe->input_price;
            $quantity = $dish->quantity;
            $amount = $input_price * $quantity;
            $total_cost += $amount;
        }
        return $total_cost;
    }
}

它在 templates/Products/view 中完美运行。php:

echo $product->total_cost;
// result ;

但是在templates/Products/index.php中显示错误:

Warning (2): Invalid argument supplied for foreach() [APP/Model\Entity\Product.php, line 44]
Code Context
App\Model\Entity\Product::_getTotalCost() - APP/Model\Entity\Product.php, line 44
Cake\ORM\Entity::get() - CORE\src\Datasource\EntityTrait.php, line 289
Cake\ORM\Entity::__get() - CORE\src\Datasource\EntityTrait.php, line 129
include - ROOT\templates\Products\index.php, line 30
Cake\View\View::_evaluate() - CORE\src\View\View.php, line 1176
Cake\View\View::_render() - CORE\src\View\View.php, line 1134
Cake\View\View::render() - CORE\src\View\View.php, line 764
Cake\Controller\Controller::render() - CORE\src\Controller\Controller.php, line 696
Cake\Controller\Controller::invokeAction() - CORE\src\Controller\Controller.php, line 538
Cake\Controller\ControllerFactory::invoke() - CORE\src\Controller\ControllerFactory.php, line 79
Cake\Http\BaseApplication::handle() - CORE\src\Http\BaseApplication.php, line 251
Cake\Http\Runner::handle() - CORE\src\Http\Runner.php, line 77
Authentication\Middleware\AuthenticationMiddleware::process() - ROOT\vendor\cakephp\authentication\src\Middleware\AuthenticationMiddleware.php, line 124
Cake\Http\Runner::handle() - CORE\src\Http\Runner.php, line 73
Cake\Http\Middleware\CsrfProtectionMiddleware::process() - CORE\src\Http\Middleware\CsrfProtectionMiddleware.php, line 156
Cake\Http\Runner::handle() - CORE\src\Http\Runner.php, line 73

请告诉我如何解决这个问题。非常感谢您的帮助!

您的 view 操作的控制器可能使用 contain 来包含产品的菜肴和食谱,而 index 操作则不是。您应该能够简单地更新 index 中查询的 contain 部分,或者如果它完全缺失则添加它。