简体   繁体   中英

CakePHP Model belongsTo SQL Query

I'm working on an old project that has been coded by someone who is no longer at the company, and the project has been made with CakePHP 2.4.0 and I'm not super familiar with CakePHP.

I'm experiencing a weird problem where the belongsTo returns the wrong entry. I have three tables, Orders, Deals and Cities, which has the following structures.

Orders

+----+---------+
| id | deal_id |
+----+---------+
|  1 |       1 |
+----+---------+

Deals

+----+---------+
| id | city_id |
+----+---------+
|  1 |       2 |
+----+---------+

Cities

+----+-----------+
| id |   name    |
+----+-----------+
|  1 | Montreal  |
|  2 | Toronto   |
|  3 | Ottawa    |
|  4 | Québec    |
|  5 | Vancouver |
|  6 | Calgary   |
|  7 | Halifax   |
+----+-----------+

Inside the OrdersController , when I try to retrieve the city name:

$this->Order->Deal->City->field('name');

I get Calgary instead of the expected Toronto . Therefore, I've taken a look inside the City.php which has a property of orders , and that explains why I'm receiving Calgary since it's ordering by the name of the city in ascending order. If I put the property in in comment, I get Montreal instead of Toronto since it's no longer ordering by the name.

I know my Deal has the right city_id because when I do the following, I get 2 :

$this->Order->Deal->field('city_id'); // 2

City.php

class City extends AppModel
{
    public $order = "City.name asc";
}

Deal.php

class Deal extends AppModel
{
    public $belongsTo = array(
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id'
        )
    );
}

Now my questions are:

  1. Why is the wrong city returned from the relation?
  2. How can I see the executed SQL query for my action?

I've tried getting the datasource of the model but it returns an empty log.

$log = $this->Order->Deal->getDataSource()->getLog(false, false);

OrdersController

public function passengers($id = 0)
{
    $this->Order->id = $id;
    if (!$this->Order->exists()) {
        $this->redirect('/');
    }

    $name = $this->Order->Deal->City->field('name');
    var_dump($name); die;
}

As already mentioned in the comments, Model::field() issues a new query to retrieve a single field from the database, restricted to the very model on which you call the method, ie it requires the id on $this->Order->Deal->City to be set, and then queries the City record with that ID, it has nothing to do with associations or already retrieved data.

If you want the name of the City associated (via Deal ) with the Order that has the ID $id , then you either need to query on $this->Order and make sure that the City association is contained, or that the required recursive level is set:

$order = $this->Order->find('first', array(
    'conditions' => array('id' => $id),
    'contain' => 'Deal.City',
    // or
    // 'recursive' => 1
));

$name = $order['Deal']['City']['name'];

Or query on the City model and include the required joins that would restrict the record via the associated tables.

If you want to see the generated queries, enable debug mode in your app/Config/core.php , and for further insight install the Debug Kit plugin.

See also

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