Расширенный поиск с параметрами

Всем привет.

Исходные условия: есть таблица с автомастерскими.

Как сделать поиск: если я хочу чтобы автомастерские выводились аналогично как в index, т.е. кучей но отсортированные и удовлетворяющие дополнительным условиям( средняя цена ремонта не больше чем, расстояние от центра не больше чем). Среднюю цену и расстояние считаю отдельно, т.е. они не табличные.

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

В идеале необходимо добавить форму вверху index view с двумя текстбоксами: цена и расстояние + кнопка по нажатию на которую вывод фильтруется.

Вот и сделайте, как должно быть в идеале :)

Создайте форму (возможно, стоит оформить её в виде виджета). При нажатии на submit данные отправятся контроллеру/экшену, отвечающему за поиск/вывод_мастерских, где достаточно будет посмотреть в массив POST/GET и воспользоваться привычным CDbCriteria (см. методы compare, addSearchCondition и др.).

А как заставить CGridView вывести в поле html?

Т.е. вместо численного значения - картинку.

Определил функцию, которая показывает повторяющимися звездочками, а количество звезд зависит от входного числа. Пытаюсь сделать так:


'stars',

       array(

            'name'=>'stars',

            'type'=>'html',

            'value'=>$model->starShow($model->stars),

        ),



На функцию показа картинки не реагирует.


'value'=>'$data->starShow($data->stars)'

именно $data, не $model

Ух ты. Спасибо. А почему нельзя использовать $model? Не спрашивал бы, если бы $model->stars - были недоступны.

Смотрите метод renderTableRow(). Там в evaluateExpression() для строки передается переменная не "model", а "data". Это можно сравнить с передачей переменных в шаблон, в котором они будут доступны под заданными именами.

Спасибо. Теперь другой вопрос: в модели есть функция, которая считает среднюю цену. Вывести ее не составляет труда, а можно как-нибудь сортировать по ней?

Я не знаю, как вы считаете среднюю цену, но обычно это делается с помощью SQL комбинацией GROUP BY и агрегатной функции AVG. Всё это можно прописать в CDbCriteria, включая и сортировку.

Возможно, стоит посмотреть статистические отношения (если средняя цена считается на основе данных связанной таблицы).

P.S. Не задавайте три абсолютно разных вопроса в одном топике. Не жалейте базу форума и создайте отдельную тему. Возможно, кто-то столкнется с похожей проблемой, и тогда ему легче будет ориентироваться в результатах поиска :)




    public function averagePriceShow()

	{

        $details=$this->details;

        foreach($details as $detail)

        {

            $total+=$detail->count;

            $totalprice+=$detail->count*$detail->price;

        }

        if($total!=0)

            return round($totalprice/$total);

        return false;

	}



Такая вот смешная функция для подсчета. Я ее вывел в таблицу, а по нему не сортирует.

И правильно делает :lol:

Если я правильно понимаю, то это таблица деталей для мастерских, где есть поля (номер_детали, номер_мастерской, количество, цена)? Считать для каждой мастерской в таком цикле среднюю цену на детали очень накладно и, как видно, это не позволяет сортировать по полю, которого в таблице не существует (ведь сортировка происходит в базе данных, а не в php скирпте, а если еще есть и разбиение на страницы, тогда совсем плохо).

Для ускорения можно либо немного денормализовать базу, добавив поле со средней ценой (если нужно действительно часто его извлекать), и периодически обновлять для каждой мастерской, либо при запросе на получение мастерских использовать JOIN + GROUP BY + AVG.

Такого в CGridView я не делал, так что точной реализации не подскажу :)

Все это понятно, спасибо. :)

Задам вопрос по другому: есть куча автомастерских и среди них необходимо найти саму близкую от "запроса ( например от центра города). В этом случае, думаю мне проще по координатам просчитать расстояние между объектами, но не хранить всю эту кашу в базе: объектов и мастерских может быть сколько угодно много.

В модели я описал функцию, которая рассчитывает расстояние от точки а, до объекта модели. Как в таком случае сделать выборку? Создал форму, обрабатываю ее с помощью actionSearch




	public function actionSearch()

	{

        $model=new AutoShop;

        $model->attributes=$_POST['autoshop'];

		$this->render('search',array(

			'model'=>$model,

		));

	}



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




//пример условия

if distanceFind($coordianateAutoShop, $coordinatePlace)< $maxdistance then выводим //$maxdistance - расстояние переданное через форму



Подскажите, пожалуйста, как правильно все это заставить работать. ;)