Yii CActiveDataProvider Многие ко многим

Я не понимаю, как реализовать отношение «многие ко многим» в CActiveDataProvider.

Во-первых, у меня есть одна модель «Компания» со следующими отношениями:

return array(

        'owner'     => array(self::HAS_ONE, 'User', 'user_id'),
        'admins'    => array(self::MANY_MANY, 'User', '{{company_user}}(company_id,user_id)', 'condition' => 'is_admin = 1'),
        'members'   => array(self::MANY_MANY, 'User', '{{company_user}}(company_id,user_id)'),
        'standard_members' => array(self::MANY_MANY, 'User', '{{company_user}}(company_id,user_id)', 'condition' => 'is_admin = 0'),
);

Теперь я хочу получить всех администраторов компании. Обычно я делал:

$company = Company::model()->find('company_id=1');
var_dump($company->with('admins')->findAll());

Так что у меня есть все администраторы компании.

Но я не разбирал, как это сделать с помощью CActiveDataProvider.

$dataProvider_admins = new CActiveDataProvider('Company', array(

'criteria' => array(

    'with' => array(

        'admins' => array('condition' => 'company_id='.$company->id)
    ),
),
'pagination' => array(

    'pageSize' => 20,
),
));

var_dump($dataProvider_admins->getData());

Но таким образом я получаю запись компании со всеми администраторами, а не массив, содержащий всех администраторов.

Обновление: я мог бы создать модель для таблицы отношений {{company_user}} и использовать ее, но я не думаю, что это правильный путь, не так ли?


person Jusophos    schedule 12.11.2012    source источник
comment
поставить array('condition' => 'company_id='.$company->id) перед 'with' и оставить только 'with' => array('admins')   -  person GBD    schedule 12.11.2012
comment
Хороший совет, но результатом будет одна запись о компании, а не массив записей администраторов. Проблема в том, что виджет, который я использую, будет отображать одну запись компании, а не список администраторов.   -  person Jusophos    schedule 12.11.2012


Ответы (2)


Вы можете попробовать следующее:

$dataProvider_admins = new CActiveDataProvider('Company', array(
    'criteria' => array(
        'with' => array('admins'),
        'condition' => 'company_id=:id', 
        'params' => array("id" => $company->id) 
    ),
    'pagination' => array(
        'pageSize' => 20,
    ),
));

Изменить: выше будет создан поставщик данных, который вернет список моделей компании. Если вы хотите получить список пользователей, вам нужно указать модель «Пользователь». Свойство with использует отношение для построения условия соединения.

Вы можете использовать условие соединения, как в другом ответе, или вы можете определить отношение в пользовательской модели и вместо этого повторно использовать отношение.

Попробуйте следующее: проверьте, что отношения компаний определены в пользовательской модели.

$dataProvider_admins = new CActiveDataProvider('User', array(
    'criteria' => array(
        'with' => array('companies'),
        'condition' => 'companies.company_id=:id and is_admin = 1', 
        'params' => array("id" => $company->id) 
    ),
    'pagination' => array(
        'pageSize' => 20,
    ),
));
person Edin Omeragic    schedule 12.11.2012
comment
Спасибо. Но та же проблема. В результате получается одна запись о компании, а не массив записей администраторов. Проблема в том, что виджет, который я использую, будет отображать одну запись компании, а не список администраторов. - person Jusophos; 12.11.2012
comment
Виджет, такой как CGridView или аналогичный, будет отображать одну запись компании, а не список администраторов. - person Jusophos; 12.11.2012
comment
Я мог бы создать модель для таблицы отношений {{company_user}} и использовать ее, но я не думаю, что это правильный путь, не так ли? - person Jusophos; 12.11.2012

Я нашел хорошее решение. Я использую модель, которую хочу отобразить. В данном случае администратором является пользователь.

Теперь присоединяюсь к таблицам вручную.

$dataProvider_admins = new CActiveDataProvider('User', array(

    'criteria' => array(

        'join' => 'LEFT JOIN `{{company_user}}` ON `id` = `user_id` AND `company_id` = '.intval($company->id),
        'with' => array('profile'),
    ),
    'pagination' => array(
        'pageSize' => 20,
    ),
));

Весь CActiveDataProvider будет возвращен Companymodel, поэтому он логически инкапсулирован.

$dataProvider = Company::model()->find('id=5')->adminsDataProvider;

Я надеюсь, что решения помогут кому-то.

person Jusophos    schedule 13.11.2012