Yii Framework Forum: CGridView - HAS_MANY + sortowanie.. - Yii Framework Forum

Jump to content

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

CGridView - HAS_MANY + sortowanie.. Rate Topic: -----

#1 User is offline   r4nd4ll 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 39
  • Joined: 09-December 10

Posted 09 December 2010 - 02:03 PM

Witam,
Przejrzałem już chyba całe tutejsze forum i nadal nie znalazłem rozwiązania mojego problemu..
Mam 2 tablice Article i Article_Txt w relacji Article HAS_MANY Article_Txt, kluczem obcym łączącym obie tablice jest artidx. W praktyce, z wykorzystaniem dodatkowego parametru language robi się z tego relacja 1:1 (1 artykuł ma 1 odpowiednik w tablicy tekstowej względem 1 języka). W wygenerowanym przez Gii CRUD dla Artykułu chciałem zrobić listę z wyszukiwarką (search), wzbogaconą o elementy z relacyjnej tablicy tj. pola z modelu Article + np. tytuł z Article_Txt (tylko w domyślnym języku - czyli praktycznie 1:1)..
Uświadomiłem sobie już, że nici z eager loading w CGridView przy takim układzie (HAS_MANY, MANY_MANY).. (czemu? nie rozumiem dlaczego można w $criteria metody search() używając with przekazać parametru, dzięki któremu join nie zwróci tablicy, a jedynie pojedyńczą encję przypisaną do głównego obiektu? czy jest to niedopatrzenie ze strony twórców fv?), więc wykorzystując lazy loading w kolumnie użyłem:
        array(
        	'name'=>'art_txts.name',
        	//'value'=>'$data->art_txts->name',
        	'value'=>'ArticleTxt::model()->findByAttributes(array("artidx"=>$data->artidx, "language"=>0))->name'
        ),


i powiedzmy, że ok - wyświetla się aczkolwiek wykonuje się więcej sqli niż bym chciał..

Za nic nie mogę dojść do tego jak nad polem z tytułem wyświetlić filter w postaci pola tekstowego. Nie chcę wyświetlać selecta, gdyż jest to tytuł artykułu, więc wybór z tablicy opcji mija się z celem..

Relacja:
'art_txts' => array(self::HAS_MANY, 'ArticleTxt', 'artidx',


Kombinacje w search(): ..
		$criteria=new CDbCriteria;

		$criteria->compare('artidx',$this->artidx);
		$criteria->compare('catidx',$this->catidx);
		$criteria->compare('status',$this->status);
		$criteria->compare('updated_at',$this->updated_at,true);
		$criteria->compare('created_at',$this->created_at,true);
		$criteria->compare('views_cnt',$this->views_cnt);
		
		//$criteria->compare('art_txts.name', $this->art_txts->name, true);
		
		$criteria->with = array(
			'art_txts'=>array(
				'select'=>'name', 
				//'joinType' => 'INNER JOIN',
				'condition' => 'art_txts.language=:language AND art_txts.artidx = :artidx', 
				'params' => array(':language' => 0, ':artidx' => $this->artidx),
				'together' => true
			),
		);
		
		
		return new CActiveDataProvider(get_class($this), array(
			'criteria'=>$criteria
			)
		));


Proszę o jakieś naprowadzenie. Może ja coś robię źle?
Podsumowując, 2 pytania:
Czy istnieje w przypadku takim jak zaprezentowałem jakiś sposób użycia eager loading do wyświetlenia danych w CGridView ?
W jaki sposób nie mając pola art_txts.name zdefiniowanego w modelu Article mogę utworzyć filter tekstowy w wyszukiwarce?

Z góry dzięki za odp.
0

#2 User is offline   aztech 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 206
  • Joined: 12-December 08
  • Location:Poland

Posted 10 December 2010 - 04:54 AM

View Postr4nd4ll, on 09 December 2010 - 02:03 PM, said:

(czemu? nie rozumiem dlaczego można w $criteria metody search() używając with przekazać parametru, dzięki któremu join nie zwróci tablicy, a jedynie pojedyńczą encję przypisaną do głównego obiektu? czy jest to niedopatrzenie ze strony twórców fv?)


Wydaje mi się, że główną przyczyną twojego problemu jest to, że masz zdefiniowaną relację art_txts jako HAS_MANY i właśnie tę relację chcesz użyć do otrzymania jednego tekstu. HAS_MANY zawsze zwracać będzie tablicę, nawet jeśli będziesz miał w niej jeden element (np. konkretny tekst dla konkretnego języka).

Powinieneś utworzyć sobie nową relację, np. articleTextWithLang, zdefiniowaną jako HAS_ONE i używać ja za każdym razem podając
'condition' => 'art_txts.language=:language'

I'm not complete idiot... some parts are missing!
0

#3 User is offline   r4nd4ll 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 39
  • Joined: 09-December 10

Posted 10 December 2010 - 06:17 AM

View Postaztech, on 10 December 2010 - 04:54 AM, said:

Wydaje mi się, że główną przyczyną twojego problemu jest to, że masz zdefiniowaną relację art_txts jako HAS_MANY i właśnie tę relację chcesz użyć do otrzymania jednego tekstu. HAS_MANY zawsze zwracać będzie tablicę, nawet jeśli będziesz miał w niej jeden element (np. konkretny tekst dla konkretnego języka).

Powinieneś utworzyć sobie nową relację, np. articleTextWithLang, zdefiniowaną jako HAS_ONE i używać ja za każdym razem podając
'condition' => 'art_txts.language=:language'




Super, dzięki :) Działa oczywiście, tylko pytanie czy nie gryzie się to w żaden sposób z dobrą praktyką programowania w Yii (tj. 2 relacje do tej samej tablicy w różnych wariantach)?
Jakbyś mi jeszcze pomógł zdefiniować tekstowy filter dla tego pola z relacji.. byłbym bardzo wdzięczny ;)
0

#4 User is offline   r4nd4ll 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 39
  • Joined: 09-December 10

Posted 10 December 2010 - 10:43 AM

Poradziłem sobie :)
Jakby jeszcze komuś było potrzebne:

Model:

public $name; //dodane pole
... 
		$criteria->with = array('art_txts_with_lang');
		$criteria->together = true;
		$criteria->compare('art_txts_with_lang.name', $this->name, true);
				
		return new CActiveDataProvider(get_class($this), array(
			'criteria'=>$criteria,
			'sort'=>array(
				'attributes'=>array(
					'*',
					'name'=>array(
						'asc'=>'art_txts_with_lang.name',
						'desc'=>'art_txts_with_lang.name DESC',
						'label'=>'Tytuł'
					)
				)
			)			
		));


Widok (kolumna CGridView):
        array(
        	'name'=>'name',
        	'value'=>'$data->art_txts_with_lang->name',
        ),

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