CActiveDataProvider с пользовательским значением

В моем проекте Yii мне нужно искать и сортировать данные по некоторому пользовательскому значению. я имею 'users' таблица, и мне нужно, чтобы каждый экземпляр пользователя имел month_profit свойство, которое должно объединять данные SQL + множество моих собственных расчетов. На данный момент у меня в модели User:

public $month_profit;

public function search($pageSize = 10, $defaultOrder = '`t`.`reg_date` DESC')
{
$criteria = new CDbCriteria;
$criteria->with = array('money');
$requests_table = Requests::model()->tableName();
$requests_count_sql = "(SELECT COUNT(*) FROM $requests_table rt WHERE rt.partner_id = t.id) ";

$referrals_table = Referrals::model()->tableName();
$referrals_count_sql = "(SELECT COUNT(*) FROM $referrals_table reft WHERE reft.user_id = t.id) ";
$referrals_payed_sql = "(SELECT COUNT(*) FROM $referrals_table reft WHERE reft.user_id = t.id AND reft.status = 'Оплачено') ";
//$month profit_sql = ???;

$criteria->select = array(
'*',
$requests_count_sql . "as requests_count",
$referrals_count_sql . "as referrals_count",
$referrals_payed_sql . "as referrals_payed_count",
$month_profit_sql . "as month_profit",
);

$criteria->compare($requests_count_sql, $this->requests_count);
$criteria->compare($referrals_count_sql, $this->referrals_count);
$criteria->compare($referrals_payed_sql, $this->referrals_payed_count);
$criteria->compare($month_profit_sql, $this->month_profit);

$criteria->compare('t.id', $this->id);
$criteria->compare('t.reg_date', $this->reg_date, true);
$criteria->compare('username', $this->username, true);
$criteria->compare('password', $this->password, true);
$criteria->compare('site', $this->site, true);
$criteria->compare('status', $this->status, true);

return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
'pagination' => array( 'pageSize' => $pageSize ),
'sort' => array(
'defaultOrder' => $defaultOrder,
'attributes' => array(
'id' => array(
'asc' => '`t`.`id` ASC',
'desc' => '`t`.`id` DESC',
),
'email' => array(
'asc' => '`t`.`email` ASC',
'desc' => '`t`.`email` DESC',
),
'requests_count' => array(
'asc' => 'requests_count ASC',
'desc' => 'requests_count DESC',
),
'referrals_count' => array(
'asc' => 'referrals_count ASC',
'desc' => 'referrals_count DESC',
),
'referrals_payed_count' => array(
'asc' => 'referrals_payed_count ASC',
'desc' => 'referrals_payed_count DESC',
),
'money' => array(
'asc' => 'money.profit',
'desc' => 'money.profit DESC',
),
'fullProfit' => array(
'asc' => 'money.full_profit',
'desc' => 'money.full_profit DESC',
),
'*',
),
)
));
}

Например. У меня есть отношение в моей модели пользователя:

public function relations()
{
return array(
'clients' => array( self::HAS_MANY, 'Referrals', 'user_id'),

Скажем так month_profit будет равен: количество пользователей clients за последние 30 дней * 150. Мне нужно как-то передать эти данные search() и создать CDbCriteria для сортировки пользователей по month_profit, Это даже реально? 🙂 Должен ли я создать другую функцию, чтобы вычислить все, а затем перейти к search()? До сих пор все мои попытки заканчивались неудачей.

3

Решение

Я полагаю, вам нужно что-то вроде следующего, основываясь на этом руководстве http://www.yiiframework.com/wiki/319/searching-and-sorting-by-count-of-related-items-in-cgridview

Сначала сделайте статистический запрос в отношениях на вашей модели пользователя:

'month_profit' => array(self::STAT, 'User', 'id', 'select'=>'COUNT(*) * 150', 'condition'=>'DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= reg_date'),

Затем пометьте атрибут «month_profit» как безопасный в сценарии поиска в правилах.

public function rules() {
return array(

...

array('username, ... , month_profit', 'safe', 'on' => 'search' ),
);
}

Добавьте все это, где каждый нужен в методе User search ():

$user_table = User::model()->tableName();
$month_profit_sql = "(SELECT COUNT(*) FROM user_table WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= reg_date)";

$criteria->select = array(
'*',
$requests_count_sql . "as requests_count",
$referrals_count_sql . "as referrals_count",
$referrals_payed_sql . "as referrals_payed_count",
$month_profit_sql . "as month_profit",
);

...
$criteria->compare($month_profit_sql, $this->month_profit);

return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
'pagination' => array( 'pageSize' => $pageSize ),
'sort' => array(
'defaultOrder' => $defaultOrder,
'attributes' => array(
'id' => array(
'asc' => '`t`.`id` ASC',
'desc' => '`t`.`id` DESC',
),

...

'month_profit' => array(
'asc' => 'month_profit ASC',
'desc' => 'month_profit DESC',
),

'*',
),
)
));

Наконец, измените вашу сетку:

$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'username',

... ,

'month_profit',
array(
'class'=>'CButtonColumn',
),
),
));

Пожалуйста, дайте мне знать, если это сработало.

РЕДАКТИРОВАТЬ
Если это не сработает, попробуйте без статистического запроса.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]