Работа со связанной моделью в CakePHP - PullRequest
1 голос
/ 12 февраля 2012

Это довольно простой вопрос о CakePHP, но, поскольку мои знания об этой среде довольно устарели, это заставляет меня терять много времени.

У меня есть отношение ManyToMany между Guest и Present. Всякий раз, когда новый гость создается и связывается с подарком, я хотел бы пометить подарок как принятый. Если подарок уже занят, должна появиться какая-то ошибка. Причина, по которой я не просто объявляю, что гость имеет много подарков, заключается в том, что в будущем все может измениться, и более одного гостя могут связываться с настоящим, поэтому я предпочитаю избегать миграции Db.

Мое Guest::add() действие выглядит следующим образом. Он вызывается с POST с данными нового гостя и идентификатором существующего подарка.

public function add() {
    if ($this->request->is('post')) {
        $id = $this->request->data['Present']['id'];
        $this->Guest->create();
        $present = $this->Guest->Present->findById($id);
        if ($present['Present']['taken']) {
            throw new ForbiddenException();
        }

        if ($this->Guest->save($this->request->data)) {
            if ($this->Guest->Present->saveField('taken', true)) {
                 // Give the guest a uuid and proceed with a welcome message
                 $this->Guest->read();
                 $this->set('uuid', $this->Guest->data['Guest']['uuid']);
            }
        }

    }
    else {
        throw new ForbiddenException();
    }
}

Что происходит, так это то, что новый гость создается (правильно) и связывается с данным подарком (правильно), но когда я сохраняю поле taken, создается новый подарок вместо изменения данного.

Как правильно обновить текущий подарок?

Если это поможет, я использую CakePHP 2.0

Ответы [ 2 ]

2 голосов
/ 12 февраля 2012

Для получения данных модели по первичному ключу лучше использовать дополнительно метод read:

    $present = $this->Guest->Present->read(null, $id);

Метод read устанавливает атрибут модели id, чтобы дальнейшие вызовы других методов влияли ната же запись данных, а не создание новой.Это должно решить вашу проблему.

Обратные вызовы модели , как правило, лучше подходят для таких ситуаций.Вы можете добавить обратный вызов beforeSave в класс Guest для проверки, если подарок уже занят, и запретить создание, если оно есть.Таким образом, логику модели оставляют на уровне модели, и вам не нужно выполнять никакой дополнительной работы, например, если ограничение необходимо применять также, когда существующие Guest сохраняются или создаются из других контроллеров или действий.

1 голос
/ 13 февраля 2012

Похоже, что идентификатор модели, которую вы пытаетесь сохранить, теряет область видимости. Вы должны быть в состоянии решить вашу проблему, обновив код:

...
if ($this->Guest->save($this->request->data)) {
    $this->Guest->Present->id = $id;
    if ($this->Guest->Present->saveField('taken', true)) {
...
...