I would like to ignore one of the inputs inside a FormRequest class. Previously, I've already done it on my previous Laravel project using the exact same code (The previous Laravel project was Laravel Version 7). Here is the code of my ignore validation:
class UserRequest extends FormRequest
{
protected $user;
public function __construct(Request $request)
{
$this->user = $request->route()->client;
}
public function rules()
{
return [
'email' => ['nullable', 'string', 'email', 'max:100', 'unique:users,email,'.$this->user.',user_id'],
];
}
The line code "$request->route()->client" is to get the submitted form request data (client is one of the route inside the web.php file).
But when I try this code inside the current project (Current project is Laravel 8). The results was the email was not ignored.
I guess there are something new in Laravel 8 about FormRequest? How can I solve this?
UPDATE
Here is my route (web.php) code:
Route::middleware('auth')->group(function () {
Route::resource('users', UserController::class);
And here is my users table structure:
I used the resource Controller so the route is simple.
try following way
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UserRequest 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<string, mixed>
*/
public function rules()
{
return [
'email' => [
'nullable', 'string', 'email', 'max:100',
Rule::unique('users','email')->ignore($this->route()->client,'user_id'),
],
];
}
}
and ignore method accept two params
ignore($id, $idColumn = null)
for the second column default, it treats as the id column as the primary key.if not then we should specify the column name.
so there is no need to use a constructor and all
Related
I am new to Laravel. I decide to apply my understanding on Laravel to create a simple registration API.
This API will receive three data which are name, email, and password. These input data will be validated inside the Request file. But I found that, if I use the RegisterUserRequest $request inside my Controller file, the method inside controller file is not executed.
Here is my AuthController file:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\RegisterUserRequest;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function register(RegisterUserRequest $request)
{
return response()->json([
'message' => 'Here',
]);
}
}
Here is my RegisterUserRequest file
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Foundation\Http\FormRequest;
class RegisterUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* #return array<string, mixed>
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
];
}
}
Here is my route
Route::group(['namespace' => 'App\Http\Controllers\Api'], function () {
Route::post('register', [AuthController::class, 'register']);
});
Here is the output show on Postman:
Because suppose the output show on Postman would be:
{
"message": "Here"
}
But it don't. So i think that the register method inside the AuthController is not executed.
Is anyone know the problem? Really Appreciated!!!
Thank you.
As you defined, the user is not authorized to make this request:
public function authorize()
{
return false;
}
Set it to true.
The standard way to validating incoming requests in Laravel is something like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*
* #return Response
*/
public function create()
{
return view('post.create');
}
/**
* Store a new blog post.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
}
There’s nothing wrong with validating requests in controllers, But how could I write the validation logic out of the controller to keep it clean and not break Single Responsibility Principle?
You could make your own form Request.
First create a request with php artisan make:request StorePostRequest
Create your own rule in this class like:
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
Update your controller function
public function store(StorePostRequest $request)
{
// do something
}
For more info:
https://laravel.com/docs/5.7/validation#creating-form-requests
Use the form requests provided by Laravel:
https://laravel.com/docs/5.7/validation#creating-form-requests
and make sure your controller uses the ValidatesRequests trait.
Form requests are validated before the controller actions are executed and contain validation rules and authorization logics.
I'm trying to create laravel form validation, so I created a form validation with the following code. The problem is that I'm getting an error "Class App\Http\Requests\RegisterForm does not exist" when I typehint the request in controller. Any help would be much appriciated. Thanks
RegisterForm.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterForm 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 [
'name': 'required',
'email': 'required',
'mobile_number': 'required',
];
}
}
UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\RegisterForm;
class UserController extends Controller
{
public function register(RegisterForm $request) {
}
public function login() {
}
}
Laravel version 5.7
NGINX
php7.2
the issue was caused by using colon (:) instead of => in rules array
return [
'name'=> 'required',
'email'=> 'required',
'mobile_number'=> 'required',
];
I have generated new form Request for the controller, but I do not know how to filter data before there will handle in the validator and so on.
Are there some native solutions in Laravel for this case?
class TestRequest 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" => "required|string",
"order" => "required|integer"
];
}
}
class TestController extends Controller
{
public function store(TestRequest $request, $chapterId)
{
// some business logic
}
}
There is some solution in Laravel 5.5 but in this example author uses
validate for filtering data from request, but I need to use filter inside TestRequest
$data = $this->validate(request(), [
//...
]); // I can't use this inside TestRequest
You can use my package: https://github.com/mikicaivosevic/laravel-filters
It's allows you to filter request values before validation...
<?php
class LoginRequest extends FormRequest {
//Filter
public function filters()
{
return [
'name' => 'lower',
'id' => 'int',
];
}
//...
}
Convert $request->name value into lowercase.
Conert $request->id value into integer.
I want to use Form Requests to validate Model so i started by create php artisan make:request TaskRequest and after i add in TaskRequest class `
public function rules()
{
return [
'name' => 'required|min:5',
];
}
public function messages()
{
return [
'name.required' => 'A title is required',
];
}
`
and in My logic
Route::post('/tasks',function (\App\Http\Requests\TaskRequest $request){
$task = new \App\Task();
$task->name = $request->input("name");
$task->save();
return response()->json(['task was created',$task], http_response_code());
});
So when i try to add a task i get error HttpException, This action is unauthorized.,AuthorizationException ...
It was work for me without Validation. So how can i fix this issue ?
Every (self-created) request has an authorize function that determines if the user is allowed to send the request. This can be useful to check for admin privileges or similar.
In you case, you can simply return true. More information can be found in the corresponding docs
Your authorize function in your TaskRequest would look like this:
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
In your custom request class for "form request" which contains the validation logic pass return:true; instead of return:false; and then it will work like a charm.
The code will look like something as following,
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class portfolioValidate 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'=> 'required',
'content'=> 'required'
];
}
}
as you can use middleware to make authentication for the page which contains this form... so we don't need that authorization in the FormRequest class. So returning true will make it(validation) authorized for all cases.
I think now it is clear to everyone now.