Anuj TBE
Anuj TBE

Reputation: 9816

CakePHP 3 : Unknown method

I am creating a function in model to find all related services.

function in ServiceCategory.php

class ServiceCategory extends Entity
{

    public function relatedServices($id)
    {
        return $this->find('all', [
          'conditions' => [
            'where' => [
              'id !=' => $id
            ],
            'limit' => 5
          ]
        ]);
    }
}

And calling in ServiceCategoriesController.php

public function view($id = null)
    {
        $serviceCategory = $this->ServiceCategories->get($id, [
            'contain' => ['Services']
        ]);

        $relatedServices = $this->ServiceCategories->relatedServices($id);

        $this->set('serviceCategory', $serviceCategory);
        $this->set('relatedServices', $relatedServices);
        $this->set('_serialize', ['serviceCategory']);
    }

But it gives Unknown method 'relatedServices'

Is there any thing wrong I am doing ?

Upvotes: 2

Views: 4579

Answers (1)

AD7six
AD7six

Reputation: 66349

The code is in the wrong class

In the question:

class ServiceCategory extends Entity

This is an entity class

$relatedServices = $this->ServiceCategories->relatedServices($id);

This is making a call on a table object, table objects and entities do not inherit from each other, the method is unavailable to the table class.

Move the code to the table class

The direct solution is to move the code to the table class:

// src/Model/Table/ServiceCategoriesTable.php
namespace App\Model\Table;

class ServiceCategoriesTable extends Table
{

    public function relatedServices($id)
    {
        return $this->find('all', [
          'conditions' => [
            'where' => [
              'id !=' => $id
            ],
            'limit' => 5
          ]
        ]);
    }

Though the arguably correct/better way to do that is to implement a finder:

// src/Model/Table/ServiceCategoriesTable.php
namespace App\Model\Table;

use Cake\ORM\Query;
use \InvalidArgumentException;

class ServiceCategoriesTable extends Table
{

    public function findRelatedServices(Query $query, array $options)
    {
        if (!isset($options['id'])) {
            $message = sprintf('No id in options: %s', json_encode($options));
            throw new InvalidArgumentException($message);
        }
        
        $query->where(['id !=' => $options['id']);

        return $query;
    }

Which would be called in exactly the same way as other find calls:

$relatedServices = $this->ServiceCategories->find(
    'relatedServices', 
    ['id' => $id]
);

Upvotes: 5

Related Questions