Eloquent relationship - whereNotNull does not exist - laravel

I have a relationship in Eloquent that I'm trying to query.
$deliveryOverride = $product->days->whereNotNull('margin')
->where('price_id', $order['price_id'])
->where('product_id', $product->id)
->where('sale_at', date('Y-m-d', strtotime($day)))
->first();
I keep getting the the error
Method whereNotNull does not exist.
Any ideas?

When you call a relation property directly on an Eloquent object, the query is executed and a Collection is returned. There is no WhereNotNull function on collections.
If you want to query the relation using that function, you will have to call the relation function directly. This will also be better for performance as the query will happen on the database.
$deliveryOverride = $product->days() // Call relation function here
->whereNotNull('margin')
->where('price_id', $order['price_id'])
->where('product_id', $product->id)
->where('sale_at', date('Y-m-d', strtotime($day)))
->first();
More information about this can be found in the documentation right here: https://laravel.com/docs/5.7/eloquent-relationships#querying-relations

Related

Laravel 7 Query with() and using Where()

Hey guys I have a query that looks like this
$query = Transaction::with(['customer', 'merchant', 'batch'])
->select(sprintf('%s.*', (new Transaction)->table));
I need to filter the transaction based on the iso_id that belons to the current user logged in.
$query = Transaction::with(['customer', 'merchant', 'batch'])
->select(sprintf('%s.*', (new Transaction)->table))
->where('merchant.iso_id', '=', auth()->user()->isIso());
The iso_id I need to compare to, is inside the merchant table
auth()->user()->isIso() returns the correct iso_id if true or sends false if not
So my first try at this was to use where('merchant.iso_id', '=', auth()->user()->isIso())
But that returns that the column does not exist because for some reason, it's not switching from the transaction model to the merchant one.
I am not sure how to use the stuff inside with() as a selector for my where()
Any help would be appreciated!
Try using whereHas to add the constraint:
$query = Transaction::with(['customer', 'batch'])
->whereHas('merchant', function ($q) {
$q->where('iso_id', auth()->user()->isIso());
})
->select(sprintf('%s.*', (new Transaction)->table))
->get();

Laravel eager loading with value of current model?

Hi guys is it possible to do this in an eager loading?
Client::with(['relationship' => function($query){
$query->whereBetween('created_at', [$client->failed_date, Carbon::now()->endOfDay()])
}])->get();
Basically I want to put the failed_date column from my CLIENT model into the eager loading query.
Since all types of Eloquent relationships are defined via methods, you may call those methods to obtain an instance of the relationship without actually executing the relationship queries. In addition, all types of Eloquent relationships also serve as query builders, allowing you to continue to chain constraints onto the relationship query before finally executing the SQL against your database.
For example.
$clients = Client::where('status', 1)->get();
foreach($clients as $client) {
$relationships = $client->relationship()
->whereBetween('created_at', [$client->failed_date, $client->pass_date]);
}
This way you can solve your problem.
If you're trying to eagerly load your relationships, As eager load will perform a separate query you don't have direct access to the parent table, so you need to join it.
public function relationship()
{
return $this->belongsTo(Client::class)
->selectRaw('clients.*')
->join('relationships', 'clients.id', '=', 'relationships.client_id')
->whereRaw("....");
}

how to get list of users who are not under belongsToMany relation under a table in laravel?

Consider the following case.
we have the Users table and Tasks table. they are in relation with belongsToMany with table task_user.
How to get the list of all users who are not under any task? i.e. their user_id is not at all under that given task or even in the task_user table.
why I need this is because like this we can only provide a list of users who are yet to be assigned a task. the task will be assigned to users and not a single user at a time.
Editing_____________
also how to filter with users based on group table? below is not working
$users = Group::with(['subscribers' => function ($q){
$q->doesntHave("tasks");
}])->whereId($gid)->latest()->get();
Assuming you've named your relationships properly, you should be able to use doesntHave("tasks"):
$tasklessUsers = User::doesntHave("tasks")->get();
doesntHave() checks for the non-existence of the supplied relationship ("tasks", in this case) and returns all objects that pass this check.
If your function name is different, use that, but the relationship should be:
User.php:
public function tasks(){
return $this->belongsToMany(Task::class, "task_user");
}
Edit: doesntHave() is the simple version, whereDoesntHave() allows a custom query. See https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-absence for full details.
Second Edit:
As stated in the comments below, with() will not filter the Model it is being called on, so this query won't work as you'd expect:
$users = Group::with(['subscribers' => function ($q){
$q->doesntHave("tasks");
}])->whereId($gid)->latest()->get();
To fix this, use a chained doesntHave() query:
$query = Group::doesntHave('subscribers.tasks')
->where('id', '=', $gid)
->latest()
->first();
// OR
$query = Group::whereHas('subscribers', function($subQuery){
$subQuery->doesntHave('tasks');
})->where('id', '=', $gid)
->latest()
->first();
$users = $query->subscribers; // Return `users` (aliased to `subscribers`)
Either approach will check the existence of subscribers that don't have any associated tasks relationship, and also only return where id is $gid.
Note: Used first() for the queries, as using id in a query should only ever return a single Group record, and get() is for returning multiple records in a Collection

Laravel isNotEmpty() not working on Eloquent model

I'm probably confused by Eloquent (again...) but I thought that this should work:
$test_row = Test::
where('status', 'active')
->where('condition2', 'value')
->orderBy('order', 'asc')
->first();
if($test_row->isNotEmpty())
return $test_row;
But is it throwing the following error: Call to undefined method App\Test::isNotEmpty().
By using first() it will return an Eloquent model right? And isNotEmpty(), as well as isEmpty(), should be able to be used on the returned model?
You are trying to call isNotEmpty() on a model object and not a collection, when you use first() it returns an object not a collection.
Use
if($test_row)
{
return $test_row
}
The method isNotEmpty() is actually returned by Laravels Collection class and not by an Eloquent model. Since you're not asking for multiple results, only the model is returned instead of a collection.
Simply use
if ($test_row) {
return $test_row;
}
to check if the query had any results and the model exists.

Query if relation is defined before whereHas

Consider the following eloquent model:
$itemModel->whereHas('location.country', function($q2) use ($value){
$q2->where('id', $value);
});
When I run this, I get an (expected) exception saying
Call to undefined method Illuminate\Database\Query\Builder::country()
Is there any way I can check the existence of this relation before I execute the whereHas query?
That's not the correct way to use whereHas, multiple relations in the query is for eager loading.
You can try :
$item->whereHas('location',function($query) use ($value){
$query->whereHas('country')->where('id',$value);
});
Relations nesting was not implemented for whereHas

Resources