L8 - Make a FormRequest from another FormRequest fails - validation

I've a simple code (more o less) like this.
Routes:
Route::post('car', 'CarController#store')->name('insert_car.store');
Route::post('car-italian', 'CarItalianController#store')->name('insert_car-italian.store');
Controllers:
class CarController extends Controller
{
public function store(StoreCarRequest $request)
{
return Car::create($request->validated()) // Calling 'car-italian' route, the code fails here!
}
}
class CarItalianController extends Controller
{
public function store(StoreCarItalianRequest $request)
{
$input_parameters = $request->validated();
$t = [
'model' => $input_parameters['modello'],
'door' => $input_parameters['porte'],
];
return (new CarController)->store(new StoreCarRequest($t));
}
}
Forms Request:
class StoreCarRequest extends FormRequest
{
public function rules()
{
return [
'model' => 'string',
'door' => 'integer'
];
}
}
class StoreCarItalianRequest extends FormRequest
{
public function rules()
{
return [
'modello' => 'string',
'porte' => 'integer'
];
}
}
When I call the route car-italian, It fails with message:
Call to a member function validated() on null
Can someone help me? I spent one full day on it :-/
Thank you

Ok, I've found a solution updating the Controller CarItalianController:
class CarController extends Controller
{
public function store(StoreCarRequest $request)
{
return Car::create($request->validated())
}
}
class CarItalianController extends Controller
{
public function store(StoreCarItalianRequest $request)
{
$input_parameters = $request->validated();
$t = [
'model' => $input_parameters['modello'],
'door' => $input_parameters['porte'],
];
$insertRequest = new StoreCarRequest();
$insertRequest->setValidator(Validator::make($t, $insertRequest->rules()));
return (new CarController)->store($insertRequest);
}
}

Related

Problem with "Route" resource in laravel 8

My app was working fine until I wanted to replace my "get" routes with a single "resource" to be able to include a delete function. I remind you that I am a beginner in laravel so it is surely due to the fact that I can not be able to make a "resource" route.
This is my code :
Route::get('/', function(){
return view('front.pages.homepage');
})->name('homepage');
Route::get('/garages', [GarageController::class, 'index'])->name('garage.index');
Route::get('/garages/{garage}', [GarageController::class, 'show'])->name('garage.show');
Route::get('/garages_create', [GarageController::class, 'create'])->name('garage.create');
Route::post('/garages_create', [GarageController::class, 'garage_create'])->name('garage_create');
Route::resource('cars', [CarController::class]);
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Car;
use App\Models\Garage;
class CarController extends Controller
{
public function index()
{
$list = Car::paginate(10);
return view('cars', [
'list' => $list
]);
}
public function store()
{
$garages = Garage::orderBy('name')->get();
return view('carCreate/carCreate', [
'garages' => $garages,
]);
}
public function create(Request $request)
{
{
$request->validate([
'name' => 'required',
'release_year' => 'required',
'garage_id' => 'required', 'exists:garage_id'
]);
$car = new Car();
$car->name = $request->name;
$car->release_year = $request->release_year;
$car->garage_id = $request->garage_id;
$car->save();
return redirect('/cars');
}
}
public function show(Car $car)
{
return view('carShow/carShow', compact('car'));
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
And my error is : ErrorException
Array to string conversion

Is it correct to create different Api Resources for each request?

Will it be correct, if I create API RESOURCES for each request. And how to make a connection between three tables in Resources. For example:
class UserResource
public function toArray($request)
{
return [
'id'=>$this->id,
'name'=>$this->name
'work'=>WorkResource::collection($this->work)//relationship between USER and WORK
]
}
class WorkResource
public function toArray($request)
{
return [
'id'=>$this->id,
'title'=>$this->title
]
}
And in class UserResource I need to return from WORK only TITLE without ID, How I can do that?
I'm not sure if I got it right but $this->work seems singular while you are instanciating the resource using Resource::collection().
So my guess would be:
class UserResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'work' => new WorkResource($this->whenLoaded('work'))
];
}
}
class WorkResource
{
public function toArray($request)
{
return [
'title' => $this->title
];
}
}

Laravel 5.6 FormRequest validation

I have set of input fields to be validated. I have removed commas (since user enters comma as thousand separator) before validation takes place. But it still complains that the number is not numeric.
class UpdateFamilyExpense extends FormRequest
{
public function authorize()
{
return true;
}
public function sanitize()
{
$attributes = $this->all();
for ($i=1; $i<=15; $i++)
{
$attributes['e'.$i] = str_replace(',', '', $attributes['e'.$i]);
}
$this->replace($attributes);
}
public function rules()
{
$this->sanitize();
return [
'e1' => 'required|numeric',
];
}
public function messages()
{
return [
'e1.required' => 'required',
'e1.numeric' => 'must be a numeric',
];
}
}
I cannot figure out where I am wrong. Can someone help me figure out what I am missing here?
Override prepareForValidation as:
protected function prepareForValidation()
{
$this->sanitize();
}

Laravel API ResourceCollection WhenLoaded

I try to include a relationship in my resource array if it has been eager loaded, but don't get it working.
Anyone has an idea, how I can check the relationships in the ResourceCollection?
Database schema looks like this:
Here is my Post Model
class Post extends Model
{
function categories() {
return $this->belongsToMany('App\Category');
}
}
Here is my Category Model
class Category extends Model
{
function posts() {
return $this->belongsToMany('App\Post');
}
}
Here is my Post Controller
Class PostController extends Controller
{
public function index()
{
return new PostResourceCollection(Post::with("categories")->get());
}
}
Here is my Post ResourceCollection
class PostResourceCollection extends ResourceCollection
{
public function toArray($request)
{
return [
'data' => $this->collection->transform(function($page){
return [
'type' => 'posts',
'id' => $page->id,
'attributes' => [
'name' => $page->title,
],
];
}),
//'includes' => ($this->whenLoaded('categories')) ? 'true' : 'false',
//'includes' => ($this->relationLoaded('categories')) ? 'true' : 'false',
];
}
}
Maybe too late, below solution is a workaround for this case:
return [
...,
'includes' => $this->whenLoaded('categories', true),
];
Loading custom attribute:
return [
...,
'includes' => $this->whenLoaded('categories', fn() => $this->categories->name),
];
You relationship is wrong, a post belongs to many categories while a category has many posts so change:
class Category extends Model
{
function posts() {
return $this->belongsToMany('App\Post', 'category_post');
}
}
to
class Category extends Model
{
function posts() {
return $this->hasMany('App\Post', 'category_post');
}
}
Now when you load the post you can load the categories also:
$posts = Post::with('categories')->get();
got it.. That was the missing piece. if anyone has a better solution for this it would be much appreciated.
foreach ($this->collection as $item) {
if ($item->relationLoaded('categories')) {
$included = true;
}

Call to a member function associate() on a non-object

Error Message: http://puu.sh/d4l0F/5b0ac07e68.png
I've even saved the $transportation object before trying to create associations. I've verified that both $transporation, $from and $to are all their respective objects and they are.
I'm sure I'm missing something stupid here but I'm out of ideas.
My code:
class RideBuilder implements RideBuilderInterface
{
public function create(Advance $advance)
{
$ride = new Ride;
if($ride->validate(Input::all())) {
$ride->save();
$to = Location::find(Input::get('dropoffLocation'));
$from = Location::find(Input::get('pickupLocation'));
$transportation = new Transportation;
$transportation->save();
$transportation->transportable()->associate($ride);
$transportation->to()->associate($to);
$transportation->from()->associate($from);
$event = new Event;
$event->start = Input::get('ridePickUpTime');
$event->save();
$event->eventable->save($transportation);
$event->subjectable->save($advance);
}
return $ride;
}
}
Location Model:
class Location extends Elegant
{
protected $table = 'locations';
public $rules = array(
'label' => 'required|min:2',
'street' => 'required',
'city' => 'required',
'state' => 'required',
'type' => 'required',
);
public function advance()
{
return $this->belongsTo('Booksmart\Booking\Advance\Model\Advance');
}
public function locationable()
{
return $this->morphTo();
}
}
Transportation Model:
class Transportation extends Elegant
{
protected $table = 'transportations';
public function event()
{
$this->morphOne('Booksmart\Component\Event\Model\Event');
}
public function start_location()
{
$this->belongsTo('Booksmart\Component\Location\Model\Location', 'start_location');
}
public function end_location()
{
$this->belongsTo('Booksmart\Component\Location\Model\Location', 'end_location');
}
}
I had a similar issue. I made the stupid mistake of not adding the "return" in the relationship method!
Make sure you return the relationship... Obviously this will not work:
public function medicineType()
{
$this->belongsTo('MedicineType', 'id');
}
This is the correct way:
public function medicineType()
{
return $this->belongsTo('MedicineType', 'id');
}
Easy to miss, hard to debug...

Resources