Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Yii criteria relations


Автор: nepster 28.6.2013, 00:51
подскажите пожалуйста как работать с релейшинами в Yii

Код
<?php
class CodeModel extends CActiveRecord
{
    public function relations()
    {
        return array(
            'Type'=>array(self::HAS_MANY, 'TypeModel', 'type_id'),
        );
    } 




Код
<?php

class TypeModel extends CActiveRecord
{
    public function relations()
    {
        return array(
            'Code'=>array(self::BELONGS_TO, 'CodeModel', 'type_id'),
        );
    } 



Пытаюсь соединить таблицу коды и типы по type_id 


Criteria
Код
         
            $criteria=new CDbCriteria;
            $criteria->limit  = ProcessingData::load()->limit();
            $criteria->order  = 'date_entry_time DESC';
            $criteria->params    = array('user_id'=>0, 'payment'=>0);
            $criteria->with = array('type'); 



собственно никаких ошибок нет и слияния талиц тоже.


В идеале работающий запрос на чистом SQL выглядит вот так
Код

select code.*,type.type_name,users.login
from code 
left join type on  code.type_id= type.type_id
left join users on  code.user_id= users.user_id;

Автор: Gromdron 28.6.2013, 10:29
А зачем именно критерии ? Почему нельзя через DAO работать ?

Код

$result = Yii::app()->db->createCommand()
->select('code.*,type.type_name,users.login')
->from('code')
->leftJoin()('type', 'code.type_id= type.type_id')
->leftJoin()('users', 'code.user_id= users.user_id')
->queryALL();


Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51ccb3ce6ccc19d336000002#findElement_E7045_51cd3b6a6ccc1997200091b9_0

Автор: nepster 28.6.2013, 15:28
да через это работает хорошо не спорю, но интересно все таки релизация через релейшини и критерию 

Автор: nepster 28.6.2013, 17:06
Код
    public function relations()
    {
        return array(
            // связь между MatrixUsersModel и MatrixModel по matrix_id
            'type'=>array(self::HAS_MANY, 'TypeModel', '', 'on'=>'t.type_id=type.type_id'),
        );
    }


собственно получилось сделать так! 

подскажите пожалуйста, как сделать так, что бы в объект записывались не все данные из таблицы, а только нужные, например мне нужно добавить только поле type_name из талицы type. 


Автор: Gromdron 28.6.2013, 20:37
В http://www.yiiframework.com/doc/api/1.1/CActiveRecord#relations-detail, написано:

Цитата

   Additional options may be specified as name-value pairs in the rest array elements:
   - 'select': string|array, a list of columns to be selected. Defaults to '*', meaning all columns. Column names should be disambiguated if they appear in an expression (e.g. COUNT(relationName.name) AS name_count).
   


Соответственно попробуйте так:

Код

public function relations() {
  return array(
     'type'=>array(
       self::HAS_MANY,
       'TypeModel',
       '',
       'select' => 'type_name',
       'on'=>'t.type_id=type.type_id'),
  );
}



Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51ccb3ce6ccc19d336000002#findElement_E7045_51cdc9f76ccc195f3700ae99_0

Автор: nepster 28.6.2013, 23:59
ольшое спасибо все заработало, осталось только 1 проблема. 


Код

    public function relations()
    {
        return array(
            // связь между MatrixUsers и Matrix по matrix_id
            'type'=>array(self::HAS_MANY, 'TypeModel', '', 'select' => 'type_id,views,levels', 'on'=>'t.type_id=type.type_id'),
        );
    }



Код

            $criteria=new CDbCriteria;
            $criteria->limit  = ProcessingData::load()->limit();
            $criteria->order  = 't.date_entry_time DESC';
            $criteria->condition = 't.user_id=:user_id OR t.pt=:payment';
            $criteria->params = array('user_id'=>0, 'pt'=>0);
            $criteria->with   = array('type'=>array('condition'=>'status!=0'));



Связи соответствуют 1 к 1. Тоесть к примеру для таблицы кодов (где есть номер типа), нужно достать имя типа из таблицы типов (номер типа это ПК)
Тоесть если есть код где, номер типа 5, то естественно номеру 5 соотвествует только 1 строка. 

ияходя из документыции нужно использовать:
Код

HAS_ONE: это частный случай HAS_MANY, где А может иметь максимум одно В (например, у User есть только один Profile);


но при этом вылазит ошибка. 

И слелудующий момент, к примеру мне нужно достать все записи из таблицы кодов, где статус типа не равен 0. 

я прописал вот так
Код

 $criteria->with   = array('type'=>array('condition'=>'status!=0'));



что эже получилось, по кодам достались все записи, а по типам сработала выборка. 


тоесть если использовать чистый SQL будет так:

Код

 select code.*, type.type_name FROM code LEFT JOIN type ON code.type_id=type.type_id WHERE code.user_id=0 OR code.pt = 0 AND type.status!=0


а вот почему 'type'=>array('condition'=>'status!=0') применяется только к прикрепленной таблице ?

Добавлено через 6 минут и 46 секунд
Проблему решил, не внимательно писал код.


работает с self::HAS_ONE

Автор: Gromdron 29.6.2013, 11:28
Насчет has_many гляну дома, а насчет таблицы - все правильно, вы же ставите условие только для подключенной при помощи with модели, а не для результата.

Вы же ставите в SQL условие:
code.user_id=0 OR code.pt = 0 AND type.status!=0

А при работе указываете только:
code.user_id=0 OR code.pt = 0

Отредактируйте $criteria->condition

P.s. Используйте в соответствии с документацией полное именование столбца: т.е. Имя_таблицы.имя_столбца

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51ccb3ce6ccc19d336000002#findElement_E7045_51ce9aaf6ccc19412c002d7d_0

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)