【问题标题】:Laravel 5 validation in model模型中的 Laravel 5 验证
【发布时间】: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 字段是必需的。

我想展示这个

名称字段是必需的。
标题字段是必需的。

【问题讨论】:

    标签: php validation laravel laravel-5 laravel-5.2


    【解决方案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();
      }
      

      只要这样做。一切都会好起来的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        • 2019-04-21
        • 1970-01-01
        • 2015-07-02
        • 2016-10-13
        • 1970-01-01
        • 2013-10-07
        相关资源
        最近更新 更多