For form validation I made a Request class via php artisan make:request UpdatePlanRequest.
However after using the UpdatePlanRequest class in store the method isn't called anymore.
The UpdatePlanRequest:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UpdatePlanRequest 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()
{ //TODO: CHECK IF THE PROTOTYPE IDS ARE OWNED BY THE USER (https://stackoverflow.com/questions/42662579/validate-an-array-of-integers/42693970)
return [
'start_date' => 'required|date',
'end_date' => 'required|date|after:start_date',
'name' => 'required|string'
];
}
}
The controller method:
use App\Http\Requests\UpdatePlanRequest;
public function store(UpdatePlanRequest $request)
{
//
dd('hello');
}
If the function header is store(Request $request) hello is shown, in that example it isn't.
The custom Request class is necessary to call $request->validated(); later for validation purposes according to the docs.
Is there a reason you have your Request class as being abstract? The default class that is created when running php artisan make:request <name> doesn't define the class as being abstract. This seems to work for me, but not when declaring it as abstract.
$request->validated(); is used to retrieve the validated inputs, so just by calling the UpdatePlanRequest it should validate the request
//Try This
use App\Http\Requests\UpdatePlanRequest;
public function store(UpdatePlanRequest $request)
{
$validatedData = $request->validated();
dd('$validatedData');
$profile = new Profile([
'user_id' => $request->get('user_id'),
]);
$profile->save();
echo $request->session()->flash('alert-success', 'Profile details Succefully Added!');
return redirect('create')->with('success', 'Data saved!');
}
Your route will be.
Route::get('profile','ProfileController#store');
Route::post('profile/create','ProfileController#store')->name('create');
Well this works right!
When the method is called, it checks the request class (UpdatePlanRequest). If there is an error, it does not enter the method anymore and you can not see the output of dd() function.
If the data is correct after checking the rules, then dd() will be displayed.
You must manage errors
Related
I am using laravel 5.8 version, i have one api which is responsible for registering ,i create one Request file which contains rules() and messages() function to display error messages but it's not throwing any error messages if any validation fails ,why this is happening can somebody explain ?
UserController.php
<?php
namespace App\Http\Controllers;
use App\Http\Requests\userRequest;
use App\UserSection;
class UserController extends Controller
{
public function userRegister(userRequest $request){
//logic of my code
return response()->json($success);
}
}
userRequest.php
<?php
namespace App\Http\Requests;
use App\Rules\CustomRule;
use Illuminate\Foundation\Http\FormRequest;
class userRequest extends FormRequest
{
public function messages()
{
return [
'first_name.required' => 'A title is required',
];
}
/**
* 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 [
'first_name' => 'string|required|max:25',
'phone_number' => 'required|integer'
];
}
}
The error i am facing when i hit the route without first_name key it's showing 404 not found error
you might have missed headers part for taking the form-data
Accept = application/json
As laravel docs
If validation fails, a redirect response will be generated to send the
user back to their previous location. The errors will also be flashed
to the session so they are available for display. If the request was
an AJAX request, a HTTP response with a 422 status code will be
returned to the user including a JSON representation of the validation
errors.
So you need to specify the response type you expect, if you use postman for testing your api end point you have to add in request header Accept:application/json
<?php
namespace App\Http\Controllers;
use App\Http\Requests\userRequest;
use App\UserSection;
class UserController extends Controller
{
public function userRegister(userRequest $request){
//logic of my code
return response()->json($success);
}
}
I'm a little bit confused to how I can store data in my api controller,
My json looks like this:
[
{ a: 1 },
{ a: 2 }
]
I have my rules
$rules = [
'*.a' => 'required',
];
I have my validation
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
$error = $validator->messages()->toJson();
return response($error, 200);
}
and now there's my "problem": I would like to make a cleaner code.
My old option was pass the request->all() to a variable , json decode the contenent and make a foreach cycle to store data as here:
foreach ($datas as $data) {
$data = new rawData([
'a' => $data->a,
]);
$newrawData->save();
}
can I do a cleaner thing?? and How?
You can put your validation logic in a custom form request validator.
First, create the validator
php artisan make:request ExampleRequest
You can find the newly created a new class in app/Http/Requests/ExampleRequest.php and you can add your rules as follows
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExampleRequest 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 [
'*.a' => 'required',
];
}
}
Now your controller method/action will not be executed unless the request passes the validation rules. you can use it in your controller method as follows:
In app/Http/Controllers/ExampleController.php
public function store(ExampleRequest $request)
{
// Your normal code.
}
that looks quite good. There is only one small thing I would have done differently. But it's a matter of taste.
foreach ($datas as $data) {
rawData::create($data->toArray());
}
And you can you use the request object directly to validate. or you implement an custom Request Object what you pass as parameter in your function.
$request->validate([
'*.a' => 'required',
]);
I make custom request by
php artisan make:request UserUpdate
and then fill UserUpdate
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name'=>'required|string',
'email'=>'required|email',
];
}
after that call from controller
public function profilepost(UserUpdate $request)
{
$user = Auth::user();
$user->name = $request['name'];
$user->email = $request['email'];
$user->save();
return back();
}
when submit form show error
Target class [app\Http\Requests\UserUpdate] does not exist.
Why that happen? Laravel documentation are not correct? Can someone explain me?
I Know it's solved, but this could be useful!
It's good practice to name the file/class like: UpdateUserRequest or UserUpdateRequest.
Why? It's more readable, other programmers understand what it does faster and
because of the specific name, class name collitions are avoided.
Remember if you have multiple requests on you project it's allways better to organize them in folders, example:
php artisan make:request User/UserUpdateRequest
This should create a request in User folder, and also with: namespace App\Http\Requests\User
Last but not least a better way to define the rules is:
public function rules()
{
return [
'name' => ['required', 'string'],
'email' => ['required', 'email'],
];
}
Why? This gives you the ability to add custom rules to the validations if needed!
I'm using Laravel 8.x and have a one-to-one and one-to-many relationship with models as follows.
class ServiceProvider extends Model
{
use HasFactory;
protected $guarded = [];
public function contact() {
return $this->hasOne('App\Models\Contact');
}
public function services() {
return $this->hasMany('App\Models\Service');
}
}
I'm using a single form to get all the data. The problem is both Contact and Service has their own validation to be done. I can duplicate the validation in the ServiceProviderController. But it seems ugly and violate DRY. Is there a way to call the ContactController and ServiceController to do the validation and return the validation result to be accessed by the ServiceProviderController?
As I guess you are doing something like:
/**
* Store a new service provider.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('services/create')
->withErrors($validator)
->withInput();
}
// Store The Service Provider...
}
If Yes, I would recommend using a form request validator to validate the request. So if the request is get passed your controller will be called. Also, you can use the same Request Validation rule for both controllers. you can read how to create and use one more here.
You can set up enumerator classes that will return validation rules for you, or even declare static properties on your model which will hold an array of validation rules, and which can be called like: ServiceProvider::$rules or something similar.
This way you will keep all your rules at one place. You can't explicitly call controllers whenever, they respond to routes.
When you get the validation rules, just use $request->validate() method and send the rules you gathered to it.
laravel5.2,I create a UserRequest.php under Requests directory,but in controller,public function add(UserRequest $request) show error,but use public function add(Request $request) is normal.
UserRequest
namespace App\Http\Requests;
use App\Http\Requests\Request;
class UserRequest extends Request
{
/**
* 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 [
'user_sn' => 'required|unique',
'user_name' => 'required',
'email' => 'required|unique',
'password' => 'required',
];
}
}
UserController
namespace App\Http\Controllers;
use App\Http\Requests\UserRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class UserController extends Controller
{
public function add(UserRequest $request)
{
if ($request->get('dosubmit')) {
$validator = Validator::make($request->all(), $request
->rules(), $request->messages());
if ($validator->fails()) {
return redirect('user/add')->withErrors($validator)
->withInput();
}
}
$corporation_list = DB::table('corporation')->get();
$department_list = DB::table('department')->get();
return view('user.add', ['corporation_list' => $corporation_list, 'department_list' => $department_list]);
}
}
Route
Route::group(['middleware'],function (){
Route::any('user/add',['as'=>'user.add','uses'=>'UserController#add']);
});
There are usually 2 reasons you could be having this issue.
You've not added the use statement for the UserRequest.
At the top of your controller (above the class) add:
use App\Http\Requests\UserRequest
assuming that is the correct namespace.
You may need to run composer dump-autoload to make sure the class has been added to the autoloader.
Edit
Firstly, replace the add() method with the following methods:
public function create()
{
$corporation_list = DB::table('corporation')->get();
$department_list = DB::table('department')->get();
return view('user.add', compact('corporation_list', 'department_list'));
}
public function store(UserRequest $request)
{
// If you get to this point the validation will have passed
// Process the request
}
Then change your routes from:
Route::any('user/add',['as'=>'user.add','uses'=>'UserController#add'])
to:
Route::get('user/add', ['as' => 'user.add', 'uses' => 'UserController#create']);
Route::post('user/add', ['as' => 'user.store', 'uses' => 'UserController#store']);
Obviously, feel free to change the as in the Routes to whatever, they should unique though.
Lastly, I would suggest looking at Resource Controllers which is a RESTful approach.
The problem is that you have not identified UserController that you are using UserRequest file
use App\Http\Requests\UserRequest
It will solve the problem