Howto reusing Form Request inside loop - laravel

I am making a "/bulk" endpoint for my API/REST made in Laravel 8.
My problem is that I don't know how to reuse the same FormRequest that I have for the create or update
json post to: /cars/bulk
{
"cars": [{"model": "A", "year": 2021, "plate": "AA11BB"},{"model": "B", "year": 2021, "plate": "AA12BB"},{"model": "C", "plate": "AA13BB"}]
}
// CarController.php
public function store(CarRequest $request)
{
$car = $this->carService->store($request, Car::class);
}
public function update(CarRequest $request, Car $car)
{
$this->carService->update($request, $car);
}
public function bulk(Request $request)
{
$this->carService->bulk($request);
}
// CarService.php
public function store($request, $modelClass)
{
# My code....
}
public function update($request, $model)
{
# My code....
}
public function bulk($request)
{
foreach ($request->cars AS $carData )
{
$car = Car::where('plate','=',$carData->plate)->first()
# here is the problem,
# howto validate each $car by reusing CarRequest
if ($car){
$this->update($carData, $car);
} else {
$this->store($carData, Car::class);
}
}
}
This is de form request for each item, i have use to for bulk or one request
class CarRequest extends BaseRequest
{
public function authorize()
{
$this->setModel(Car::class);
return $this->isAuthorized();
}
public function rules()
{
$this->setModel(Car::class);
$rules = parent::rules();
$rules = [
'model' => 'required',
'year' => 'required|numeric',
'plate' => 'required'
];
return $rules;
}
public function messages()
{
# multiples messages
}
}
I need reuse my request
Edit: add form request

So I wouldn't suggest using it within a loop how you have in your example, what would be better would be to create a second, bulk request that valiates an array like this.
public function rules()
{
$this->setModel(Car::class);
$rules = parent::rules();
$rules = [
'cars' => ['required', 'array'],
'cars.*.model' => 'required',
'cars.*.year' => 'required|numeric',
'cars.*.plate' => 'required'
];
return $rules;
}

You can do it with same CarRequest form request class as follows.
public function rules()
{
return[
'cars.*.model' => 'required',
'cars.*.year' => 'required',
'cars.*.plate' => 'required',
];
}
Laravel will expect that you are sending nested array. If you dont want to mix it up with CarRequest you can do it with creating another FormRequest class.

Related

Unique Rule for two fields failed in Laravel

In my Laravel-5.8, I have this model:
class HrDepartment extends Model
{
public $timestamps = false;
protected $table = 'hr_departments';
protected $fillable = [
'company_id',
'dept_name',
];
public function company()
{
return $this->belongsTo('App\Models\Organization\OrgCompany', 'company_id');
}
}
I tried to use Request Rules
Rules
class StoreDepartmentRequest extends FormRequest
{
public function authorize()
{
return \Gate::allows('department_create');
}
public function rules()
{
return [
'dept_name' => [
'required',
'string',
'min:2',
'max:80',
Rule::unique('hr_departments', 'dept_name', 'company_id')
],
];
}
public function messages()
{
return [
'dept_name.max:80' => 'Department Name cannot be more than 80 characters.',
'dept_name.unique' => 'Department Name already exists.',
'dept_name.required' => 'Please enter the Department Name.',
];
}
}
Controller
public function store(StoreDepartmentRequest $request)
{
$department = HrDepartment::create([
'dept_name' => $request->dept_name,
'company_id' => Auth::user()->company_id,
]);
Session::flash('success', 'Department is created successfully');
return redirect()->route('hr.departments.index');return redirect()->route('hr.departments.index');
}
}
I entered dept_name, Services for company 1, when I entered Services for company 2, I got this error:
'Department Name already exists.',
Why and how do I resolve it?
Thanks
use this code for unique validation
Rule::unique('hr_departments')->ignore($hr_department->id)

Laravel resource empty request parameters

When calling API route the data from query doesn't get passed to resource and the request doesn't contain any data from the query.
Route
Route::get('rooms', 'RoomController#index');
Controller
public function index() {
$rooms = Room::get();
return RoomCollection::collection($rooms);
}
Resource
public function toArray($request){
return [
'id' => $this->uid_room,
'code' => $this->room_code,
'name' => $this->name
];
}
Maybe you need Room::all() instead of Room::get()?
In controller
use App\Room;
use App\Http\Resources\Room as RoomResource;
public function index() {
$rooms = Room::all();
return RoomResource::collection($rooms);
}
In App\Http\Resources\Room.php
public function toArray($request){
return [
'id' => $this->uid_room,
'code' => $this->room_code,
'name' => $this->name
];
}

How to adopt FormRequest to API JSON request?

How to adopt FormRequest to API JSON request? Now it looks as:
class CreateOrder extends FormRequest
{
// Validation rules
public function rules()
{
return [
'DeliveryDate' => 'required|date_format:d-m-Y H:m:s',
'PostCard' => 'boolean',
'PostCardText' => 'string|max:250',
'PhotoBefore' => 'boolean',
'Remark' => 'string|max:200',
'OrderDate' => 'required|date_format:d-m-Y',
'CallRecipientBefore' => 'boolean',
'AnonymousDelivery' => 'boolean',
'PhotoAfter' => 'boolean',
'Employers_Id' => 'required|integer',
'Employers_Id' => 'required|integer',
'Partners_Id' => 'required|integer',
];
}
public function authorize()
{
return true;
}
}
And using:
public function store(CreateOrder $request)
{
dd(Request::get('DeliveryDate'));
dd($request->all()); // Or
}
When I send data to this endpoint, Laravel instead showing incoming data $request, does redirect.
Sending data
Using Postman data is sent in raw format as:
{
"DeliveryDate": "2018-01-01"
}
As result I give Laravel screen saver.
So, I have did some tests, method is not called at all:
public function store(CreateOrder $request)
{
dd('ss');
}
Seems an error in class: CreateOrder

Error storing Topic Model into the database using Sentinel

I have a small forum, im trying to create topic and replies for the store method.
routes.php
Route::get('board/{id}/create', 'TopicsController#create');
Route::post('board/{id}/create', 'TopicsController#store');
TopicsController.php
public function store()
{
$this->request->user()->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}
I am receiving this error.
Call to a member function topics() on null
Also note, i am using Sentinel https://github.com/rydurham/Sentinel from this repo.
<?php namespace App\Models;
class User extends \Sentinel\Models\User
{
protected $fillable = ['email', 'first_name', 'last_name'];
protected $hidden = ['password'];
public function topics()
{
return $this->hasMany(Topic::class);
}
public function replies()
{
return $this->hasMany(Reply::class);
}
public function getGravatarAttribute()
{
$hash = md5(strtolower(trim($this->attributes['email'])));
return "https://www.gravatar.com/avatar/$hash";
}
}
Updated Model
public function store($id)
{
$user = Sentry::getUser($id);
$user->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}
It seems that your user object is null. Properly retrieve the user using the id
public function store($id)
{
$user = \App\Models\User::find(\Sentinel::getUser()->id);
$user->topics()->create([
'board_id' => $this->request->id,
'title' => $this->request->title,
'body' => $this->request->body
]);
return redirect(url('/board/' . $this->request->id));
}

Validation request with Laravel 5

I am trying to make validation with Laravel 5 on right way:
Here is my working code in model:
public function apiAddNewComment() {
if (Input::get("task") == 'addComment') {
$user = Auth::id();
$inputs = array(
'comment' => Input::get('comment'),
'projectID' => Input::get('projectID'),
'order' => Input::get("order"),
'level' => Input::get("level"),
);
$rules = array(
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
);
$validator = Validator::make($inputs, $rules);
if ($validator->fails()) {
return json_encode(array('err' => true, 'errors' => $validator->messages()->all()));
} else {
return $this->createNewComment();
}
}
}
here is my controller:
public function update($id, Comment $update)
{
return $update->apiUpdateComment();
}
How can I make validation with request?
And can someone explain me how this method works inside request:
public function authorize()
{
return false;
}
?
The Request has to basic functions: rules() and authorize()
rules returns an array that is used for the validation.
The authorize method can for example check if the user is allowed to do this request.
public function authorize() {
return Auth::check();
}
So you don't have to check it each time when you use the request in a controller.
If you need no check just return true.
UPDATE:
Generate a request File with artisan
php artisan make:request CommandRequest
then edit the generate file like this:
class CommandRequest extends FormRequest
{
public function rules()
{
return [
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
];
}
public function authorize()
{
return true;
}
}
Also update the controller method:
public function update($id, Comment $update, CommandRequest $request)
{
// create your comment here like:
return Comment::create($request->all());
}
You are using a Laravel 4 code I guess, you need to translate it to L5 where Input::get('var') turns into $request->input('var') for instance:
public function apiAddNewComment(Illuminate\Http\Request $request) { //Remember to add the Request as a parameter of the method
if ($request->input("task") == 'addComment') {
...
Then the validation part looks fine

Resources