CakePHP несколько модельных условий в find () с HABTM - PullRequest
2 голосов
/ 03 ноября 2010

Моя схема имеет следующие отношения:

User hasMany Transaction belongsTo User 
Item hasMany Transaction belongsTo Item
User hasManyAndBelongsTo Item using Transaction as join table 

Я хочу вернуть все элементы данного символа элемента , которые принадлежат данному идентификатору пользователя .Я могу получить все элементы, которые принадлежат пользователю с помощью

$this->User->find('all', array( 'conditions' => 
    array( 'User.id' => $userId ) ) )

, и я могу получить все элементы с данным именем элемента с помощью

$this->Item->find( 'all', array( 'conditions =>
    array( 'Item.symbol' => $itemSymbol ) );

, ноесли я попытаюсь использовать массив условий ('Item.symbol' => $ itemSymbol, 'User.id' => $ userId) в $ this-> Item-> find (), $ this-> Item-> User-> find (), $ this-> User-> find () или $ this-> User-> Item-> find (), я получаю либо ошибку

SQL Error: 1054: Unknown column 'Item.id' in 'where clause'

, либо

SQL Error: 1054: Unknown column 'Item.symbol' in 'where clause'

Я проглотил HABTM во всех версиях кулинарной книги и прочитал десятки постов форума / SO об этом, но мне не повезло в формировании этого запроса.

Соответствующая информация: // Ассоциации User.php

// a user hasMany transactions
     var $hasMany = array('Transaction' =>
      array('className' => 'Transaction',
      'order' => 'Transaction.created DESC', // order by descending time of transaction
      //'limit' => '1', // change this if we need more, for example, if we need a user transaction history
      'foreignKey' => 'user_id',
      )
      ); 
    // a user hasAndBelongsTo items through transactions
    var $hasAndBelongsToMany = array('Item' =>
        array('className' => 'Item',
            'joinTable' => 'transactions',
            'foreignKey' => 'user_id',
            'associationForeignKey' => 'item_id',
            'order' => '',
            'limit' => '',
            'unique' => true,
            'finderQuery' => '',
            'deleteQuery' => '',
        )
    );

// Ассоциации Item.php

var $hasMany = array('Transaction' =>
        array('className' => 'Transaction',
            'order' => 'Transaction.created DESC',
            //'limit' => '1', // change this if we need more, for example, if we need a item transaction history
            'foreignKey' => 'item_id',
        )
    );
    // a item hasAndBelongsTo users through transactions
    var $hasAndBelongsToMany = array('User' =>
        array('className' => 'User',
            'joinTable' => 'transactions',
            'foreignKey' => 'item_id',
            'associationForeignKey' => 'user_id',
            'order' => '',
            'limit' => '',
            'unique' => true,
            'finderQuery' => '',
            'deleteQuery' => '',
        )
    );

// Ассоциации Transaction.php:

var $belongsTo = array('User', 'Item');

1 Ответ

3 голосов
/ 03 ноября 2010

Вы ищете контейнерное поведение; например,

// app_model.php
var $actsAs = array(
    'Containable'
);

Я предполагаю, что Пользователь расширяет AppModel, поэтому Containable будет установлен для дочернего элемента (User). Теперь в вашем контроллере условия для связанного класса могут быть помещены в клавишу «содержать» второго аргумента функции find (); например,

// users_controller.php
$this->User->find('first', array(
    'conditions' => array('User.id' => $userId),
    'contain' => array(
        'Item' => array(
            'conditions' => array('Item.symbol' => $itemSymbol)
        )
    )
);

Cake найдет подходящего Пользователя и получит соответствующие Предметы (с тем же идентификатором user_id и Item.Symbol. Но будьте очень осторожны, если в этом нет необходимости, указывать «contains» => array (), иначе Cake получит все определенных ассоциаций, которые будут облагать налогом вашу базу данных.

...