wtih() Problem bei relationalem AR

Hallo zusammen,

ich habe folgendes Problem. Ich möchte 2 Tabellen, die über eine Relationstabelle (MANY_MANY) verbunden sind abfragen und dabei sowohl von Tabelle 1 als auch von Tabelle 2 Conditions in die Where-Klausel bekommen. Folgenden Code habe ich im Controller:




$criteria=new CDbCriteria;

$criteria->condition = 'film.status=1';

$criteria->order = 'filmtitel ASC';


$withOption = array();

$withOption['genres']['params'][':genreid'] = 8;


$films = film::model()->with($withOption)->findAll($criteria);

$this->render('index', array('films' => $films, 'pages' => $pages,));



Der erzeugte SQL sieht so aus:




SELECT `film`.`filmid` AS `t0_c0`, `film`.`filmtitel` AS `t0_c1`, `film`.`produktionsjahr` AS `t0_c2`, `film`.`status` AS `t0_c3`, t1.`genreid` AS `t1_c0`, t1.`genretitel` AS `t1_c1`, t1.`status` AS `t1_c2` FROM `film` INNER JOIN `genrefilm` genres_t1 ON (`film`.`filmid`=genres_t1.`genreid`) INNER JOIN `genre` t1 ON (t1.`genreid`=genres_t1.`filmid`) WHERE (film.status=1) ORDER BY filmtitel ASC



Ich möchte aber, diese Abfrage:




SELECT `film`.`filmid` AS `t0_c0`, `film`.`filmtitel` AS `t0_c1`, `film`.`produktionsjahr` AS `t0_c2`, `film`.`status` AS `t0_c3`, t1.`genreid` AS `t1_c0`, t1.`genretitel` AS `t1_c1`, t1.`status` AS `t1_c2` FROM `film` INNER JOIN `genrefilm` genres_t1 ON (`film`.`filmid`=genres_t1.`genreid`) INNER JOIN `genre` t1 ON (t1.`genreid`=genres_t1.`filmid`) WHERE (film.status=1 AND t1.genreid=<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> ORDER BY filmtitel ASC



Die Models an sich sehen i.O. aus, zumal ich ja auch Ergebnisse bekomme. Nur eben die falschen ohne die weitere Einschränkung. Wie bekomme ich das aber hin?

Besten Dank für alle Antworten.

Wie sieht denn deine Relation zu genres aus? Wenn du’s so machst, wie im Blog-Tutorial mit tagFilter, sollte es klappen. Es ist o.k. wenn die genres condition nicht in WHERE sondern im ON bei der Join-Condition steht, du machst ja nen INNER JOIN.

http://www.yiiframework.com/doc/blog/post.model

Das ist vom film-Model:




return array('genres' => array(self::MANY_MANY,

'genre',

'genrefilm(genreid, filmid)',

'together' => true,

'joinType' => 'INNER JOIN')

);



und das vom genre-Model:




return array('filme' => array(self::MANY_MANY,

'film',

'genrefilm(genreid, filmid)',

'together' => true,

'joinType' => 'INNER JOIN')

);



Sollte eigentlich passen, oder?

Entweder so:


return array(

  'genres' => array(self::MANY_MANY,

    'genre',

    'genrefilm(genreid, filmid)',

    'together' => true,

    'joinType' => 'INNER JOIN',

    'condition'=>'genrefilm.genreid=:genreid'),

  )

);

oder diese condition in dein $criteria mit einbauen (inkl. Tabellenname).

Erstmal besten Dank für die Antworten, leider komm ich da nicht wirklich weiter.

Criteria sehen jetzt so aus:


$criteria=new CDbCriteria;

$criteria->condition = 'film.status=1';

$criteria->condition = 'genrefilm.genreid=:genreid';

$criteria->params = array(':genreid' => <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />;

$criteria->order = 'filmtitel ASC';

Ergebnis: Unknown column ‘genrefilm.genreid’ in ‘where clause’ bei diesem SQL


SELECT `film`.`filmid` AS `t0_c0`, `film`.`filmtitel` AS `t0_c1`, `film`.`produktionsjahr` AS `t0_c2`, `film`.`status` AS `t0_c3` FROM `film` WHERE (genrefilm.genreid=:genreid) ORDER BY filmtitel ASC

Liegt natürlich daran, dass yii hier keinen join anlegt und damit auch die tabelle nicht kennt.

Hier vielleicht noch die Relations des Relations-Model:


return array(

'filme' => array(self::HAS_MANY, 'film', 'filmid'),

'genres' => array(self::HAS_MANY, 'genre', 'genreid')

);

Vielleicht liegt es ja daran.

Und so, wie du’s ursprünglich hattest, inkl. der Relation-Definition von meinem Post vorhin?


$criteria=new CDbCriteria;

$criteria->condition = 'film.status=1';

$criteria->order = 'filmtitel ASC';


$withOption = array();

$withOption['genres']['params'][':genreid'] = 8;


$films = film::model()->with($withOption)->findAll($criteria);

$this->render('index', array('films' => $films, 'pages' => $pages,));

Ich hab jetzt die vergangenen Tage nochmals alles mögliche herumprobiert und bin leider mit selbem Ergebnis rausgekommen. Irgendwie will yii den SQL nicht so bauen wie ich ihn möchte!

Hat irgendwer noch einen Tipp oder hat sich mit selbem Problem bereits herumgeschlagen?

Besten Dank für alle Hinweise.

Du musst für die tabellen beim join einen alias vergeben, den du dann auch in deiner where clause verwendest. wenn kein alias angegeben wird, verwendet yii einen eignen.





//movie relations

public function relations() {

    return array(

        'roles' => array(self::HAS_MANY, 'Role', 'movieId' , 'with' => 'actor'),

        'genres' => array(self::MANY_MANY, 'Genre', 'MovieGenre(movieId, genreId)')

    );

}


$with = array(

                    'genres' => array(

                                    'alias' => 'Genre',

                                    'joinType' => 'INNER JOIN',

                                    'together' => true,

                                    'condition' => 'Genre.slug = :slug',

                                    'params' => array('slug' => $genre->slug)

        ));


//movie/admin/genre/action

$genreSlug = Yii::app()->request->getParam('genre', '');

$genre = Genre::model()->find('slug = :slug', array('slug' => $genreSlug));


$models = Movie::model()->with($with)->findAll();