2015-06-27 21 views
7

Nhiều câu hỏi về việc xác thực có thể thuộc về nhau, bởi vì họ là tất cả các loại adressing khái niệm xác nhận mới trong CakePHP 3.Khó hiểu Validation vs Rules ứng dụng trong CakePHP3

Tôi đã đọc các chương (1, 2, 3) trong sách dạy nấu ăn nhiều lần nhưng thành thật mà nói tôi không hiểu cách làm đúng cách. Tôi cũng biết hiện tại có issue/discussion at GitHub về Xác thực trong CakePHP3 có thể giải quyết cùng một chủ đề.

Lỗi xác thực được kích hoạt, ví dụ: với patchEntity. Vì vậy, tôi sẽ nghĩ rằng đó là tốt hơn để kiểm tra LUÔN/lỗi hiển thị trước khi thực hiện hành động tiết kiệm:

// 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); 
} 

Tại sao các hướng dẫn nấu ăn không tận dụng $user->errors() trước khi lưu dữ liệu? Theo tôi hiểu nó save không cần phải được gọi nếu có một lỗi xác nhận đã ?! Một cách khác là kết hợp kiểm tra lỗi và lưu hành động:

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.'); 
} 

Bạn đang sử dụng? Tôi có nên sử dụng nó không? Hoặc nếu không, tại sao không?

Tại sao CakePHP hiển thị lỗi xác thực ngay cả khi tôi KHÔNG sử dụng $user->errors() trong bộ điều khiển, như trong tất cả các ví dụ về sách dạy nấu ăn? Tôi nghĩ rằng save sẽ KHÔNG kiểm tra xác thực đối tượng ?!

Ví dụ: isUnique

Theo cookbook "Đảm bảo email độc đáo" là một trường hợp sử dụng cho các quy tắc ứng dụng.

// 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ỗi này chỉ được kích hoạt với save -có trong bộ điều khiển. Nhưng nó cũng có thể kiểm tra tính duy nhất trong quá trình xác nhận. Tại sao tốt hơn KHÔNG nên làm theo cách này?

// 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; 
} 

Nếu tôi có thể thêm ApplicationRule trong quá trình xác thực, tại sao tôi nên sử dụng ApplicationRules?

Làm cách nào để xác định trong ApplicationRule KHI Quy tắc chỉ được áp dụng trong một hành động cụ thể (không phải tất cả lệnh tạo/cập nhật)?

Tôi cũng không nhìn thấy hoặc hiểu lợi ích của hai trạng thái xác thực được tách riêng khi thực thể được điều khiển sau patchEntity -call.

Trong trường hợp tôi tự động thêm một số giá trị vào thực thể, tôi muốn chắc chắn rằng tất cả các giá trị vẫn hợp lệ trước khi lưu chúng vào cơ sở dữ liệu (như trong CakePHP2). Vì vậy, tôi sẽ đoán nó tốt hơn/nessecary để ALWAYSUsing Validation as Application Rules?!

Bạn đang giải quyết vấn đề này nói chung như thế nào? Có các ví dụ khác có sẵn để hiển thị/chứng minh lợi ích và một số trường hợp sử dụng của Validation vs. ApplicationRules không?

Trả lời

6

Tôi nghĩ rằng nguồn chính của sự nhầm lẫn là bạn không biết rằng save() sẽ không lưu một thực thể nếu nó có lỗi.Ví dụ:

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

Lý do nó sẽ trả về false là vì save() đọc $entity->errors() kết quả trước khi tiến hành quá trình tiết kiệm thực tế. Đó là, sau đó, không cần thiết để kiểm tra lỗi bằng tay trước khi gọi save(), giống như các ví dụ trong chương trình hướng dẫn sử dụng.

Ví dụ về tính duy nhất của email rất khó, vì nó là thứ bạn muốn kiểm tra cho cả biểu mẫu người dùng (xác thực được nhắm mục tiêu cho) và trong quy tắc ứng dụng.

Điều quan trọng cần nhớ là Validation, như trong phương thức validation*(), có nghĩa là cung cấp phản hồi cho con người về dữ liệu mà chúng đang cung cấp. Bạn muốn trình bày tất cả các lỗi trong một biểu mẫu (bao gồm các lỗi cho thuộc tính lồng nhau) trước khi quá trình lưu bắt đầu.

Validation hiếm khi xảy ra bên trong giao dịch cơ sở dữ liệu, không có đảm bảo thực tế nào giữa xác thực và lưu email sẽ vẫn là duy nhất. Đây là một trong những quy tắc ứng dụng đang cố gắng giải quyết: Các quy tắc ứng dụng chạy trong cùng một giao dịch như phần còn lại của quá trình lưu, vì vậy bất kỳ kiểm tra nào sẽ có sự đảm bảo nhất quán.

Một quy tắc ứng dụng vấn đề khác giải quyết là chúng có thể làm việc trên dữ liệu đã được đặt trên thực thể, do đó bạn có toàn quyền truy cập trạng thái hiện tại của đối tượng. Điều đó là không thể khi vá một thực thể hoặc khi tạo một thực thể mới, vì bất kỳ dữ liệu được truyền nào đều có khả năng không nhất quán.

+0

Vì vậy, để tránh những điều bất ngờ khi lưu dữ liệu, đó là cách tốt nhất để luôn sử dụng tính hợp lệ cũng như quy tắc ứng dụng? Tôi nghĩ rằng đây sẽ là cách duy nhất để đảm bảo dữ liệu vẫn hợp lệ nếu thực thể được thao tác giữa tạo và lưu thực thể? Bạn có thể đưa ra một số ví dụ cụ thể khi các quy tắc ứng dụng hoàn toàn tốt hơn sau đó xác thực (không có mã, chỉ sử dụng các trường hợp có lợi thế lớn) không? Bởi vì tôi nghĩ rằng với [xác nhận có điều kiện] (http://book.cakephp.org/3.0/en/core-libraries/validation.html#conditional-validation) Tôi có thể làm chủ yếu giống như với các quy tắc ứng dụng –

+0

Có [ví dụ với quy tắc ứng dụng miễn phí] (http://book.cakephp.org/3.0/en/orm/validation.html#validation-vs-application-rules). Tôi cũng có thể làm điều đó với xác nhận có điều kiện 'return $ context ['data'] ['price'] <100 && $ context ['data'] ['shipping_mode'] === 'free'; ' –

+1

Tôi đã đưa ra một ví dụ trong câu trả lời của tôi: Các quy tắc ứng dụng chạy trong một giao dịch, vì vậy chúng là cách duy nhất để đảm bảo dữ liệu sẽ vẫn nhất quán. Đặc biệt cho các quy tắc liên quan đến tính toán. –