Skip to main content

At a first glance, it's simple: another CRUD-like resource for Parking, and we're done? But here's where you have a lot of room to choose from, how to structure the API endpoints and Controller methods.

  • Should it be /parkings/start and /parkings/stop?
  • Should it be POST /parkings and PUT /parkings?
  • Some other structure?

I posted this question on Twitter - you can read the replies or watch my re-cap on YouTube: To CRUD or Not To CRUD?.

In short, there are at least a few ways to structure this. I would go for a non-standard-CRUD approach and create a ParkingController with start/stop methods.

The Full Lesson is Only for Premium Members

Want to access all of our courses? (36 h 00 min)

You also get:

61 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

andywong31 avatar

Hi Povilas, question regarding your code under start method of ParkingController:

$parking->load('vehicle', 'zone');

Is it still necessary to use the load function to eager load vehicle and zone? i believe there wont be any N+1 problem knowing that there will only be one vehicle and one zone per parking.

👍 2
Povilas Korop avatar

Right, you're probably right, this time I was overly cautious. But better safe than sorry! :)

👍 6
Bless Darah avatar

This is the first time seeing this syntax. I'm happy to always learn something new in Laravel. It gives the confidence that I am getting far deeper into the framework everyday. Thanks a lot.

👍 3
kalDeveloper avatar

Since there will be only one record, is that the reason that show() and stop() method does not load relationships before passing to resource class like in the start() method ? thanks

Ali Al Qahtani avatar

In start method, when we fire this endpoint more one time it will store duplicate records at same parking and zone, so I suggest set a validation when same parking exists if stop time null.

👍 1
Povilas Korop avatar

Good catch, didn't think of that validation.

Chris McGee avatar

What would be the best way to implement such validation?

👀 1
Nerijus avatar

In the repo it was inplemented, updated this lesson with the code.

Karolis avatar

$parkingData validation section exists has table vehicles and the column deleted_at. Need to update migration/ model files to add softDelete.

Elmar Cabbarlı avatar

I think you put the wrong screenshot "We launch this endpoint with success!" (after this sentence)

Povilas Korop avatar

Thanks, another well spotted mistake, changed to the correct screenshot. It's so good to see people actually READ the content :)

👍 1
Elmar Cabbarlı avatar

you forgot to add "id" in ParkingResource.php

return [ 'id' => $this->id, ...

Povilas Korop avatar

Well spotted! Fixed now.

vilyo avatar

Is there difference if we register an observer in AppServiceProvider rather than EventServiceProvider (as in Laravel docs) like you did for Vehicle and Parking observers?

Povilas Korop avatar

No difference, any Service Provider is fine.

Huy Nguyen avatar

Regarding

Route::get('parkings/{parking}', [ParkingController::class, 'show']);
Route::put('parkings/{parking}', [ParkingController::class, 'stop']);

Would it be better it we add these constraints for these routes?? Like this

Route::get('parkings/{parking}', [ParkingController::class, 'show'])->whereNumber('parking')
Route::put('parkings/{parking}', [ParkingController::class, 'stop'])->whereNumber('parking')
👍 3
Povilas Korop avatar

Yes I think it's a good suggestion, great comment.

fatima zohra ezzaidani avatar
fatima zohra ezzaidani

hi, After creating this : 'exists:vehicles,id,deleted_at,NULL,user_id,'.auth()->id(), for validation Rule, when runing postman , I have this issue: Column not found: 1054 Unknown column 'deleted_at' in 'where clause' (SQL: select count(*) as aggregate from `vehicles`
I need to create deleted_at colum in the parking migration ?

Povilas Korop avatar

Pretty sure it was created earlier, with $table->softDeletes();

👍 1
Márlon avatar

Hello! It is ok in the repository, but in the text lesson, not was created.

Povilas Korop avatar

Oh right, I see it now. Fixed in the lesson, thanks for the notice!

fatima zohra ezzaidani avatar
fatima zohra ezzaidani

Hi Povilas, I think 'stop_time' => $this->stop_time?->ToDateTimeString(), the ? dont fixe my problem about parse null toDateTime.. this is what postman said: "message": "Call to a member function ToDateTimeString() on null",

but it work on database!

Povilas Korop avatar

Weird, it did for me. Well, you can rewrite it with if-statement or ternary then, try something like $this->stop_time->toDateTimeString() ?? null or if-statement

👍 1
fatima zohra ezzaidani avatar
fatima zohra ezzaidani

Yeah I fix it using Carbon, thank you Povilas!

kaitrenbath avatar

It looks like you're using the local scope Parking::active() when checking if there's an active parking in the controller but it's not been added to the model in any previous steps.

Povilas Korop avatar

Well noted, thanks! Weird, in the repository scopes are here but perhaps forgot to add them to the lesson text itself. Fixed now!

Cesar Schefer avatar

If you stop an already stopped parking, it will always update the stop_time. One possible solution would be to apply the scopeStopped (declared but not used) similarly to the scopeActive in start parking.

Cesar Schefer avatar

Well, someone noticed the same in the next video :)

Luis Antonio Parrado avatar
Luis Antonio Parrado

Hi Povilas, The syntax

'exists:vehicles,id,deleted_at,NULL,user_id,'.auth()->id(),

applied in ParkingController.php validation calls my attention and i need some explanation.

Why can I use so many parameters separated by commas?, in the documentation is not clear to me.

David Lun avatar

This translates to:

value provided exists on vehicles table id column AND deleted_at column has value NULL AND user_id is of currently authenticated user

so you can request to start parking for car you own that is not deleted otherwise request would be invalid

Luis Antonio Parrado avatar
Luis Antonio Parrado

Are they any way more readable to write this line, using for example the Rule class? I have saw something like

Rule::exists('vehicles')->whereNull('deleted_at') . .
;
IsaiasXavier avatar

I have edit the

if (Parking::active()->where('vehicle_id', $request->vehicle_id)->exists())

to

if (Parking::active()->where('vehicle_id', $request->vehicle_id)->whereNull('stop_time')->exists())

to allow the user to park with the same vehicle more than once only after checking out.

augusto-dmh avatar

Why do we are checking for authentication in the observers if they're only executed on context where there's always an authenticated user? (Parking creation only happens in this context: accessing the endpoint '/parking/start' unauthenticated results in authentication error).

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.