отношение cakephp принадлежит

Я использую cakephp 2.1.3, и у меня есть таблица Ingredients и таблица IngredientAliases. Я хочу, чтобы это было в моем индексе страницы в Ingredient, когда я выбираю IngredientAlias. Я хочу видеть IngredientAlias ​​и некоторые поля Ingredients. Но я не знаю, если Мне нужно сделать два запроса к моему контроллеру или только установить id ингридиента_идентификатора, а cakephp автоматически получить данные. Теперь я делаю два запроса в своем контроллере, но я не знаю, лучший ли это способ

$this->set('ingredient', $this->Ingredient->read());            $this->set('ingredient_alias',$this->Ingredient->IngredientAlias->read()); 

Вот мои таблицы:

class Ingredient extends AppModel {
    public $name = 'Ingredient';
    public $useTable = 'ingredients';
    public $belongsTo = 'User';

    public $hasMany = array (
        'IngredientAlias' => array (
            'className'     => 'IngredientAlias',
            'foreignKey'    => 'ingredient_id'
        )
    );
}

class IngredientAlias extends AppModel {
    public $name = 'IngredientAlias';
    public $useTable = 'ingredient_aliases';
    public $belongsTo = array(
        'Ingredient' => array(
            'className'    => 'Ingredient',
            'foreignKey'   => 'ingredient_id'
        )
    );
}

И вот мой IngredientsController (я изменил маршруты, чтобы добавить псевдоним в свои аргументы, и он работает)

public function edit ($alias) {
        $ing = $this->Ingredient->IngredientAlias->find('first', array(
                    'conditions' => array('IngredientAlias.alias' => $alias)));
        $this->Ingredient->IngredientAlias->id= $ing['IngredientAlias']['id'];
        $this->Ingredient->IngredientAlias->set('ingredient_id',$ing['IngredientAlias']['ingredient_id']);
        $this->Ingredient->id= $ing['IngredientAlias']['ingredient_id'];
        if (!$this->Ingredient->IngredientAlias->exists()) {
                throw new NotFoundException ('Nessuna corrispondenza trovata per questo ingrediente');
            }
            if (!$alias) {
                $this->set('flash_element','error');
                $this->Session->setFlash ('Ingrediente non valido');
            }
            $this->Ingredient->recursive = 2;
            $this->set('ingredient', $this->Ingredient->read());
            $this->set('ingredient_alias',$this->Ingredient->IngredientAlias->read());
    }

person Community    schedule 19.06.2012    source источник


Ответы (1)


На основе отношений, которые вы описали, и если у вас есть ключ ingredient_id в таблице ingredient_aliases, если вы вызываете:

$this->Ingredient->find('first', array('conditions' => array('Ingredient.id' => $id)));

Вы получите запись Ingredient, указанную $id, со всеми связанными с ней записями IngredientAlias ​​в структуре массива, подобной следующей:

Array =>
    [Ingredient] => Array
                        [id] => 3
                        [other_data_from_DB] =>
                        .....
    [IngredientAlias] => Array => 
                         [0] => Array =>
                                [id] => 1
                                [ingredient_id] => 3
                                [other_data_from_DB] =>
                                ....
                         [1] => Array =>
                                [id] => 2
                                [ingredient_id] => 3
                                [other_data_from_DB] =>
                                ....
                         [2] => Array =>
                                [id] => 3
                                [ingredient_id] => 3
                                [other_data_from_DB] =>
                                ....

Подструктура массива IngredientAlias ​​индексируется из-за отношения hasMany. Если вы не видите связанные записи IngredientAlias, проверьте рекурсивный свойство:

debug($this->Ingredient->recursive);

Если он равен -1, то будут получены только данные модели ингредиента. Посмотрите, что делают другие рекурсивные значения по ссылке, которую я предоставил.

Если вы хотите пойти другим путем, вам следует пройти через модель IngredientAlias:

$this->IngredientAlias->find('first', array(CONDITIONS));

предоставит указанную в записи CONDITIONS IngredientAlias ​​связанную с ней запись Ingredient. Запись Ingredient будет только одна из-за отношения IngredientAlias belongsTo Ingredient.

person Borislav Sabev    schedule 20.06.2012
comment
Но мне нужен только ингридиент-алиас с этим псевдонимом, я думаю, это подзапрос, потому что мне нужно искать идентификатор ингредиента и после точного псевдонима, потому что я хочу только один ингридиент-алиас (выбранный ингридиент-алиас) - person ; 21.06.2012
comment
Тогда просто пойдите наоборот - найдите IngredientAlias, и вы получите связанную запись Ingredient. ;) Итак, $this-›IngredientAlias-›find('first', array(УСЛОВИЯ)); предоставит то, что вам нужно, когда у вас определены оба отношения. - person Borislav Sabev; 21.06.2012
comment
Это то же самое, но если вы сделаете все в соответствии с соглашениями CakePHP, фреймворк сделает за вас свое волшебство, и вам не придется беспокоиться. Конечно, вы также можете выполнять так называемые специальные соединения, указав условия соединения в ключе 'joins' вызова Model::find(). Вы даже можете написать свой собственный оператор SQL и вызвать его с помощью метода Model::query(), но опять же CakePHP сделает это за вас, если вы будете следовать соглашениям. - person Borislav Sabev; 21.06.2012