模型中的 Laravel 5 验证
Posted
技术标签:
【中文标题】模型中的 Laravel 5 验证【英文标题】:Laravel 5 validation in model 【发布时间】:2016-09-11 09:55:45 【问题描述】:我有这样的模型
class test extends Model
public $rules = [
'title' => 'required',
'name' => 'required',
];
protected $fillable = ['title','name'];
还有这样的控制器
public function store(Request $request)
$test=new test; /// create model object
$validator = Validator::make($request->all(), [
$test->rules
]);
if ($validator->fails())
return view('test')->withErrors($validator)
test::create($request->all());
验证显示这样的错误
0 字段是必需的。
我想展示这个
名称字段是必需的。 标题字段是必需的。
【问题讨论】:
【参考方案1】:我解决了
public function store(Request $request)
$test=new test; /// create model object
$validator = Validator::make($request->all(),$test->rules);
if ($validator->fails())
return view('test')->withErrors($validator)
test::create($request->all());
【讨论】:
如果我想让这个通用(如 API),以便可以从任何视图调用它怎么办。我如何将它传递给同一个视图(不知道)。 @VeerShrivastav 也许你可以给自己写一个帮助类?【参考方案2】:你做错了。 rules
数组应该在您的控制器中,或者更好的是在 Form Request 中。
让我告诉你一个更好的方法:
使用php artisan make:request TestRequest
创建一个新的表单请求文件。
例如TestRequest
类:
namespace App\Http\Requests;
use App\Http\Requests\Request;
class TestRequest extends Request
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
return true;
/**
* Get the validation messages.
*
* @return array
*/
public function messages()
return [
'title.required' => 'A title is required.',
'name.required' => 'The name field is required'
];
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
return [
'title' => 'required',
'name' => 'required',
];
将 request 对象注入到您的控制器方法中。
public function store(TestRequest $request)
// You don't need any validation, this is already done
test::create($request->all());
【讨论】:
为什么将规则与模型一起存储不好?为什么要创建一个带有验证登录请求的额外对象? 我来自 Ruby on Rails 背景,使用 Laravel 已经有几年了,个人而言,我更喜欢在模型级别进行验证的方法,主要原因有两个:1. 模型可以更改从用户输入以外的许多地方,维护数据的完整性不仅适用于前端用户,还适用于每个人,包括项目中的所有开发人员。 2. 自定义请求和验证器仅适用于您从控制器获得的属性,它们不会验证模型的所有属性,例如,如果有效购买 2 件商品会使库存变为 -1。 我也很想知道为什么 Laravel 会这样做。虽然我认为这个答案总的来说很好,但我认为这种方式“更好” - “更好”是主观的 这里用户想要将规则放入模型而不是控制器或表单请求中。因为大多数情况下,我们按照框架的建议将规则写入模型中。 我知道这是旧的,但今天仍然适用。不得不说,这个答案从根本上是错误的。在模型上存储规则的方法并没有“更糟”,更不用说“错误的方式”了。 OOP 是关于重用的,如果您在各处重新定义规则,那么您的代码就会出现根本性问题。只需一点点代码,您就可以确保在整个应用程序中都遵循您的规则,无论入口点如何(包括修补程序)。提供单一事实来源总是优于整个应用程序中的大量重新定义。【参考方案3】:您还可以查看模型中的验证并抛出 ValidationException,该异常将在您的控制器中照常处理(使用错误包等)。例如:
abstract class BaseModel extends Model implements ModelInterface
protected $validationRules = [];
/**
* Validate model against rules
* @param array $rules optional array of validation rules. If not passed will validate against object's current values
* @throws ValidationException if validation fails. Used for displaying errors in view
*/
public function validate($rules=[])
if (empty($rules))
$rules = $this->toArray();
$validator = \Validator::make($rules,$this->validationRules);
if ($validator->fails())
throw new ValidationException($validator);
/**
* Attempt to validate input, if successful fill this object
* @param array $inputArray associative array of values for this object to validate against and fill this object
* @throws ValidationException if validation fails. Used for displaying errors in view
*/
public function validateAndFill($inputArray)
// must validate input before injecting into model
$this->validate($inputArray);
$this->fill($inputArray);
然后在我的控制器中:
public function store(Request $request)
$person = $this->personService->create($request->input());
return redirect()->route('people.index', $person)->with('status', $person->first_name.' has been saved');
终于在我的基础服务类中
abstract class BaseResourceService
protected $dataService;
protected $modelClassName;
/**
* Create a resource
* @param array $inputArray of key value pairs of this object to create
* @returns $object
*/
public function create($inputArray)
try
$arr = $inputArray;
$object = new $this->modelClassName();
$object->validateAndFill($arr);
$this->dataService->create($object);
return $object;
catch (Exception $exception)
$this->handleError($exception);
如果模型通过验证,它会照常继续。如果出现验证错误,它会返回上一页,并在闪存数据/错误包中显示验证错误。
我很可能会将 $person->validate() 方法移到我的服务类中,但是它仍然可以按上述方式工作。
【讨论】:
【参考方案4】:您可以通过在 Model 中编写来简单地进行验证。
在您的模型文件中
即模型\Test.php
public static $createRules = [
'name'=>'required|max:111',
'email'=>'required|email|unique:users',
];
在控制器中
public function store(Request $request)
$request->validate(ModalName::$createRules);
$data = new ModelName();
只要这样做。一切都会好起来的。
【讨论】:
以上是关于模型中的 Laravel 5 验证的主要内容,如果未能解决你的问题,请参考以下文章
使用新模型和保护的 Laravel 身份验证失败:未定义索引:模型