I'm using Laravel and I have a custom validation. I want to pass some value to the validation class and validate it against the DB so I keep all the validation logic in the validation class. Here's my code but the validation error is not triggered:
public function rules() {
$userCode = UserCode::getCode();
$rules = [
'name' => 'required|string',
'email' => 'required|email',
$userCode => 'unique:user_codes,code,'. $userCode
];
return $rules;
}
What am I doing wrong here? the validation is never triggered even if the value $userCode already exists in the DB. The validation is triggered if the request contains bad email for example.
Edit: I have this user_codes table that has a code column that must be kept unique. UserCode::getCode() produces this code. So I also want to check if this code is unique or not in the table user_codes before passing it to the controller. I already have the custom validator but the problem is that I want it to also validate this code. The validator works fine with the other request body. The problem is that this code is not passed from the request body but it is simply generated from another method.
You could do this using a FormRequest class with the prepareForValidation() method. It should look something like this:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class WhateverRequest extends FormRequest
{
protected function prepareForValidation(): void
{
$this->merge([
'user_code' => UserCode::getCode(),
]);
}
public function rules(): array
{
return [
'name' => 'required|string',
'email' => 'required|email',
'user_code' => 'unique:user_codes,code'
];
}
}
your question is not clear, I understand you have a column named by code
and you want to be unique, you can add usercode to request,
request()->merge(['userCode'=>$userCode]);
then
$rules = [
'name' => 'required|string',
'email' => 'required|email',
'userCode' => 'unique:user_codes,code,'.UserCode::getId().',id'
];
I answered what I understand from your question
Okay start with the following:
php artisan make:rule SomeAwesomeRule
Then edit that created Rule
class SomeAwesomeRule implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
//some logic that needs to be handled...
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return __('Some.nice.translated.message');
}
}
And then apply the rule
$rules = [
'name' => 'required|string',
'email' => 'required|email',
'userCode' => new SomeAwesomeRule(#this is a constructor so pass away)
];
see
$rules = [
'name' => 'required|string',
'email' => 'required|email',
'userCode' => 'unique:user_codes,code'
];
//or
$userCode="";
do{
$userCode = UserCode::getCode();
}
while(UserCode::where('code',$userCode)->first());
// after loop you sure the code is unique
$rules = [
'name' => 'required|string',
'email' => 'required|email',
];
Related
I'm trying to update a company data using CompanyRequest but got an error. Please see my code below and other details.
CompanyRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Validation\Rule;
use Illuminate\Foundation\Http\FormRequest;
class CompanyRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
if($this->isMethod('PATCH')) {
return [
'name' => [
'required',
'max:255',
Rule::unique('companies')->ignore($this->id)
],
'owner' => 'required|max:255',
'address' => ''
];
}
return [
'name' => 'required|max:255|unique:companies',
'owner' => 'required|max:255',
'address' => ''
];
}
}
CompanyController.php
public function update(Company $company, CompanyRequest $request)
{
return $company->update($request->validated());
}
api.php
Route::patch('company/{company}', [CompanyController::class, 'update'])->name('company.update');
Error
I think you need to use the same property as the route
Rule::unique('companies')->ignore($this->company)
Try something like
'name' => 'unique:companies,name,' . $id,
so basically name is unique, but allow update when id is same.
To tell the unique rule to ignore the user's ID, you may pass the ID as the third parameter:
'name' => 'unique:companies,column,'.$this->id
I want to create a Request made by php artisan make:request wherein rules I can add a param, for instance I have the following validator in the controller:
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:{{number}}',
'body' => 'required',
]);
Where number is from url parameter
How can I get this url parameter in my Request class?
Here is my Request class:
<?php
namespace Modules\Blog\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
class SaveBlogCategoriesRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
dd($request->param);
return [
'lang' => 'required',
'name' => 'required',
'slug' => "required|unique:blog_categories_id,slug,", // here I want to add id from param
];
}
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
protected function failedValidation(Validator $validator)
{
$data = [
'status' => false,
'validator' => true,
'msg' => [
'e' => $validator->messages(),
'type' => 'error'
],
];
throw new HttpResponseException(response()->json($data));
}
}
For the request class, you dont need to instantiate the validator
class ModelCreateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
//if you need the input, you can access it via $this->request;
$param = $this->request->get('param');
//or you can also access it directly (yeah I know it not intuitive)
$param = $this->param
return [
'lang' => 'required',
'name' => 'required',
'slug' => "required|unique:blog_categories_id,slug,".$param,
];
}
}
Use dd($this) to get the request object in request class
I'm using FormRequest for Validation.
I'm creating record in DB. There a some fields which are not required, how can i get them through FormRequest. At, the moment i'm only getting fields which are in rules() method.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CategoryRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'title_tr' => 'required|min:2|max:255',
'description_tr' => 'required',
'parent_id' => 'required',
'seo_title_tr' => 'required',
'meta_description_tr' => 'required'
];
}
public function messages(){
return [
'title_tr.required' => trans('admin.category.validation_errors.title_tr'),
'description_tr.required' => trans('admin.category.validation_errors.description_tr'),
'seo_title_tr.required' => trans('admin.category.validation_errors.seo_title_tr'),
'meta_description_tr.required' => trans('admin.category.validation_errors.meta_description_tr'),
];
}
}
you can use sometimes
Validating When Present In some situations, you may wish to run
validation checks against a field only if that field is present in the
input array. To quickly accomplish this, add the sometimes rule to
your rule list:
public function rules()
{
return [
'username' => 'sometimes',
];
}
You can make it nullable as shown below.
public function rules()
{
return [
// ...
'not_required_field' => 'nullable',
];
}
I have read in the documentation how to create new custom validation rule.
I have made one like the one in the example but to only allow lowercase. The class is creatively named Lowercase.
Now I want to add that to the Validator-list in the RegisterController generated from make:auth. This is the list I want to add it to:
return Validator::make($data, [
'name' => 'required|string|max:255|**ADD MY VALIDATOR HERE**',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
Obviously there is something here I am missing... In the documentation it says to use the one I have done like this:
$request->validate([
'name' => ['required', 'string', new Lowercase],
]);
What do I need to do to be able to add my custom rule to the list above?
EDIT 1:
Per request I am showing the rule I have created. It is IDENTICALL to the one in the linked example in the documentation but I have switched the name of it from Uppercase to Lowercase and strtoupper to strtolower
public function passes($attribute, $value)
{
return strtolower($value) === $value;
}
You have a few options. One would be to use artisan to make a rule
php artisan make:rule Lowercase
You would end up with app\rules\Lowercase.php which you'd want to look something like this
<?php
namespace App\Rules;
use Auth;
use Illuminate\Contracts\Validation\Rule;
class Lowercase implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return strtolower($value) === $value;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Must be lowercase!';
}
}
"Once the rule has been defined, you may attach it to a validator by passing an instance of the rule object with your other validation rules:"
So in your RegisterController
use App\Rules\Lowercase;
return Validator::make($data, [
'name' => ['required', 'string', 'max:255', new Lowercase],
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
A second option would be to use a closure and not bother making the custom rule with artisan. This works well if you don't really need to use the rule somewhere else.
So in your RegisterController you can do something like this:
return Validator::make($data, [
'name' => [
'required',
'max:255',
function ($attribute, $value, $fail) {
if (strtolower($value) != $value) {
$fail($attribute.' must be all lowercase.');
}
},
],
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
$request->validate([
'name' => ['required','string', 'max:255', 'new MyNewRuleClass(or Uppercase)'],
'email' => ['required', 'string','email','max:255','unique:users'],
'password' => ['required','string','min:6','confirmed'],
]);
Hope this helps you.
I use Laravel to submit a form. Here is my web.php routes :
Route::middleware(['auth'])->prefix('account')->namespace('Account')->group(function () {
Route::get('informations', 'AccountController#index')->name('account.informations');
Route::post('informations', 'AccountController#update')->name('account.informations.post');
});
My Controller AccountController.php :
/**
* #param UpdateMember $request
* #return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateUser $request)
{
dd($request->all());
$user = User::where('id', Auth::user()->id)
->update($request->all());
return redirect()->route('account.informations');
}
And my UpdateUser.php :
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users|confirmed',
'password' => 'required|string|min:6|confirmed',
];
}
My problem : when I use UserUpdate $request in my controller, I don't reach the function, the dd($request->all()) is not shown.
But if I replace :
public function update(UpdateUser $request)
By
public function update(Request $request)
My controller is reached. What do I do wrong ?
what about the unique field validation like email because your validation rules returns a error email already exists while updating a existing record. This can be solved as example below
public function rules()
{
$client = Client::find($this->client);
return [
'name' => 'required|string',
'address' => 'required|string',
'gender' => 'required|string',
'dob' => 'required|string',
'phone' => 'required|string',
'email' => 'required|unique:clients,email,' . $client->id,
'password' => 'regex:/^[0-9a-zA-Z]*$/',
'profile-photo' => 'image|mimes:jpg,png,jpeg',
'c_name' => 'nullable|regex:/^[a-zA-Z ]*$/',
'c_address' => 'nullable|regex:/^[a-zA-Z ]*$/',
'c_email' => 'nullable|email|unique:clients,company_email,'. $client->id,
'c_contact' => 'nullable|regex:/^[0-9]*$/',
];
}
In my case, the reason was that I forgt to add "Accept: application/json" in the request header. After adding that header everything worked fine