I’ve got the following model:
<?php namespace App; use IlluminateDatabaseEloquentModel; class Product extends Model { protected $guarded = ['id']; public static function rules() { return [ 'created_at' => 'nullable', 'updated_at' => 'nullable', 'name' => 'required|string|between:1,255', 'description' => 'required|string|between:1,255', 'date_added' => 'nullable', 'date_edited' => 'nullable', 'unit' => 'required|string|between:1,255', 'unit_type' => 'required|integer', 'stock' => 'nullable|string|between:0,255', 'barcode' => 'nullable|string|between:0,32', 'tax' => 'nullable|float', 'price' => 'nullable|float', 'category_id' => 'required|integer|gt:0' ]; } }
And there’s a controller ProductController
that has an action insertProduct
.
class class ProductController extends ApiController { // controller class public function insertProduct(Request $request) { $inputJson = $request->input('data_json', null); if(empty($inputJson)) { $inputJson = $request->getContent(); if(empty($inputJson)) { return $this->errorResponse( 'Either data_json formdata parameter or request body should contain a JSON string.' ); } } try { $product = $this->extractProductFromJSON($inputJson); } catch(Exception $e) { return $this->errorResponse($e->getMessage(), 400); } // When I dump the Product ($product) instance using dd(), it is just as expected and its // properties contain the right values. $validator = Validator::make($product, Product::rules()); /* Above line causes exception: TypeError: Argument 1 passed to IlluminateValidationFactory::make() must be of the type array, object given, called in /.../vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 261 in file /.../vendor/laravel/framework/src/Illuminate/Validation/Factory.php on line 98 */ if($validator->fails()) { return $this->errorResponse($validator->errors()->first()); } // ... } // How I extract the data from the JSON string (which is input). // Although I don't think this has anything to do with my problem. private function extractProductFromJSON(string $json) { $data = json_decode($json); if(json_last_error() != JSON_ERROR_NONE) { throw new Exception('Error parsing JSON: ' . json_last_error_msg()); } try { $productData = $data->product; $productId = empty($productData->id) ? null : $productData->id; // Product id is allowed to be absent $product = new Product(); // My AppProduct model instance. $product->id = $productId; $product->name = $productData->name; $product->description = $productData->description; $product->date_added = $productData->date_added; $product->date_edited = $productData->date_edited; $product->unit = $productData->unit; $product->unit_type = $productData->unit_type; $product->stock = $productData->stock; $product->barcode = $productData->barcode; $product->tax = $productData->tax; $product->price = $productData->price; $product->category_id = $productData->category_id; return $product; } catch(Exception $e) { echo 'EXCEPTION...'; } } } // end of controller class
It seems pretty clear there’s something wrong with the following line:
$validator = Validator::make($product, Product::rules());
The simplest cause I can think of, is that the validator simply does not accept objects and only wants arrays.
If not, what could be the problem?
If Laravel’s validation only works with arrays, is it somehow possible to validate an object?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
validator = Validator::make($product, Product::rules());
the problem is not Product::rules()
but $product
. Product::rules()
is correct because it’s return an array, but $product
is an object instead of an array. You should change/convert $product
to an array an example:
validator = Validator::make((array)$product, Product::rules());
Method 2
Yes! You’re right. If we look at the make method, we can see that it accepts rules as an array.
* @param array $data * @param array $rules * @param array $messages * @param array $customAttributes * @return IlluminateValidationValidator * @static */ public static function make($data, $rules, $messages = [], $customAttributes = []) { /** @var IlluminateValidationFactory $instance */ return $instance->make($data, $rules, $messages, $customAttributes); }
I usually validate data directly in the controller
$validator = Validator::make($info, [ 'shortDescription' => 'required', 'description' => 'required', 'countryId' => 'required', 'cities' => 'required | array | min:1', ]);
Method 3
class Cliente extends Eloquent { public static $autoValidates = true; protected static $rules = []; protected static function boot() { parent::boot(); // or static::creating, or static::updating static::saving(function($model) { if ($model::$autoValidates) { return $model->validate(); } }); } public function validate() { } }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0