CakePHP обновить значение поля на основе другого значения в той же строке? - PullRequest
0 голосов
/ 13 июля 2010

Я пытался выяснить, как это сделать, и кажется, что это не то, что многие люди пытаются сделать в CakePHP, или я просто совершенно неправильно понимаю документацию. Я использую следующий запрос ниже, чтобы получить значение поля, так что я получаю значение, где «findbycreated» равен 0 ... эта часть отлично работает

$unregisteredemail = $this->Testmodel->findBycreated('0');
$emailaddress = $unregisteredemail['Testmodel']['emailaddress'] ;
$emailpassword = $unregisteredemail['Testmodel']['password'] ;

Но теперь, после того, как я что-то сделаю с этими данными, которые я получу, я хочу пометить поле в той же строке в той же модели / таблице значением '1', чтобы указать, что действие выполнено место (например, адрес электронной почты был успешно создан) ... Я просто не могу понять, как это сделать в cakephp, несмотря на мои усилия по просмотру документации и поиску, это должно быть довольно просто, я испытываю искушение, в с этой точки зрения, просто использовать обычный запрос mysql в качестве простого запроса .. в основном это запрос (прошу прощения за мой синтаксис, так как я не использовал прямые запросы mysql некоторое время) = '1' где 'адрес электронной почты' = $ адрес электронной почты "

Или я мог бы использовать идентификатор строки, если это необходимо, поскольку cakephp, похоже, предпочитает это, но все еще не может понять, как это сделать. Это моя попытка ниже, которая не работает:

// update database to show that email address has been created
$this->Testmodel->read('emailaddress', $this->Testmodel->findBycreated('0'))
$this->Testmodel->id = 1;
$this->Testmodel->set(array(
            'created' => '1'
            ));

 $this->Testmodel->save();

Ответы [ 5 ]

3 голосов
/ 13 июля 2010

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

В модели CakePHP абстрагировал строки базы данных в массив в соответствии с его реализацией ORM . Это дает нам удобный способ манипулирования данными и их изменения в архитектуре MVC.

Когда вы говорите:

$this->Testmodel->set(array(
            'created' => '1'
            ));

Вы имеете дело непосредственно с моделью, но данные на самом деле хранятся в виде массива в переменной класса с именем $ data. Чтобы получить доступ к этим данным и манипулировать ими, вы должны вместо этого сказать:

$this->data['Testmodel']['created'] => '1';

Причиной указания имени модели в качестве первого индекса является то, что там, где были найдены связанные таблицы, к ним можно получить доступ таким же образом, например, вы можете иметь:

Array([Testmodel] => Array ([id] => 1,
                            [created] => [1],
                            ...
                           )
      [Relatedmodel] => Array ([id] => 1,
                               [data] => asd,
                            ...
                           )
     )

... и так далее. Очень удобно.

Теперь, когда вы используете $this->MyModelName->save() без параметров, он использует $ this-> data по умолчанию и использует часть массива данных, соответствующую модели, которую вы используете. вызываем метод сохранения. Вы также можете передать массив данных, отформатированный таким же образом, если по какой-то причине вы не (или не можете) использовать $this->data.

Вы используете метод read () неверно. Первый параметр должен быть пустым, строкой или массивом строк (представляющих имена полей). Второй параметр должен быть идентификатором записи, которую вы хотите прочитать. Вместо этого для параметра 2 вы передаете результат поиска, который будет массивом. Результат, который вы не захватываете, будет пустым.

Я бы написал ваш код как:

$this->data = $this->Testmodel->read('emailaddress',1); 
$this->data['Testmodel']['created'] = 1;
$this->Testmodel->save();

или более кратко:

$this->Testmodel->id = 1;
$this->Testmodel->saveField('created', 1);
3 голосов
/ 13 июля 2010

В этой ситуации я бы позволил Cake разобраться с идентификаторами и сосредоточиться на изменении данных строк и их сохранении в базе данных.

$row = $this->Model->findBycreated(0);
$row['Model']['emailaddress'] = 1;
$this->Model->save($row);

Таким образом, вам не нужно беспокоиться об идентификаторах., так как идентификатор в любом случае будет в вашем наборе данных, просто измените то, что вы хотите, и скажите Cake, чтобы сохранить его.

Редактирование ниндзя, убедитесь, что вы возвращаете полную строку с id из вашего findBycreated() метода.

2 голосов
/ 13 июля 2010

Есть много способов сделать вашу работу. Я предлагаю вам прочитать поваренную книгу о сохранении данных в cakephp . И кроме решения Дэвида, еще один простой способ будет

$this->Testmodel->id = 1;  
$this->Testmodel->saveField('created' =>'1'); 
1 голос
/ 13 июля 2010

Хорошо, я думаю, что наконец нашел решение, я смог заставить это работать:

$this->Test->updateAll(
  array(
    'Test.field' => 'Test.field+100'
  ),
  array(
    'Test.id' => 1
  )
);

Я думаю, что вы должны использовать updateAll, так как все остальное просто создаст новую строку .. в основном CakePHP, по какой-то причине, забыл включить функцию для обновления только одного поля, поэтому вы должны поместить его в массив с помощью updateAll чтобы заставить это работать ...

+100 - это место, куда отправляется обновленная информация, поэтому в этом случае "100" будет тем, к чему обновляется поле.

0 голосов
/ 15 августа 2018

В cakephp 3.x синтаксис кажется другим. Вот что у меня сработало в 3.x:

$this->Tests->updateAll(
    [
        'Tests.field = Tests.field+100'
    ],
    [
        'Tests.id' => 1
    ]
];

Разница в том, что все выражение должно быть в значении первого массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...