2010-11-03 10 views
2

Mon schéma a les relations suivantes:plusieurs conditions modèles CakePHP à trouver() avec HABTM

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

Je voudrais revenir tous les éléments d'un symbole élément donné qui appartiennent à un identifiant d'utilisateur donné. Je suis en mesure de récupérer tous les éléments qui appartiennent à l'utilisateur avec

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

et je suis en mesure de récupérer tous les éléments avec un nom d'élément donné avec

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

mais si je tente de utiliser le tableau de conditions ('Item.symbol' => $ itemSymbol, 'User.id' => de $ userid) sur $ this-> item-> find(), $ this-> item-> Utilisateur-> find() , $ this-> Utilisateur-> find(), ou $ this-> Utilisateur-> item-> find(), je reçois l'erreur soit

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

ou

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

Je l'ai dévoré HABTM dans toutes les versions du livre de cuisine et de lire des dizaines de forum/SO messages à ce sujet, mais je ne l'ai pas eu de chance dans la formation de cette requête.

Infodesks: // associations 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' => '', 
     ) 
    ); 

// associations 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' => '', 
     ) 
    ); 

// associations Transaction.php:

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

Pouvez-vous préciser le groupe '(1 = 1) par user_id' et pourquoi vous avez une relation' hasMany' et comme HABTM avec la transaction sur les deux modèles ?. –

+0

J'ai éliminé le (1 = 1) groupe par une partie user_id je l'ai copié de certains tutoriel et il est probablement superflu -. retirer n'a eu aucune incidence sur la question ou le résultat –

+0

A Transactions hasMany utilisateur (et vice versa), car t voici les données de transaction que je dois enregistrement qui n'a rien à voir avec l'adhésion à un utilisateur à un élément, comme la quantité de transaction, le prix de transaction, etc. Articles HABTM utilisateur parce qu'un utilisateur peut avoir plusieurs objets et chaque objet peut avoir beaucoup d'utilisateurs. Commenter seulement la relation de hasMany dans l'utilisateur et l'article n'a aucun impact sur les résultats. Commenter uniquement la relation HABTM dans User et Item n'a pas non plus d'impact sur les résultats. –

Répondre

3

Vous re chercher le comportement Containable; par exemple. Je suppose que l'utilisateur étend AppModel, ainsi Containable sera défini pour l'enfant (Utilisateur). Maintenant, dans votre contrôleur, les conditions de la classe associée peuvent être placées dans la clé 'contain' du second argv de find(); par exemple.

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

Cake trouver l'utilisateur correspondant et récupérer les éléments correspondants (avec le même user_id et le Item.Symbol spécifié. Mais soyez très prudent quand il n'est pas nécessaire d'utiliser « contenir » array =>(), sinon gâteau récupérera toutes les associations définies, qui taxera votre base de données.

+0

Merci beaucoup, Wayne! C'est juste le genre d'information que je cherchais. Une fois que je l'aurai mieux compris, je modifierai le livre de cuisine. Containable n'est pas mentionné une seule fois sur la page HABTM!Au fait, AppModel va-t-il à côté de AppController dans la structure du répertoire, ou est-ce qu'il va dans le dossier models? J'ai fini par appliquer Containable à chacun de mes modèles individuellement. –

+0

Glad it helps! AppModel doit être enregistré sous app/models/app_model.php. AppController doit être enregistré sous app/controllers/app_controller.php. Ils n'ont pas le même héritage! Bien sûr, vous pouvez appliquer Containable individuellement, mais cela rend la maintenance plus difficile! – Wayne

Questions connexes