facing difficulty on implementing "groupBy" method in laravel - laravel

I am trying to fetch data using groupBy method in laravel, but it's returning all data. what I am trying to get is
lets there are 2 tables
Table 1 : variants
id variant
1 color
2 size
Table 2: product_variants
color variant_id
red 1
yellow 1
red 1
sm 2
xl 2
lg 2
Now I want to fetch data so it returns as follow:
variant_table: {
id:1,
variant: color,
variants: {
variant_id: 1,
color:red
},
{
variant_id: 1,
color:yellow
}
},
{
id:2,
variant: size,
variants: {
variant_id: 2,
color:sm
},
{
variant_id: 2,
color:lg
},
{
variant_id: 2,
color:xl
}
}
But I am getting all variants instead of distincts grouped by variant_table id, My code:
$productVariants = ProductVariant::with('productVariants')
->whereHas('productVariants',function ($q) {
$q->groupBy('variant_id');
})
->get();

let suppose the model of product_variants table is ProductVariant
let suppose the model of variants table is Variant
let suppose the in model ProductVariant the relation function name is variant()
$product_variants = ProductVariant::with('variant')->groupBy('variant_id')->get();
try this $product_variants = ProductVariant::with('variant')->get()->groupBy('variant_id');
if it does not work than config\database.php --> "mysql" array
Set 'strict' => false

Related

Laravel - Assert json array ids using wildcard

In my application I have a response like this:
{
"items": [
{
"id": 10,
"field": "foo"
},
{
"id": 20,
"field": "bar"
}
]
}
I need to test the content of items and validate each id.
I've tried many solutions but no one works, for example (this is just a kind of pseudo-code):
assertJson(fn (AssertableJson $json) =>
$json->where('items.*.id', [10, 20])
)
Is there a way to use a wildcard to pick every ID and validate using an array?
You can use array_filter:
$idArray = [10, 20];
$myObj = json_decode($json); // Turn JSON to obj
$items = $myObj["items"]; // Get items from object
// Filter the items for items that aren't in the ID list
$invalidItems = array_filter($items, function ($el) {
// If the item has an id which isn't in the array, return true
return !in_array($el["id"], $idArray);
});
// This returns true if we found 0 items with IDs not in the ID list
return $invalidItems == [];
You can similarly use array_map to simplify your array, then compare it to your ID array:
$myObj = json_decode($json); // Turn JSON to obj
$items = $myObj["items"]; // Get items from object
$outIdArray = array_map(function($el) {
return $el["id"];
}, $items);
// Compare $outIdArray to [10, 20]
Not tested yet but below should work.
We attach an each on each child element under items and add a callback to where on that id key of each child.
<?php
assertJson(fn (AssertableJson $json) =>
$json->each('items', fn (AssertableJson $childJson) =>
$childJson->where('id', fn($idVal) =>
in_array($idVal, [10,20])
)
)
)

Laravel - How to combine multiple queries as one Eloquent Query

In my Laravel-5.8, I have these four queries accessng the same model:
$allLeaves = HrLeaveRequest::where('company_id', $userCompany)->whereYear('created_at', date('Y'))->count();
$pendingLeaves = HrLeaveRequest::where('leave_status', 1)->where('company_id', $userCompany)->whereYear('created_at', date('Y'))->count();
$rejectedLeaves = HrLeaveRequest::where('leave_status', 3)->where('company_id', $userCompany)->whereYear('created_at', date('Y'))->count();
$approvedLeaves = HrLeaveRequest::where('leave_status', 4)->where('company_id', $userCompany)->whereYear('created_at', date('Y'))->count();
How do I combine the four queries as one
something similar to this
$gender_unpublished_record = HrEmployee::selectRaw('count(gender_code) as count,gender_code, if (gender_code = 1, "Male", "Female") as gender')->whereNotIn('employee_code', $publishedgoals)->where('company_id', $userCompany)->where('hr_status', 0)->groupBy('gender_code')->get();
The one above only have 0 or 1. But what I want to achive takes care of everything in the table, leave_status as 1, 3 and 4
Thank you
in your Company Model you should have the relation:
public function HrLeaveRequests()
{
return $this->hasMany(HrLeaveRequest::class,'company_id');
}
now you could use withCount:
$value=Company::where('company_id',$userCompany)->withCount(['HrLeaveRequests as allLeaves'=>function($query){
$query ->whereYear('created_at', date('Y'));
},
'HrLeaveRequests as pendingLeaves'=>function($query){
$query->where('leave_status', 1)->whereYear('created_at', date('Y'));
},
'HrLeaveRequests as rejectedLeaves'=>function($query){
$query->where('leave_status', 3)->whereYear('created_at', date('Y'));
},
'HrLeaveRequests as approvedLeaves'=>function($query){
$query->where('leave_status', 4)->whereYear('created_at', date('Y'));
},
])->get();

How to query from two elasticsearch indexes with one query

Newbie here. I have two indexes: /items and /categories that contain data similar to this:
#Items:
{ id:1, name: "banana", categories: [1] },
{ id:2, name: "coconut", categories: [1] },
{ id:3, name: "smoothie", categories: [1, 2] }
#Categories
{ id:1, name: "Apple" },
{ id:2, name: "Banana" }
I want to create a query with bana as a query string and I should return items 1 and 3. It should not return category objects. ID 1 because of the name match and ID 3 because it has a category that has a name match.
How could a query like this be constructed?
My current query does not return item 3 and simply like
GET /items/_search
{
"query": {
"bool":{
"must":{
"query_string":{
"query":"bana"
}
}
}
}
}
Is it necessary to create two indexes for this? maybe use name directly in Item index to replace id:
{ id:1, name: "banana", categories: ["Apple"] }
Since index will have its own dictionary, will not cause extra disk space.
if really need to join two indexes, maybe you want to try Parent-Child Relationship, but it will deprecated in future, and replaced by: join datatype, this way also will keep data in one index.

Laravel 5.5 - Merge 2 collections into one based on id?

So I have 2 models Books and Classes:
$books = Books::limit(3)->get(['id','classable_id','easy_book']);
// Books returned:
{ id: 200,
classable_id: 2,
easy_book: false
},
{ id: 201,
classable_id: 3,
easy_book: true
},
{ id: 202,
classable_id: 4,
easy_book: false
}
$classIds = $books->pluck('classable_id');
$classes = Classes::whereIn('id', $classIds);
// Classes returned:
{ id: 2,
subject: Math,
students: 30
},
{ id: 3,
subject: History,
students: 30
},
{ id: 4,
subject: Physics,
students: 30
}
Then trying to get the following output (without combining the queries, but keeping them separate like above, and just using php logic to output):
Classes returned:
{ id: 2,
subject: Math,
students: 30.
easy_book: false }, // trying to merge this!
{ id: 3,
subject: History,
students: 30.
easy_book: true}, // trying to merge this!
{ id: 4,
subject: Physics,
students: 30.
easy_book: false } // trying to merge this!
Basically, I am trying to merge the easy_book field from books returned to the respective class returned based on class.id == books.classable_id. Any idea how to merge it?
Add a relationship to your Books model like so:
public function class() {
return $this->belongsTo(Classes::class, 'id', 'classable_id);
}
Then you can do:
Book::with('class')->select('id', 'classable_id', 'easy_book')->limit(3)->get();
Each collection item will then have a collection of classes where applicable.
If after that you want to manipulate them, you can use the map function as documented here: https://laravel.com/docs/5.7/collections#method-map

RethinkDB get all and order with index

I have an object like this:
Company {
Enable bool
Pro bool
Type int
Categories []int
}
So, how can I make query to retrieve all objects that Enable=true, Categories contains, for example, "1" and order by Pro and Type.
I have more than 200,000 records so I have to to that efficient with indexes.
I try to use this:
r.db("test_main").table("companies").indexCreate("ListAll", function(comp) {
return comp("Categories").map(function(cat) {
return [ comp("Pro"), comp("CompType"), comp("Enabled"), cat ];
});
}, {multi: true})
r.db("test_main").table("companies").between([false, 0, true, 1],
[r.maxval, r.maxval, true, 1], {index:"ListAll"}).orderBy({index:r.desc("ListAll")}).limit(100)
But categories doesn't match.

Resources