How to compare on Laravel pivot amounts with table column - php

I am really stuck with this.
I have a Many to Many relationship with Actors and Works. I need to get all the works that don't have all the actors they need. The actors needed per work is a property on the Works table called "extras_needed"
So far I've tried withCount, but you can't use it on a where. This is the closest thing I have which is:
$works = $works->has('actors','<','extras_needed');
But its trying to use extras_needed as a string and I need it to treat it as the column per se.
Any advice? Thanks in advance

You'll want to use DB::raw:
Sometimes you may need to use a raw expression in a query.
Armed with this, we can turn your query into:
$works = $works->has('actors', '<', \DB::raw('extras_needed'));
Hope this helped!

Related

How to query whereIn inside json column in laravel 5.3?

I have been working with a laravel 5.3 version and in a table i have a json column where i have saved average rating of a category table.
so, A product category table has a column "detail" as a json data type which saves avgRating.
I want to run a query inside that json column. And i want to filter that category with a average rating. So, from the frontend side rating comes in a parameter with a comma seperated so that category can be filtered with multiple ratings.
$productCategory = ProductCategory::query();
$ratings = explode(',',$params['ratings']);
$productCategory = $productCategory->whereIn('detail->avgRating',$ratings)->get();
I want to achieve something like this.
I am using Postgres
It turns out that there was too much uncertainty at the time when the question was asked. Once the asker separated the problems and figured out that the raw query of
DB::select(DB::raw("SELECT * FROM product_categories where detail->>'avgRating' in ('2.0','4.0')"));
works in Postgres, the asker from that point onwards had a much easier time figuring out the actual solution in the where clause. I presuppose that it was
detail->>avgRating
instead of
detail->avgRating
but from the comment section that was not yet confirmed. But the moral of the story is that whenever one has an eloquent problem that might be related to the RDBMS, then it makes a lot of sense to first sort out the raw query and then, having solid knowledge about what should be generated, at that point one can switch to the Eloquent code and apply the solution there.
You should use whereJsonContains or whereRaw:
$productCategory->whereJsonContains('detail->>avgRating',$ratings)->get();
OR
$productCategory->whereRaw('JSON_CONTAINS(detail->>avgRating, ?)', $ratings)->get();

How to get the column value inside relation outof the relationship in laravel

Below is my code.
DB Code
return $this->model
->select('orderNumber','orderNumber as order_id','orderDate as order_date','status')
->where('orderNumber','=',$id)
->with(array('OrderDetail'=>function($query){
$query->select('productCode','orderNumber','priceEach as unit_price',DB::raw('quantityOrdered*priceEach as line_total'));
}))
->with('customer')
->first()->makeHidden(['orderNumber']);
I want to get the sum of the line_total column and it should be displayed under the order section as in the below image..
JSON Payload
DB Table Design
DB Table Design
I tried many ways, but could not achieve the expected outcome.
So your help is really appreciated.. :)
What you can do is you can add a select in main query like this:
->addSelect(['order_total' => DB::table('order_items')->whereRaw('order_items.order_id = orders.id')->sum('priceEach')]);
I hope this helps, let me know if you need something else.

Comparing columns in laravel

Sorry in advance for inappropriate question.I am a beginner in php and laravel. Wondering where i am doing mistake in the following code fragment.
$customer_vlan = Customer::select('vlan_id')->get();
$vlans = Vlans::where(function($query) use ($customer_vlan){
$query->where('id','!=',$customer_vlan);
})->get();
I have two tables in database."Customer" table has a column 'vlan_id'. In first query i am trying to fetch used vlan_id.
For second table "Vlans", column'id' holds all possible vlan. So i am trying to find which vlan's not used.
You are trying to compare id with a collection. Then the result is all of the Vlans.
$query->where('id','!=',$customer_vlan);
I think the best way to do this is loop through $customer_vlan collection and push $customer_vlan[$i]->id to an array. Then you can use this:
$query->whereNotIn('id', $arrayOfId);

Laravel inRandomOrder repeat twice with pagination

I have the code:
$products = Product::whereIn('id_principal_category', $array)->inRandomOrder()->paginate(6);
It sometimes shows me a repeated record.
I have read that I must use whereNotIn, the problem is that it can work if it just one time... but how can i do that if does it have a paginator? because i dont know which the repeated records are and i cant use whereNotIn.. so my question is how can I do that inRandomOrder does not show a repeated record with paginator?
Thanks
See if unique() method helps.
$products = Product::whereIn('id_principal_category', $array)->unique()->inRandomOrder()->paginate(6);
You can't use random ordering with pagination ,mysql cannot track the rows for each visitor .
I quoted those lines from Chris Henry's answer
Solution 1
Pick from a number of existing columns that already indexed for being sorted on. This can include created on, modified timestamps.
Solution 2
You could have an additional column that stores a random number for sorting. It should be indexed, obviously. Periodically, run the following query;
UPDATE table SET rand_col = RAND();

Logic in getting users that is not a member of the group

What kind of logic is behind getting a list of users that is not a member of the selected group.
Or get a list of users that is not in my contacts list.
Using laravel I have came up with a code.
The code:
// I get all the uid of the members of the user group.
$members_list = GroupMembers::where('group_id', $group_id)->lists('uid');
// I compare it to the list of all users and get those that are not in the list
$nonMembers = Users:whereNotIn('uid', $members_list)->paginate(10);
But is this the most efficient way of doing it?
I'm not sure it really matters too much because they are both pretty simple queries so they shouldn't take too long. It would probably take some experimenting to figure out which way is the fastest if you are really concerned about performance.
Here is a way you can do it using the query builder and table joins. This will use one query, but because it's joining, it will probably take just about the same amount of time as using what you have already. Also note that this won't allow you to traverse the collections like you usually would ($user->group->name for example would just become $user->name, which if there is a name column on your users table, something may get overwritten)
$users = DB::table('group_members')
->join('users','users.uid','=','group_members.uid')
->where('group_members.group_id', '<>', $group_id)
->paginate(10);
What you are doing now is pretty much exactly what eager loading is doing, except you are doing it by hand. The correct way to do this is as follows and is probably your best solution, though it probably won't save you anything on performance.
$users = User::with(array('groupMembers' => function($query) use ($group_id)
{
$query->where('group_id', '<>', $group_id);
}))->paginate(10);
definitely not that best..
Assuming the relationship is
Group members->has many->Users
you could to to use joins
DB::table('group_members')
->join('users','group_members.uid','<>','users.uid')

Categories