2015-06-27 16 views
7

più domande su di convalida, che possono appartenere insieme, perché sono tutti i tipi di indirizzamento del nuovo concetto di validazione in CakePHP 3.Confondere convalida vs Regole di applicazione in CakePHP3

Ho letto i capitoli (1, 2, 3) nel libro di cucina più volte, ma sinceramente non capisco come farlo nel modo giusto. So anche che attualmente c'è un issue/discussion at GitHub sulla convalida in CakePHP3 che potrebbe affrontare lo stesso argomento.

Gli errori di convalida vengono attivati ​​ad es. con patchEntity. Così penserei che è meglio controllare SEMPRE errori/visualizzare prima di fare l'azione salvare:

// src/Controller/UsersController.php 
public function add() { 
    $user = $this->Users->newEntity(); 
    if ($this->request->is('post')) { 
    $user = $this->Users->patchEntity($user, $this->request->data, ['validate' => 'default']); 
    if ($user->errors()) { 
     $this->Flash->error('There was a Entity validation error.'); 
    } else { 
     // Optional: Manipulate Entity here, e.g. add some automatic values 
     // Be aware: Entity content will not be validated again by default 
     if ($this->Users->save($user)) { 
     $this->Flash->succeed('Saved successfully.'); 
     return $this->redirect(['controller' => 'Users', 'action' => 'index']); 
     } else { 
     $this->Flash->error('Not saved - ApplicationRule validation error.'); 
     } 
    } 
    } 
    $this->set('user', $user); 
} 

Perché i tutorial libro di cucina non fanno uso di $user->errors() prima di salvare i dati? Per quanto ho capito, non è necessario chiamare save se c'è già stato un errore di convalida ?! Un altro modo sarebbe quello di combinare il controllo degli errori e salvare l'azione:

if (!$user->errors() && $this->Users->save($user)) { 
    $this->Flash->succeed('Saved successfully.'); 
    return $this->redirect(['controller' => 'Users', 'action' => 'index']); 
} else { 
    $this->Flash->error('There was a validation OR ApplicationRule error.'); 
} 

Stai usando questo? Dovrei usarlo? O se no, perché no?

Perché CakePHP mostra gli errori di convalida anche se NON utilizzo $user->errors() nel controller, come in tutti gli esempi di libri di cucina? Ho pensato che save NON verificherà la validazione dell'entità ?!

Esempio: isUnique

Secondo il cookbook "Assicurare email unicità" è un caso d'uso per le regole di applicazione.

// src/Model/Table/UsersTable.php 
namespace App\Model\Table; 
use Cake\ORM\Table; 
use Cake\ORM\RulesChecker; 
use Cake\ORM\Rule\IsUnique; 
// Application Rules 
public function buildRules(RulesChecker $rules) { 
    $rules->add($rules->isUnique(['email'], 'This email is already in use')); 
    return $rules; 
} 

L'errore dovrebbe essere attivato solo con un save -call nel controller. Ma è anche possibile verificare l'unicità nella convalida. Perché è meglio non farlo in questo modo?

// src/Model/Table/UserTable.php 
namespace App\Model\Table; 
use Cake\ORM\Table; 
use Cake\Validation\Validator; 
public function validationDefault(Validator $validator) { 
    $validator 
    ->add('email', [ 
     'unique' => [ 
     'rule' => 'validateUnique', 
     'provider' => 'table', 
     'message' => 'This email is already in use' 
     ], 
     ]) 
    return $validator; 
} 

Se posso aggiungere l'ApplicationRule nella validazione, perché sarebbe/dovrebbe utilizzare ApplicationRules a tutti?

Come posso definire in ApplicationRule QUANDO la regola deve essere applicata solo in un'azione specifica (non tutte le chiamate di creazione/aggiornamento)?

Inoltre, non vedo né comprendo il vantaggio dei due stati di convalida separati quando l'entità viene manipolata dopo la chiamata patchEntity.

Nel caso aggiungo alcuni valori automaticamente all'entità, voglio essere sicuro che i valori siano tutti ancora validi prima di salvarli nel database (come in CakePHP2). Quindi direi che è meglio/nessecary a SEMPREUsing Validation as Application Rules?!

Come ti stai comportando in generale? Ci sono altri esempi disponibili per mostrare/dimostrare il beneficio e alcuni casi d'uso di Validation vs. ApplicationRules?

risposta

6

Penso che la vostra principale fonte di confusione sia che non si sa che save() non salverà un'entità se contiene già degli errori.Per esempio:

$entity = $users->newEntity(['email' => 'not an email']); 
$users->save($entity); // Returns false 

Il motivo tornerà falso è perché save() legge il risultato $entity->errors() prima di procedere con il processo di salvataggio vero e proprio. Quindi, non è necessario verificare manualmente gli errori prima di chiamare save(), proprio come gli esempi nel manuale mostrano.

L'esempio di univocità della posta elettronica è un po 'complicato, perché è qualcosa che si desidera controllare sia per i moduli rivolti all'utente (a cosa è destinata la convalida) che nelle regole dell'applicazione.

È importante ricordare che lo Validation, come nei metodi validation*(), è pensato per fornire un feedback agli utenti sui dati che stanno fornendo. Si desidera presentare tutti gli errori in un modulo (inclusi gli errori per le proprietà nidificate) prima dell'avvio del processo di salvataggio.

Dal momento che lo Validation si verifica raramente in una transazione di database, non esiste alcuna garanzia effettiva che tra la convalida e il salvataggio dell'email sia ancora univoco. Questa è una delle cose che le regole applicative stanno tentando di risolvere: le regole dell'applicazione vengono eseguite nella stessa transazione del resto del processo di salvataggio, quindi qualsiasi controllo su donde avrà una garanzia di coerenza.

Un'altra regola di applicazione del problema risolta è che possono lavorare su dati che sono già stati impostati sull'entità, quindi si ha pieno accesso allo stato corrente di un oggetto. Ciò non è possibile durante l'applicazione di patch a un'entità o quando ne viene creata una nuova, poiché qualsiasi dato passato è potenzialmente incoerente.

+0

Per evitare sorprese durante il salvataggio dei dati, è il modo migliore di utilizzare sempre la convalida anche come regole di applicazione? Penso che questo sarebbe l'unico modo per assicurarsi che i dati siano ancora validi se l'entità viene manipolata tra la creazione e il salvataggio dell'entità? Puoi dare alcuni esempi concreti quando le regole dell'applicazione sono assolutamente migliori della convalida (nessun codice, solo casi d'uso dove c'è un grande vantaggio)? Poiché penso con [validazione condizionale] (http://book.cakephp.org/3.0/en/core-libraries/validation.html#conditional-validation), posso fare la stessa cosa delle regole applicative –

+0

C'è l'esempio [ con la spedizione gratuita come regola dell'applicazione] (http://book.cakephp.org/3.0/en/orm/validation.html#validation-vs-application-rules). Potrei anche farlo con una convalida condizionale 'return $ context ['data'] ['price'] <100 && $ context ['data'] ['shipping_mode'] === 'free';' –

+1

Ho già dato un esempio nella mia risposta: le regole dell'applicazione vengono eseguite in una transazione, quindi sono l'unico modo per garantire che i dati rimangano coerenti. Specialmente per le regole che implicano calcoli. –

Problemi correlati