Hi @hjortur17
You should take a look to querying for relationship presences and how to constrain it:
https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence
Basically you need to use ->whereHas()
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hi, is it possible to have a where clause on belongsToMany relationship? I want to only get the Bookings associated with services that have the category garage.
So what I'm trying to do is: Bookings where services->category = garage
Here is my SQL right now:
$today = Carbon::now()->format('d/m/Y');
$garageToday = Booking::where('booking_type', '=', 'service')
->where('dropOffDate', '=', $today)
->orderBy('dropOffTime')
->with('services')
->get();
Hi @hjortur17
You should take a look to querying for relationship presences and how to constrain it:
https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence
Basically you need to use ->whereHas()
@hjortur17 something like this maybe:
$garageToday = Booking::where('booking_type', '=', 'service')
->where('dropOffDate', '=', $today)
->whereHas('services', function($query) {
$query->where('category', 'like', 'garage');
})
->orderBy('dropOffTime')
->with('services')
->get();
hope this helps!
@hjortur17 this should do it.
$today = Carbon::now()->format('d/m/Y');
$garageToday = Booking::with('services')
->where('booking_type', 'service')
->where('dropOffDate', $today)
->whereHas('services', function (Builder $query) {
$query->where('category', 'garage');
})
->orderBy('dropOffTime')
->get();
@hjortur17 This should get you close.
// Quick tip: you can just use the now() helper without Carbon::
$today = now()->format('d/m/Y');
$garageToday = Booking::where('booking_type', '=', 'service')
->where('dropOffDate', '=', $today)
->orderBy('dropOffTime')
->with('services')
->whereHas('services', function (Builder $query) {
$query->where('category', 'garage');
})
->get();
It seems we all have been writing almost at the same time this time :D
@marianomoreyra lol, yep! =)
@fylzero I guess you have ran out of lessons to watch :P Have you any more to go as I see you are well into 1800..
@automica lol, facts. I've been in the habit of watching everything at 1.5x speed (or faster) when videos/series hit the What's New page. Been pretty into to this site/Laravel for a while now.
@fylzero Ive been mining the archive for interesting series. Even the old stuff is still good learning
@automica how do you browse the archive this days?
I was trying to find an old lesson but can't find that filter anymore and some really old lessons are not showing in the search results page anymore.
For example I have these two series links saved as I learned a lot from them and still recommend to people:
https://laracasts.com/series/build-a-laravel-app-from-scratch ( The Larabook series )
https://laracasts.com/series/build-project-flyer-with-me
Those links work, one can watch all the episodes, but when I search for any episode title or description from these two series I get no results.
I remember being able to search for archived series, or at least find them, until last year, but I no longer know how to do it.
I was after an old series on building and API, although it might be very outdated Laravel-wise, I remember it had some great explanations on how some stuff worked and recommendations on how you should organize it. I wanted to recommend to some fellow programmer but can't find it anymore.
If you know where to find them, please share. Thanks in advance.
I even tweeted @JeffreyWay about this back in April, but I didn't here back from him.
Of course I know he might have a very busy twitter timeline to deal with.
And maybe keeping the archives easy to browse is time and resource consuming.
But would be nice if thee is a way to browse the archive again...
Go to the user menu at the top right and click search. That pulls up a filterable page for all courses on the site.
Thanks @fylzero , I am aware of that.
It leads to this this page, right?
If you compare the home page stats, its says there are 1831 lessons, but when you visit that search page its sidebar shows 1265 lessons under the "Lesson Type" filter group. Both figures as of I am writing this response.
So there are around 560+ lessons not able to be filtered. Those are the ones I am referring to.
Try searching for any of Larabook series' lessons I linked before, they don't show up at that search page. Also, from memory, the first ever lesson was from 2014, now the earliest lesson if you scroll way down is from 2016.
Until earlier this year I could browse those archived series and lessons, I noticed for the first time in April this year I could not find them anymore.
If I am doing anything wrong, or if you know a different page to browse them, please let me know. I remember there there was a /library page, or something similar, but I can't access that anymore.
Thanks in advance.
By the way this is the API series I was trying to find:
https://laracasts.com/series/incremental-api-development
Found it on a Google search.
Although Laravel changed a lot from that series and added features to make some of the tasks outlined there easier, the way @jeffreyway explains some API concepts in that series makes it still worth watching in my opinion.
Let me know if you know how to find those archived series without resorting to searching Google.
Thanks again!
An alternative could be joins, which are faster than whereHas.
The whereHas is not working. Here is what I'm trying:
I added this column to the services table called servicing, so I'm trying to get all Bookings which has a service with the servicing column set to cleaning.
$cleaningToday = Booking::where('booking_type', 'service')
->where('dropOffDate', $today)
->orWhere('booking_type', 'storage')
->where('dropOffDate', $today)
->whereHas('services', function (Builder $query) {
$query->where('servicing', 'cleaning');
})
->orderBy('dropOffTime')
->with('services')
->get();
when you say 'not working' what do you mean?
@hjortur17 Additional to @automica question, please share the bookings and services migrations, as well as some sample data from both tables.
Ideally, it would help if you can show those sample records along with the expected result from your query.
Sorry. So I have two bookings in my bookings table. Both of them have the booking_type = service, but the first one has associated service with servicing = garage and the second one has the servicing = cleaning.
This code is giving me both of these bookings but I'm only trying to get that one with servicing = cleaning.
Here is my migration:
Schema::create('bookings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedMediumInteger('user_id')->nullable();
$table->string('name');
$table->string('email');
$table->string('phone');
$table->string('carNumber');
$table->string('carSize');
$table->string('dropOffDate');
$table->string('dropOffTime');
$table->string('pickUpDate')->nullable();
$table->string('pickUpTime')->nullable();
$table->string('numberOfDays')->nullable();
$table->boolean('send_bill')->nullable();
$table->string('companyName')->nullable();
$table->string('companyId')->nullable();
$table->string('discountUsed')->nullable();
$table->string('discountValue')->nullable();
$table->string('discountPrice')->nullable();
$table->string('priceForServices');
$table->string('priceForStorage');
$table->unsignedMediumInteger('price');
$table->boolean('paid')->default(0);
$table->string('korta_authcode')->nullable();
$table->string('cardbrand')->nullable();
$table->string('card4')->nullable();
$table->boolean('accepted_terms');
$table->string('booking_type');
$table->string('randomKey')->unique();
$table->timestamps();
});
Schema::create('services', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('carSize');
$table->string('title');
$table->string('category');
$table->integer('price');
$table->boolean('visible');
$table->string('servicing');
$table->timestamps();
});
Schema::create('booking_service', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('booking_id');
$table->unsignedBigInteger('service_id');
$table->timestamps();
$table->unique(['booking_id', 'service_id']);
});
Use the same filter for eager loading.
$cleaningToday = Booking::with(['services' => $closure = function ($query) {
$query->where('servicing', 'cleaning');
}])->where('booking_type', 'service')
->where('dropOffDate', $today)
->whereHas('services', $closure)
->orderBy('dropOffTime')
->get();
Quick question, do any of you have an idea of how I can use my code better? I'm copy-pasting on for different places, always the same code only difference is two attributes.
This is what I am repeating:
Booking::with(['services' => $closure = function ($query) {
$query->where('servicing', 'garage')
}])
->where('booking_type', 'service')
->where('dropOffDate', $today)
->whereHas('services', $closure)
->orWhere('booking_type', 'storage')
->where('dropOffDate', $today)
->whereHas('services', $closure)
->orderBy('dropOffTime')
->get();
You can use scopes
@michaloravec - I don't understand how I would move my query over to this scope. This is what I'm trying, but I'm getting this error Undefined variable: type
public function scopeOfType($query, $type, $day)
{
return $query->with(['services' => $closure = function ($q) {
$q->where('servicing', $type);
}])
->where('booking_type', 'service')
->where('dropOffDate', $day)
->whereHas('services', $closure)
->orWhere('booking_type', 'storage')
->where('dropOffDate', $day)
->whereHas('services', $closure)
->orderBy('dropOffTime');
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Booking extends Model
{
public function scopeOfService($query, $servicing, $today)
{
return $query->with(['services' => $closure = function ($query) use ($servicing) {
$query->where('servicing', $servicing);
}])->where('booking_type', 'service')
->where('dropOffDate', $today)
->whereHas('services', $closure)
->orderBy('dropOffTime');
}
}
Then you use it like this
$cleaningToday = Booking::ofService('cleaning', $today)->get();
The name of scope you can use what you want, just for example I used ofService
You forget to use use to pass variables from parent scope
Thanks alot! Much cleaner code
Please or to participate in this conversation.