Yii Framework Forum: Many_Many - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Many_Many Rate Topic: -----

#1 User is offline   test_yii 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 14
  • Joined: 16-January 12

Posted 07 March 2012 - 11:56 AM

Witam, podczas swojej pracy z yii napotkałem na taki o to problem:

Mam w bazie 3 tabele, dla każdej z nich wygenerowałem model za pomocą gii:

Tabele:

kategorie:
- id
- nazwa

posty:
- id
- nazwa

kategorie_posty:
- id
- post_id
- category_id

Efekt jaki chciałbym osiągnąć, to po kliknięciu w nazwe katogorii chciałbym uzyskać listę przynaleznych postów, chciałbym to zrobić za pomocą CDbCriteria - bo chciałbym sobie tym później ładnie zarządzać poprzez filtry ajaxowe. Nie bardzo wiem jak to rozpracować, kombinowałem coś z witch(), ale efekty nie są zadowalające. Miałby ktos jakąs wskazówkę która pozwoliłaby mi ruszyć z miejsca?
0

#2 User is offline   sidewinder 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 218
  • Joined: 08-July 09
  • Location:Poland

Posted 08 March 2012 - 03:06 AM

Koniecznie przeczytaj ten rozdział: http://www.yiiframew...en/database.arr

Z tabeli kategorie_posty wywal id, oraz usuń model do tej tabeli. Jak masz ustawione klucze zewnętrzne ? Jeżeli baza danych z której korzystasz obsługuje klucze zewnętrzne, to gii powinien odpowiednio wygenerować modele.
Najważniejsza jest funkcja relations().
Tak na przykład model Posty będzie miał taką funkcję relations:
public function relations(){
 		return array(
 			'kategorie'=>array(self::MANY_MANY, 'Kategorie',
   				'kategorie_posty(post_id, category_id)'),
 		);}


Teraz możesz pobrać posty z kategoriami tak:
$posty=Posty::model()->with('kategorie')->findAll();
CVarDumper::dump($posty[0]);

Jeżeli chcesz używać CDbCriteria, to tak samo ustawiasz sobie właściwość with a obiekt tej klasy przekazujesz do funkcji find() modelu:
$criteria=new CDbCriteria; 
$criteria->with('kategorie');
...
//inne kryteria wyszukiwania
...
$posty=Posty::model()->find($criteria);  

---------------------------------------------------------------------
"Never memorize what you can look up in books."
Albert Einstein
0

#3 User is offline   test_yii 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 14
  • Joined: 16-January 12

Posted 08 March 2012 - 10:10 AM

Klucze w bazie danych są ok.

W modelu postów mam taka relację(MANY_MANY)

mam równiez taką metodę:

public function search($id){
   $criteria=new CDbCriteria;
   $criteria->compare('id',$this->id);
   $criteria->compare('title',$this->name,true);
   $criteria->compare('text',$this->mail,true);
   $criteria->compare('insert_time',$this->insert_time,true);
   $criteria->with = array('kategorie');
   $criteria->condition = 'kategorie.id = '.$id;
   return new CActiveDataProvider($this, array(
      'criteria'=>$criteria,
   ));
}



W kontrolerze:

public function actionViewPosts($id){
   $model=new Posts();
   $model->search($id);
   $model->unsetAttributes(); 
   if(isset($_GET['Posts']))
     $model->attributes=$_GET['Posts'];
   $this->render('viewPosts',array(
      'posts'=>$model,
      'id'=>$id
   ));
}


W widoku:

<?php 
$this->widget('zii.widgets.grid.CGridView', array(
   'id'=>'posts-grid',
   'dataProvider'=>$posts->search($id),
   'filter'=>$posts,
   'columns'=>array(
	'id',
	'title',
	'text',
	'link',
	array(
	   'class'=>'CButtonColumn'
	),
   ),
),
)); 
?>


I niestety, w prawdzie wyszukuje posty, ale znajduje dla każdej kategorii wszystkie(tzn. nie dzieli na kategorie - zawsze mam wszystie posty :/). W dodatku padła ta światna przeszukiwajka tabeli -> chcąc filtrować sobie ajax'owo po kolumnach system tylko mieli i nic nie zmienia:/

PS.
Gdy utworzyłem model kategorie_posty i w nim zmodyfikowałem funckcje search to działało tylko z koleji zamiast nazw miałem same id :/
0

#4 User is online   redguy 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 809
  • Joined: 02-July 10
  • Location:Central Poland

Posted 11 March 2012 - 11:02 AM

metoda CDbCriteria::compare modyfikuje zawartosc atrybutu 'condition', ktory pozniej nadpisujesz:
$criteria->condition = 'kategorie.id = '.$id;

przenies ta linie przed wszystkie inne wywolania 'compare' i powinno byc lepiej. Polecam tez wyrobienie sobie nawyku uzywania wszedzie parametrow - latwiej uniknac SQLInjection...
public function search($id){
   $criteria=new CDbCriteria;
   $criteria->with = array('kategorie');
   $criteria->condition = 'kategorie.id = :kat_id';
   $criteria->params[':kat_id'] = $id;

   $criteria->compare('id',$this->id);
   $criteria->compare('title',$this->name,true);
   $criteria->compare('text',$this->mail,true);
   $criteria->compare('insert_time',$this->insert_time,true);
   return new CActiveDataProvider($this, array(
      'criteria'=>$criteria,
   ));
}

red
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users