2010-12-13 63 views
2

Nous sommes désolés de poser toutes ces questions sur Kohana. Ils sont généralement ignorés. Je pense que je viens de trouver un bug. Je fais une jointure entre deux tables qui ne sont pas directement liées.Bug dans Kohana 3 ORM?

$results = ORM::factory('foo')->join("bar")->on("foo.foreign_id", "=", "bar.id"); 

Cela génère une requête qui ne résout pas les noms de table explicitement:

SELECT * FROM `foo` JOIN `bar` ON (`foo`.`foreign_id` = `bar`.`id`) 

Ce qui donne (phpMyAdmin) une table qui ressemble à ceci:

id time   foreign_id  blah_int id baz 
4  1291851245 3   0    3 52501504 

avis il y a deux colonnes id, une pour la table foo et une pour bar. Ceci est un vrai problème. Parce que maintenant, dans mes résultats, si la boucle I à ...

foreach ($results as $result) { 
    echo $result->id; // prints 3!!! 
} 

Parce que mes résultats devraient être foo objets, je compte obtenir un id de 4, mais il me donne 3 à cause de la jointure. Est-ce un bug dans la bibliothèque ORM? Dois-je utiliser une méthode différente pour limiter mes résultats à la requête? Je ne veux vraiment pas faire deux requêtes séparées où je charge tous les identifiants bar, puis chargez mes foo de cette façon, mais il semble que je dois le faire.

+0

Avez-vous essayé les relations ORM (http://kohanaframework.org/guide/tutorials.orm)? Quelque chose comme foreach ($ foo-> barres comme $ bar) {...} – biakaveron

+0

Les tables ne sont pas liées, sauf indirectement. Ils partagent une relation avec une autre table. Donc mon alternative est de charger les ids de la table en commun en premier, mais je préférerais ne pas le faire. – Tesserex

Répondre

1

Vous devez utiliser l'objet de base de données pour créer des requêtes brutes, non ORM, comme celui-ci:

$results = DB::select()->from('foo')->join('bar')->on("foo.foreign_id", "=", "bar.id")->execute(); 

Vous devrez spécifique des alias de colonne mais pour rendre votre travail de recherche, sauf si vous utilisez ORM comme il était prévu.

En utilisant ORM

Si vous souhaitez utiliser ORM, vous devez définir les relations dans votre modèle. Vous mentionnez qu'ils partagent une relation avec une autre table donc dans votre cas, vous pouvez utiliser a beaucoup à travers une relation comme ceci:

protected $_has_many = array(
    'bars' => array('model' => 'bar', 'through' => 'other_table', 'foreign_key' => 'foreign_id'), 
    ); 

Bien que votre exemple comme donné suggère qu'une relation has_many droit travaillerait:

protected $_has_many = array(
    'bars' => array('model' => 'bar','foreign_key' => 'foreign_id'), 
    ); 

Cela vous permettra d'accéder à toutes les barres en utilisant une déclaration comme

$bars = $results->bars->find_all(); 
foreach($bars as $bar) 
{ 
    echo $bar->id; // should echo 4, assuming one record in bars with id 4 
} 

Le Kohana 3.1 ORM Reference Guide est bon endroit pour commencer si vous voulez en savoir plus sur ORM et les relations

Utilisation de l'objet de base de données Kohana et générateur de requêtes

Si vous préférez des requêtes ad hoc et faites les jointures avec le générateur de requêtes, vous avez probablement entrer en collision les noms de colonnes quel que soit si vous utilisez Kohana ou seulement des requêtes brutes (pop "SELECT * FROM foo JOIN bar ON (foo. foreign_id = bar. id) "dans MySQL et vous obtiendrez exactement le même résultat.)

Kohana, tout comme MySQL vous permet de définir des alias de colonnes pour cette raison précise.(Voir here for more information)

Ressaisissez votre requête comme suit:

$results = DB::select('id', 'time', 'foreign_id', array('bar.id', 'bar_id'), 'baz')->from('foo')->join("bar")->on("foo.foreign_id", "=", "bar.id")->execute(); 

Cela renverra:

id time   foreign_id  blah_int bar_id baz 
4  1291851245 3    0   3  52501504