ActiveRecord и join

Выполняю поиск в модели Object




$aConditions['join'] = 'LEFT JOIN block_values dt_published ON dt_published.object_id = t.id';

$aConditions['condition'] = 'dt_published.block_id = 3 AND dt_published.val_date > "2010-01-01"';



Потом вывожу на экран id полученного объекта, получаю id записи из таблицы block_values.

Нашел следующее решение:




$aConditions['select'] = 't.*';



Но так писать каждый раз не есть хорошо.

Подскажите, это баг ActiveRecord-а или можно еще как-то решить эту проблему более изящно?

по дефолту для таблицы (к которой применяется критерия и find/findAll()) алиас = "t" если в критерии не указано иное

Не понял, какое отношение это имеет к вопросу.

непосредственное, так как по-моему:

[list=1]

[*]либо запрос выполняется не у модели Object

[*]либо для block_values некорректно указан alias=>‘t’

[/list]

покажите полностью запрос (если есть - используемые скопы), а не только условия

Алиас t используется для модели Object, т.е. для таблицы objects. Для таблицы block_values указан алиас dt_published, как это видно из параметра JOIN.

Поиск происходит так:




$oObject = Object::model()->findAll($aConditions);



Вот запрос, который при этом генерирует CActiveRecord:

SELECT * FROM objects t LEFT JOIN block_values dt_published ON dt_published.object_id = t.id WHERE dt_published.block_id = 3 AND dt_published.val_date > "2010-01-01"

Далее:




echo $oObject->id;



Выводит на экран id записи из таблицы block_values, а не objects.

по логике работы AR он не генерирует алиасы для филдов выбираемых таблиц, если не добавлено ни одного отношения…

т.е. в вашем случае я сделал бы один из пунктов:

[list=1]

[*]relation blockValues (HAS_MANY) в object

[*]добавил


public function defaultScope(){

 return array(

   'select'=>$this->getTableAlias().'.*',

 );

}

либо добавил бы в scopes и в запросе использовал

[/list]

вам выбирать :rolleyes:

Т.е. это все таки баг. По идее при использовании join, AR должна использовать алиас.

Первый способ на прокатывает, т.к. может понадобиться несколько раз вызывать blockValues, и при этом использовать их под разными алиасами.

Спасибо за помощь.

почему же!?

это первое:


with(array(

  'blockValues'=>array(

    'alias' => 'myCustomAlias',

    'condition' => 'x=1',

  )

))

но вы правы, несколько раз не получится использовать (дополнительные withЫ будут мержится, рекурсивно с учетом имени отношения [по патчу, который еще не применен issue и patch, на текущий момент последующий вызов with() мержится используя CMap::mergeArray()] - если вы только руками не будете мержить их… т.е. $model->getDbCriteria()->mergeWith(…,$useAnd=false)), но это избавит от необходимости указывания select=‘t.*’ (+если не секрет, в каком случае вы связываете несколько раз blockValues - опишите задачу, просто интересно)

а второе… что при использовании join - вы сами определяете необходимый набор полей для выборки, если бы это было не так, тогда были бы жалобы: “куда исчезают филды, которые у меня выбираются?”, т.к. у CActiveRecord есть возможность биндить результаты поиска на публично-доступные для записи проперти модели (а не аттрибуты, которые имеет таблица модели) :rolleyes:

Задача не простая, здесь ее описать будет не просто)

Идя взята отсюда - http://misha.design.ru/hobby/progr/engine4.html

Но уже притерпела много изменений.

А насчет join, AR должна корректно определять, какой id к какой записи относится, т.е. учитывать такой случай, когда у таблиц есть поля с одинаковым именем.