Модуль CakePHP принадлежит к комплексу, но не все модули имеют комплекс?

У меня есть «сложная» модель, в которой есть много единиц. Мои ассоциации моделей верны, все работает, просто у меня возникли проблемы с правильной работой другой модели/ассоциации, и это заставило меня задуматься, нужно ли мне настраивать эту модель по-другому.

Видите ли, не ВСЯ Единица будет иметь связанный с ней Комплекс. Некоторые Единицы — это дома, некоторые Единицы — гостиничные номера, а некоторые Единицы — это просто компании по аренде.

Поскольку комплексы имеют много единиц, у меня возникает искушение оставить это в покое, но мне интересно, не следует ли мне переопределить отношение как принадлежность комплекса к единице. Я пытаюсь не повторяться в своей базе данных, добавляя несколько экземпляров одного и того же комплекса.

Вот моя текущая модель устройства:

class Unit extends AppModel {
public $name='Unit';

public $belongsTo=array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user'
),
'Complex'=>array(
'className'=>'Complex',
'foreignKey'=>'complex_id'
)
);

public $hasOne=array(
    'Location'=>array(
        'className'=>'Location',
        'foreignKey'=>'location_id'
        )
    );

}

и вот моя текущая сложная модель:

class Complex extends AppModel {
    public $name='Complex';
    public $hasMany=array('Unit');
    public $hasOne=array(
        'Location'=>array(
            'className'=>'Location',
            'foreignKey'=>'location_id'
            )
        );






}

Между прочим, «Местоположение» — это модель, с которой у меня возникли проблемы (часть «Местоположение» моего массива в настоящее время возвращает пустое значение, когда я вызываю информацию о своей единице/комплексе в своем представлении, поэтому мне нужно правильно установить связь).
Если объект представляет собой квартиру с комплексом, я хочу, чтобы он возвращал местоположение комплекса. Если это дом, гостиница или компания по аренде, я хочу, чтобы она возвращала местоположение объекта. Мне нужно сделать несколько таких ассоциаций (изображения, местоположение и т. д.), поэтому я хочу сразу все прояснить.

Верны ли мои текущие отношения между единицей и комплексом или мне нужно определить все по-другому?

ОБНОВЛЕНИЕ Вот моя логика контроллера:

$this->paginate['Unit']=array(
        'limit'=>9,
        'order' => 'RAND()',
        'contain'=>array(
                'User'=>array(
                    'email'),
                'Complex'=>array(
                    'id','complex_name', 'realname', 'photo1','photo2','photo3','photo4','photo5'),
                'Location'=>array(
                    'complex_id','address', 'city','state','zip','area_code','exchange','sln','lat','lon','website')
                ),
        'conditions'=>array(
                'Unit.type'=>array('condo', 'rentalco'),
                'Unit.active'=>1)   
    );
$data = $this->paginate('Unit');
$this->set('allcondos', $data);


}

И вы можете увидеть результат, который я получаю здесь:

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

 public function index() {
    $this->Complex->Behaviors->attach('Containable');
    $this->Complex->contain();
    $c=$this->Complex->find('all');
    $this->set('complexes', $c);
    }

ОБНОВЛЕНИЕ Теперь у меня все работает, для всех, кто сталкивается с этой проблемой. Пришлось сменить Location на корень и сделать Complex ownTo Location. Вот мои обновленные модели:

class Location extends AppModel {
    public $name='Location';
    public $hasMany=array('Complex', 'Unit');
    var $belongsTo=array(


    'Restaurant'=>array (
        'className'=>'Restaurant',
        'foreignKey'=>'restaurant_id'
        )
    );


}

class Complex extends AppModel {
    public $name='Complex';
    public $hasMany=array('Unit');
    public $hasOne=array('Image');
    public $belongsTo=array(
        'Location'=>array(
            'className'=>'Location',
            'foreignKey'=>'location_id'
            )
    );






}


class Unit extends AppModel {
public $name='Unit';

public $belongsTo=array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user'
),
'Complex'=>array(
'className'=>'Complex',
'foreignKey'=>'complex_id'
),

'Location'=>array (
        'className'=>'Location',
        'foreignKey'=>'location_id'
        ),
);

public $hasOne=array('Image');

}

Большое спасибо Wylie за помощь, это было круто!


person huzzah    schedule 30.01.2012    source источник
comment
Где в вашем приложении находится вызов find(), оставляющий Location пустым?   -  person Wylie    schedule 30.01.2012
comment
$this-›paginate['Unit']=array( 'limit'=›9, 'order' =› 'RAND()', 'contain'=›array( 'User'=›array( 'email'), 'Complex'=›array( 'id','complex_name', 'настоящее имя', 'photo1','photo2','photo3','photo4','photo5'), 'Location'=›array( 'complex_id' ,'адрес', 'город','штат','zip','код_города','биржа','sln','широта','долгота','веб-сайт') ), 'условия'=›массив( 'Unit.type'=›array('condo', 'rentalco'), 'Unit.active'=›1) ); $data = $this-›paginate('Unit'); $this-›set('allcondos', $data);   -  person huzzah    schedule 30.01.2012
comment
Все ли эти модели имеют ContainableBehavior? Можете ли вы отредактировать ОП и опубликовать результат находки?   -  person Wylie    schedule 31.01.2012
comment
Я отредактировал OP и разместил ссылку на результат отладки в представлении.   -  person huzzah    schedule 31.01.2012


Ответы (1)


http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html?содержащие-болееглубокие-ассоциации#содержащие-болееглубокие-ассоциации

When using ‘fields’ and ‘contain’ options - be careful to include all foreign keys that your query directly or indirectly requires. Please also note that because Containable must to be attached to all models used in containment, you may consider attaching it to your AppModel.

Вы можете сделать это в своей AppModel следующим образом: public $actsAs = array('Containable'); Вам не нужно использовать Contain, когда вы этого не хотите, поэтому он не должен мешать.

Когда модель A имеет модель B, вы используете внешний ключ в модели B. Таким образом, ваш внешний ключ в Location должен быть complex_id. Хотя так быть не должно, ведь не у всех юнитов есть комплекс.

Мне кажется, вы должны сделать Location «корневым». Таким образом, комплекс принадлежит местоположению, а единица принадлежит комплексу и местоположению. Затем Location hasOne/Many complex и т. д. Либо так, либо просто поместите столбцы адресов в таблицы Unit/Complex.

person Wylie    schedule 30.01.2012
comment
Хорошо, после того, как я изменил свою ассоциацию и повозился, я заставил ее работать, публикую то, что я сделал, в OP. Спасибо за помощь! - person huzzah; 31.01.2012