I'm trying to make a unique validator to check against a specific product. Like:
// Validate Request for name and url
$this->validate($request, [
'nome' => 'bail|required|min:2|unique:produto,name',
'url' => 'required|unique:produto',
]);
// Grab the user->id
$user_id = Auth::user()->id;
// Create a new product
if ($product = Product::create([
'user_id' => $user_id,
'name' => $request['nome'],
'url' => $request['url'],
'is_active' => $request['is_active'],
])) {
flash()->success('Produto criado.');
} else {
flash()->error('Não foi possivel criar produto.');
}
// Check if $request data is unique at above created product
$this->validate($request, [
'addmore.*.plataforma' => 'required|unique:plataforma_produto,plataforma_id,' . $product->id . ',id,product_id',
]);
// For each of the addmore.*. fields create an entry on DB
foreach ($request->addmore as $value) {
Plataformaprod::create([
'product_key' => $value['product_key'],
'basic_authentication' => $value['basic_authentication'],
'codigo_produto' => $value['codigo_produto'],
'plataforma_id' => $value['plataforma'],
'product_id' => $product->id,
]);
}
return redirect()->route('products.index');
Checking the comments inside my code its basically doing this:
Validate $request for name and url
Grab the user->id
Create a new product
(this is what I can't get to work) RUN THE UNIQUE RULE JUST AGAINST A SPECIFIC PRODUCT_ID AND CHECK IF IT HAS UNIQUE PLATAFORMA_ID ENTRIES!
Couldn't make the validation rule to work properly so I found this solution:
Created a unique index between the product_id and plataforma_id inside my migration file.
Created a try catch encapsulating the hole store method.
Catch the $e and turn it to a 500 error message saying: "The product already have a plataforma_id with that ID. Just added the first
record, change it's info in Edit page. It this error persists contact
dev#"
Related
I am working with the laravel validations in form request and this time I need to validate a data array something like this:
public function rules()
{
$rules = [
'products.*.quantity' => 'required|integer',
'products.*.dimension' => 'required|min:5|max:16',
'products.*.description' => 'required|min:5',
];
return $rules;
}
where products is the array where I have each of the items, this works however it gives me a message more or less like this: The products.1.quantity field is required.
I need to change the name of the attribute, I know it is possible to change the name inside the messages method giving a new value to products.*. quantity for example products.*. quantity => "quantity", however I would also like to specify the key of the item that is failing and at the end have a message like this:
The quantity in item 1 field is required.
then is it possible to achieve this?
Search for this file resources/lang/xx/validation.php and modify custom entry with your custom messages
'custom' => [
'products.*.quantity' => [
'required' => 'Your custom message',
]
]
I've got a table called Sides which consists of id, name, side_category_id and some other fields not important at the moment.
I wanted to validate that when creating a new side record, the record doesn't exist already. So, let's say I've got in the database a record such as:
id: 1
name: Salad
side_category_id: 3
If I try to insert a new record with name = 'salad' and side_category_id = 3 then the creation must fail and return an error.
I've achieved this by using the following rule:
$rules = [
'name' => 'required',
'side_category_id' => 'required|exists:side_categories,id|unique:sides,side_category_id,NULL,id,name,' . $this->request->get('name')
]
So far so good. It works as it's supposed to. But now it's returning an error if I want to edit a record and save it without any modifications and this is not my desired outcome.
If I try to update the record with no modifications it should succeed. How can I update my rule to achieve this?
you can use Rule::unique()
for create use like this
$rules = [
'name' => ['required'],
'side_category_id' => ['required',Rule::unique('sides', 'name')->where(function ($query) use($category_id) {
return $query->where('side_category_id', $category_id);
}),Rule::exists('side_categories')]
]
for update
$rules = [
'name' => ['required'],
'side_category_id' => ['required',Rule::unique('sides', 'name')->where(function ($query) use($category_id) {
return $query->where('side_category_id', $category_id);
})->ignore($id),Rule::exists('side_categories')]
]
//$id should be you parameter
I am using a 2 dimensional array of fields in Laravel 5.3. I wish to validate all the values of that as required and to display the individual error messages.
I used the validation in the controller function as follows
$this->validate($request, [
'training_id' =>'required',
'survey_name' =>'required',
'question.*' =>'required',
'answer_option.*.*' =>'required'
],
['question.*.required' => 'The question field is required.',
'answer_option.*.*.required' => 'The answer field is required.']);
In the view page while i tried to display all the error messages, only the first row of answers will be validated and the others won't. The error messages are as
Array ( [0] => The question field is required. [1] => The question field is required. [2] => The answer_option.0.0 field is required. [3] => The answer_option.0.1 field is required. [4] => The answer_option.0.2 field is required. [5] => The answer_option.0.3 field is required. [6] => The training id field is required. [7] => The survey name field is required. )
To Validate all the fields with custom error message individually, Creating validator manually is the best solution....
step-1:
use Validator; (after namespace of any controller where validation is needed)
step-2:
Add a method (suppose the method name check_data()). And inside the following code will be placed....
public function check_data(Request $request){
//Rules for form fields
$rules = array(
'training_id' =>'required',
'survey_name' =>'required',
'question' =>'required',
'answer_option' =>'required'
);
//Custom message for individual fields
$messages = array(
'training_id.required' => 'Training Id should not be empty...',
'survey_name.required' => 'Survey Name is Essential...',
'question.required' => 'Question is urgent...',
'answer_option.required' => 'Answer option can be any one but required...'
);
$validator = Validator::make($request->all(), $rules, $messages);
//Check for validation
if ($validator->fails()) {
//if validation fails
return redirect()->back()->withInput()->withErrors($validator);
} else {
//Validation is successful and do as you wish
return "All data are validated !!";
}
}
Hopefully, It will work
These are my rules in my class:
class AppointmentsController extends Controller
{
protected $rules = [
'appointment' => ['required', 'min:5'],
'slug' => ['required', 'unique:appointments'],
'description' => ['required'],
'date' => ['required', 'date_format:"Y-m-d H:i"'],
];
This is in the laravel official docs:
Sometimes, you may wish to ignore a given ID during the unique check.
For example, consider an "update profile" screen that includes the
user's name, e-mail address, and location. Of course, you will want to
verify that the e-mail address is unique. However, if the user only
changes the name field and not the e-mail field, you do not want a
validation error to be thrown because the user is already the owner of
the e-mail address. You only want to throw a validation error if the
user provides an e-mail address that is already used by a different
user. To tell the unique rule to ignore the user's ID, you may pass
the ID as the third parameter:
'email' => 'unique:users,email_address,'.$user->id.',user_id'
I tried using this in my rules:
'slug' => ['required', 'unique:appointments,id,:id'],
This indeed ignores the current row BUT it ignores it completely. What I want to accomplish is, I want it to ignore the current row only if the slug is unchanged. When it is changed to something that is already unique in another row, I want it to throw an error.
The Unique validator works like that
unique:table,column,except,idColumn
So in your case, you can do it like that:
Get the id you want to validate against, you can get it from the route or with any other way that works for you; something like that
$id = $this->route('id');
'slug' => ['required','unique:appointments,slug,'.$id],
For example we need to update contact info into Users table.
In my model User I created this static method:
static function getContactDataValidationRules( $idUserToExcept ) {
return [
'email' => 'required|email|max:255|unique:users,email,' . $idUserToExcept,
'pec' => 'required|email|max:255',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:8|max:20',
'mobile' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:8|max:20',
'phone2' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:8|max:20',
'recovery_email' => 'required|email|max:255',
];
}
and in my UsersController, into the method that update User I've:
$id = $request->input('id');
$request->validate(User::getContactDataValidationRules( $id ));
:-)
I have a model with a mobileNumber property. the mobile number is unique and the validation rules are:
public static $rulesForEdit = array(
'firstName' => 'required|min:5',
'lastName' => 'required|min:5',
'mobileNumber' => 'required|min:5|unique:admin,mobileNumber|numeric'
);
when I update the model, I do this:
$data = array('firstName' => Input::get('firstName'),
'lastName' => Input::get('lastName'),
'mobileNumber' => Input::get('mobileNumber')
);
$validation = Validator::make($data, Admin::$rulesForEdit);
if($validation->passes()){
$admin = Admin::find($id);
$admin->firstName = Input::get('firstName');
$admin->lastName = Input::get('lastName');
$admin->mobileNumber = Input::get('mobileNumber');
$admin->update();
return Redirect::to("restaurants/admins/".$admin->id);
}else{
return Redirect::back()->withInput()->withErrors($validation);
}
The problem that I keep getting a validation error message states that : The mobile number has already been taken, which is correct, but the mobile is belongs to the same model that I am updating, there is no other model that took this mobile number, just the one that I want to update. In other words, I am updating the firstname and the last name but not the mobile number,
To force the Validator to ignore unique rule for a given id you may pass the id of that recored which is being validated, for example:
'mobileNumber' => 'required|min:5|numeric|unique:admin,mobileNumber,50'
This, will not check uniqueness of the model if the id is 10, so when you are updating the model you need to pass the id of the current model to ignore the unique rule on this model:
'mobileNumber' => 'required|min:5|numeric|unique:admin,mobileNumber,' . $id
// Replace the Model with the name of your model within the controller
// update method before the validation takes place
Model::$rules['mobileNumber'] = 'required|min:5|numeric|unique:admin,mobileNumber,' . $id;