3

I do not understand how to implement a many to many relation in CActiveDataProvider.

At first the situation, I have one Model "Company" with following relations:

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'),
);

Now I want to get all admins of a company. Normally I did:

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

So I have all administrators of a company.

But I did not parse, how to do it with a 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());

But with this way I get a company record with all administrators, but not an array containing all administrators.

Update: I could create an Model for the relation table {{company_user}} and use this, but I do not think its the right way, isn't it?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Jusophos
  • 41
  • 1
  • 6
  • put `array('condition' => 'company_id='.$company->id)` before `'with'` and keep only `'with' => array('admins')` – GBD Nov 12 '12 at 13:43
  • Good advice, but the result is **one** company entry and not an array of administrators entries. The problem is the widget, which i am using will display the one company entry and not a list of administrators. – Jusophos Nov 12 '12 at 13:49

2 Answers2

2

You can try following:

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

Edit: Above will create data provider that will return list of company models. If you want to get list of users than you need to specify 'User' model. 'with' property uses relation to build join condition.

You can use join condition like in other answer or you can define relation in user model, and reuse relation instead.

Try something as follows, please check that companies relation is defined on user model.

$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,
    ),
));
Edin Omeragic
  • 1,948
  • 1
  • 23
  • 26
  • Thank you. But the same problem. The result is **one** company entry and not an array of administrators entries. The problem is the widget, which i am using will display the one company entry and not a list of administrators. – Jusophos Nov 12 '12 at 13:54
  • A Widget like CGridView or similar will display the one company entry and not the list of admins. – Jusophos Nov 12 '12 at 13:55
  • I could create an Model for the relation table `{{company_user}}` and use this, but i do not think its the right way, isn't it? – Jusophos Nov 12 '12 at 13:58
1

I found a good solution. I use the model, which I want to display. In this case, an administrator is an user.

Now I join the tables manually.

$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,
    ),
));

The whole CActiveDataProvider will be returned by the Companymodel, so it is logical encapsulated.

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

I hope the solutions helps somebody.

Jusophos
  • 41
  • 1
  • 6