Yii Framework Forum: Problem z CGridView (odwołanie kolumny z relacji wiele-do-wiele) - Yii Framework Forum

Jump to content

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

Problem z CGridView (odwołanie kolumny z relacji wiele-do-wiele) Rate Topic: -----

#1 User is offline   gilek 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 11-September 09

Posted 03 June 2010 - 01:44 PM

Cześć:)

Mam problem z widgetem CGridView, a dokładniej z odwołaniem się do wartości kolumny z relacji wiele-do-wiele.

'value'=>'$data->groups->group'


Framework zwraca błąd:

Trying to get property of non-object

Brak kodu źródłowego


Gdy wywołam normalnie (nie przez wigdet);

$user = User::model()->findByPK('1'); $user->groups

Wynik jest poprawny - zwracana jest tablica obiektów group.

Męczę się w tym już kilka godzin i nie mogę dojść do ładu, dlatego proszę Was o pomoc.

Relacja jest zdefiniowana:

	
public function relations()
{
	return array(
		'groups' => array(self::MANY_MANY, 'Group', 'users_groups(id_user, id_group)'),		
	);
}


Metoda search:

public function search()
{
	$criteria=new CDbCriteria;

	$criteria->compare('login',$this->login,true);

	$criteria->compare('name',$this->name,true);

	$criteria->compare('surname',$this->surname,true);

	$criteria->compare('email',$this->email,true);

	$criteria->compare('lastActive',$this->lastActive,true);

	$criteria->compare('active',$this->active);

	$criteria->with = array('groups');

	return new CActiveDataProvider(get_class($this), array(
		'criteria'=>$criteria,
	));
}


Widget:

<?php $this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'user-grid',
	'dataProvider'=>$model->search(),
        'filter'=>$model,
		'columns'=>array(
             .
			 .
			 .
                array(
                    'filter'=>CHtml::listData(Group::model()->findAll(),'id','group'),
                    'header'=>'Grupy',
                    'name'=>'groups.group', //? nie wiem jak sie odwolac
                    'value'=>'$data->groups->group' // tu zwraca blad
                ),
            .
			.
			.
	),
)); ?>


Baza w zarysie ogółnym wygląda następująco:

Tabela users
id (PK) int(11)
login varchar(64)
passwd varchar(40)
name varchar(64)
surname varchar(64)
email varchar(64)
lastActive datetime
active tinyint(1)

Tabela users_groups
id_user (PK) int(11)
id_group (PK) smallint(6)

Tabela groups
id (PK) smallint(6)
group varchar(64)
0

#2 User is offline   krzysiek 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 07-May 10

Posted 07 June 2010 - 05:17 AM

Cześć! Pewnie już sobie poradziłeś, ale może ktoś inny będzie miał podobny problem.

Dzieje się tak dlatego że

$data->groups


to nie obiekt a tablica obiektów (grup do których należy user), stąd błąd. Poniższe powinno zadziałać:

$data->groups[0]->group


Oczywiście wypisana zostanie jedynie pierwsza wartość :). Lepiej zrobić tak:

'value' => 'implode("<br/>",$data->groups)'


oczywiście uprzednio uzupełniwszy klasę Group o metodę __toString

public function  __toString() {
   return $this->group;
}


Pozdro :)
0

#3 User is offline   gilek 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 11-September 09

Posted 07 June 2010 - 12:21 PM

dzięki krzysiek:) Poradziłem sobie, ale Twój sposób jest o wiele bardziej elegancki:)

Korzystają z farta:) wiesz może jak zrobić, aby Grid filtrował po tych grupach?

W tablicy column ustawiłem widgetu:

array(
   'filter'=>CHtml::listData(Group::model()->findAll(),'id','group'),
   'header'=>'Grupy',
   'name'=>'groups',
   'value'=>'implode(", ",$data->groups)',
),


name ustawiłem na wartość groups, choć nie wym czy przypadkiem do nie powinienem dodać nowej właściwości do modelu User (np. groupId)?

W metodzie Rules dodałem:

array('groups', 'safe', 'on'=>'search'),


Dodatkowo w search:
$criteria->compare('g.id',$this->groups);
$criteria->with = array('groups');


Całośc zwraca:

1054 Unknown column 'groups.id' in 'where clause'


Najpierw fw wywołuje

Querying SQL: SELECT COUNT(DISTINCT `t`.`id`) FROM `users` `t`  LEFT OUTER
JOIN `users_groups` `groups_g` ON (`t`.`id`=`groups_g`.`id_user`) LEFT
OUTER JOIN `groups` `g` ON (`g`.`id`=`groups_g`.`id_group`) WHERE
(g.id=:ycp0). Bind with parameter :ycp0='2'


a później (tu pojawia się błąd):

Error in querying SQL: SELECT `t`.`id` AS `t0_c0`, `t`.`login` AS `t0_c1`,
`t`.`passwd` AS `t0_c2`, `t`.`name` AS `t0_c3`, `t`.`surname` AS `t0_c4`,
`t`.`email` AS `t0_c5`, `t`.`lastActive` AS `t0_c6`, `t`.`active` AS
`t0_c7` FROM `users` `t`  WHERE (g.id=:ycp0) LIMIT 10. Bind with parameter
:ycp0='2'

?? :(((


Z góry dzięki za pomoc:))
0

#4 User is offline   krzysiek 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 07-May 10

Posted 08 June 2010 - 02:35 AM

Też miałem (mam?) z tym problem. Jak widać w zapytaniach pierwsze dotyczące ilości rekordów idzie z joinem, drugie już nie. Niestety, nie udało mi się wymusić joina w drugim zapytaniu. Jeżeli ktoś wie jak to zrobić to również byłbym wdzięczny za hinta :).

Ja obszedłem to za pomocą podzapytania, patrz niżej.

View Postgilek, on 07 June 2010 - 12:21 PM, said:

name ustawiłem na wartość groups, choć nie wym czy przypadkiem do nie powinienem dodać nowej właściwości do modelu User (np. groupId)?


Ja dodałbym do klasy User pole o nazwie np. 'filter_group' i taki też nadał name w widżecie.

public $filter_group;


Oznacz jako 'safe' dla odpowiedniego scenariusza, a w metodzie search() dodaj co następuje przed return:

if(is_string($this->filter_group) && strlen($this->filter_group) > 0) {
    $criteria->params[':groupname'] = $this->filter_group;
    $criteria->addCondition("t.id IN (SELECT ug.id_user FROM `users_groups` ug JOIN `groups` g ON ug.id_group = g.id WHERE g.group LIKE :groupname)");
}

return new CActiveDataProvider...


Powinno zadziałać. :)

Trzeba przy tym uważać żeby nie nadpisać w tablicy params żadnego parametru dodawanego przez Yii. Na szczęście mają one dość egzotyczne nazwy więc nie powinno być problemu.
0

#5 User is offline   gilek 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 11-September 09

Posted 08 June 2010 - 03:30 AM

dzięki za szybką odpowiedź i pomoc:) możliwe, że trochę poczekamy na jakąś wskazówkę...
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