Cakephp 4.x Conditional $rules->isUnique(['email'] работает только с операциями добавления, а не обновления в buildRules

Попытка реализовать логику условной проверки через buildRules. Логика работает при добавлении, но не при обновлении. Я убедился, что правило возвращает true при обновлении и false при добавлении.

Моя модель стола:

namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Rule\IsUnique;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Event\EventInterface;
use ArrayObject;
use Cake\Error\Debugger;
use Cake\Log\Log;
   public function buildRules(RulesChecker $rules): RulesChecker {     
      $rules->add(function ($entity, $options) use($rules) {
         if ($entity->send_email == 'Y') {
            $rule = $rules->isUnique(['email'], 'The email should be unique for MailChimp'); // Works on add only
            return $rule($entity, $options); // Works on add only
         }
         return true;
      }, 'email');
      return $rules;
   }

я пытался

    public function buildRules(RulesChecker $rules): RulesChecker {
          $rules->add(function ($entity, $options) use($rules) {
             if ($entity->send_email == 'Y') {
                $rules->add($rules->isUnique(
                      ['email'], 'Error Message'
                ));
                return $rules;
             }
             return true;
          }, 'email');
          return $rules;
       }

Который при редактировании отображает флэш-сообщение от контроллера. Но при добавлении не отображается сообщение и остается в форме редактирования.

Будем очень признательны за любые предложения или образовательные указатели. Извините, если это не правильно отформатировано

Обновлять: | Имя | Тип | сортировка | | ----------------| ----------------- | -------------------- | | электронная почта | varchar(255) | utf8_general_ci | | отправить_электронная почта | varchar(1) | utf8_general_ci |

Цель состоит в том, чтобы не допустить обновления или добавления в базу данных, если электронная почта уже существует и флаг send_email == "Y" Электронная почта может существовать несколько раз, если флаг send_email == "N" Возврат true генерируется из уникальной проверки

    $rule = $rules->isUnique(['email'], 'The email should be unique for MailChimp'); // Works on add only
    Debugger::dump($rule($entity, $options));
    return $rule($entity, $options);

🤔 А знаете ли вы, что...
Фреймворк CakePHP популярен благодаря своей конвенции над конфигурацией (CoC) и шаблонизации (DRY).


511
1

Ответ:

Решено

Если я правильно вас понимаю, то похоже, что простое включение поля send_email в правило должно делать то, что вы ищете, то есть:

if ($entity->send_email === 'Y') {
    $rule = $rules->isUnique(
        ['email', 'send_email'],
        'The email should be unique for MailChimp'
    );

    return $rule($entity, $options);
}

return true;

Таким образом, условия поиска будут такими:

WHERE email = 'unchanged@email' AND send_email = 'Y' ...

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