Collection sum fo array of obj Laravel whit relation callback - eloquent

I try to figure it out to make the sum of all the levelAccess for a role.
this is my data:
{
"id": 1,
"uuid": "1fdc0660-1b0f-11e8-b9e8-b5c43c94fc8c",
"name": "admin",
"total_levelAccess": null,
"level_accesses": [
{
"id": 1,
"userRoleId": 1,
"levelAccess": 6,
"code": "location"
},
{
"id": 2,
"userRoleId": 1,
"levelAccess": 6,
"code": "business"
},
{
"id": 3,
"userRoleId": 1,
"levelAccess": 6,
"code": "account"
},
{
"id": 4,
"userRoleId": 1,
"levelAccess": 6,
"code": "review"
}
]
},
{
"id": 2,
"uuid": "1fdc2980-1b0f-11e8-a6e9-7934303e6543",
"name": "editor",
"total_levelAccess": null,
"level_accesses": [
{
"id": 5,
"userRoleId": 2,
"levelAccess": 6,
"code": "location"
},
{
"id": 6,
"userRoleId": 2,
"levelAccess": 2,
"code": "business"
},
{
"id": 7,
"userRoleId": 2,
"levelAccess": 2,
"code": "account"
},
{
"id": 8,
"userRoleId": 2,
"levelAccess": 6,
"code": "review"
}
]
}
This is my code :
$userRoleWithLevel = UserRole::with('levelAccesses')->get();
$userRoleWithLevel->map(function ($userRole) {
$$userRole->total_levelAccess = $userRole->level_accesses->sum(function ($levelAccesses) {
return $levelAccesses->levelAccess;
});
return $userRole;
});
and
$userRoleWithLevel->map(function ($userRole) {
$userRole->total_levelAccess = $userRole->level_accesses;
return $order;
});
I got an error
FatalThrowableError in ApiSystemController.php line 49:
Call to a member function sum() on null
I can't access to level_access.
I tried this answered
Laravel Sum a Collection with multiple items
we use Laravel 5.2
Please if somebody can help me.
my UserRole model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as Eloquent;
use App\Models\LevelAccess;
class UserRole extends Eloquent
{
public $timestamps = false;
protected $table = 'userRoles';
protected $connection = 'system';
protected $fillable = [
'uuid',
'name'
];
public function levelAccesses()
{
return $this->hasMany(LevelAccess::class, 'userRoleId','id');
}
// I try this but it doesn't work to.
public function sumlevelAccesses()
{
return $this->hasMany(LevelAccess::class,'userRoleId','id')
->selectRaw('SUM(levelAccess) as total_Level')
->groupBy('userRoleId');
}
}

After a while, I found what was wrought. It's $userRole->Level_accesses it's the under score.
$userRoleWithLevel->map(function ($userRole) {
$userRole->total_levelAccess = $userRole->*levelAccesses*->sum(function ($level_Accesses) {
return $level_Accesses->levelAccess;
});
return $userRole;
});
After that my result it's what i try to do.
[
{
"id": 1,
"uuid": "1fdc0660-1b0f-11e8-b9e8-b5c43c94fc8c",
"name": "admin",
"total_levelAccess": 24,
"level_accesses": [
{
"id": 1,
"userRoleId": 1,
"levelAccess": 6,
"code": "location"
},
{
"id": 2,
"userRoleId": 1,
"levelAccess": 6,
"code": "business"
},
{
"id": 3,
"userRoleId": 1,
"levelAccess": 6,
"code": "account"
},
{
"id": 4,
"userRoleId": 1,
"levelAccess": 6,
"code": "review"
}
]
}
]
Thank you #Jonas Staudenmeir

Related

How to insert data on last item of an inner array in MongoDB

I am trying to insert data in the last element of an array in MongoDB. insert in the first element works using the 0 operator, but I'm confused about how to insert in the last element. To explain it, consider the following data:
[
{
"_id": "1",
"company": "turivius",
"forms": [
{
"current_version": 1,
"history": [
{
"content": [],
"layout": [],
"responses": [
{
"client_id": 100,
"response_date": datetime(2022, 5, 17, 3, 0),
"values": [
{
"field_id": 0,
"primeiro user": "primeiro form, resposta 1",
},
{
"field_id": 1,
"value": "aaa",
},
],
},
{
"client_id": 100,
"response_date": datetime(2022, 5, 17, 3, 0),
"values": [
{
"field_id": 0,
"primeiro user": "primeiro form, resposta 2",
},
{
"field_id": 1,
"value": "bbb",
},
],
},
],
"version": 0,
},
{
"content": [],
"layout": [],
"responses": [
{
"client_id": 100,
"response_date": datetime(2022, 5, 17, 3, 0),
"values": [
{
"field_id": 0,
"primeiro user": "primeiro form, resposta 1 v1",
},
{
"field_id": 1,
"value": "aaa",
},
],
}
],
"version": 1,
},
],
"id": "33b66684-24a9-4a45-a12f-27a330152ac8",
"is_active": True,
},
{
"current_version": 0,
"history": [],
"id": "fa2eb9a1-c7c4-4b64-b682-7f51658bc4ab",
"is_active": False,
},
],
"user_id": "1",
},
{
"_id": "2",
"company": "turivius",
"forms": [
{
"current_version": 0,
"history": [],
"id": "565656",
"is_active": True,
},
],
"user_id": "9999",
},
]
I want to insert data in the document with user_id = 1, form.id = 33b66684-24a9-4a45-a12f-27a330152ac8 and in the history array where the version = 1 I want to insert a new response:
{
"client_id": 100,
"response_date": datetime(2022, 5, 17, 3, 0),
"values": [
{
"field_id": 0,
"test": "test",
},
{
"field_id": 1,
"test2": "test3",
},
],
}
The history with version 1 is the last element, if I wanted insert in the first element the following code would works:
find_one_and_update(
{"$and": [{"user_id": "1"}, {"forms.id": '33b66684-24a9-4a45-a12f-27a330152ac8'}]},
{
"$push": {"forms.$.history.0.responses": data_here},
},
return_document=ReturnDocument.AFTER,
)
Is there anyway to do it that way or I need a more complex query to do it?
You want to add a new document to the responses array when those conditions are true:
{
user_id: '1',
'forms.id': '33b66684-24a9-4a45-a12f-27a330152ac8',
'forms.history.version': 1
}
forms is an array, so you want to update the array element that matches the condition, so you can use the $[identifier] operator. Inside the array of forms, you only want to update the history with a specific version, so you need to use the $[identifier] operator multiple times, the field you want to update would be like this:
forms.$[f].history.$[h].responses
f is the identifier of each elements in forms that matches the condition and h the elements of the history array that match the other condition. An arrayFilters object is used to define the conditions.
The complete query could be like this:
db.collection.update({
user_id: "1",
'forms.id': '33b66684-24a9-4a45-a12f-27a330152ac8',
'forms.history.version': 1
},
{
$push: {
'forms.$[f].history.$[h].responses': {
"client_id": 100,
"response_date": "datetime(2022, 5, 17, 3, 0)",
"values": [
{
"field_id": 0,
"test": "test",
},
{
"field_id": 1,
"test2": "test3",
},
],
}
}
},
{
arrayFilters: [
{
'h.version': 1
},
{
'f.id': '33b66684-24a9-4a45-a12f-27a330152ac8'
}
]
})
Working example at MongoDB playground

RangeError (end): Invalid value: Only valid value is 0: 1 when generating model

Getting the error RangeError (end): Invalid value: Only valid value is 0: 1 when generating model when I try to generate model
Expected Behavior
when I use this command get generate model on match_details with assets/models/to_get/match_details.json
it should be creating a model inside the match_details folder with the fields inside the JSON file mentioned.
Current Behavior
When I try to do this I get the error RangeError (end): Invalid value: Only valid value is 0: 1 when generating model** when I try to generate model
Possible Solution
Am sure it is something about parsing the JSON file
More info
here is what the JSON file looks like
{
"success": true,
"details": {
"id": 22,
"date_time": "2022-04-12T20:00:00Z",
"home_team": {
"id": 69,
"home_strip": {
"id": 15,
"image": "/uploads/strip_5_0py3QXM.png"
},
"away_strip": {
"id": 16,
"image": "/uploads/WhatsApp_Image_2022-03-09_at_10.24.56_AM.jpeg"
},
"players": [{
"id": 47,
"is_cap": false,
"average_skill": 3,
"region": {
"id": 13,
"name_ar": "التجمع الخامس",
"name_en": "Fifth Settlement",
"state": {
"id": 8,
"name_ar": "القاهره",
"name_en": "Cairo"
}
},
"first_name": "Ezz El Din",
"last_name": "Karim",
"mobile": "01113481110",
"email": null,
"image": null,
"positions_ar": [{
"مدافع": 3
}],
"positions_en": [{
"CB": 3
}],
"basic_skills_ar": [{
"السرعة": 4
},
{
"تمرير الكرة": 3
},
{
"تسديد": 2
}
],
"basic_skills_en": [{
"speeding": 4
},
{
"Passing": 3
},
{
"shooting": 2
}
]
}],
"cap": {
"id": 46,
"is_cap": true,
"average_skill": 3,
"region": {
"id": 13,
"name_ar": "التجمع الخامس",
"name_en": "Fifth Settlement",
"state": {
"id": 8,
"name_ar": "القاهره",
"name_en": "Cairo"
}
},
"first_name": "Karim",
"last_name": "Garrana",
"mobile": "01113332257",
"email": "karim.garrana#gmail.com",
"image": null,
"positions_ar": [{
"مهاجم": 3
},
{
"مدافع": 4
}
],
"positions_en": [{
"ST": 3
},
{
"CB": 4
}
],
"basic_skills_ar": [{
"السرعة": 3
},
{
"تمرير الكرة": 3
},
{
"تسديد": 3
}
],
"basic_skills_en": [{
"speeding": 3
},
{
"Passing": 3
},
{
"shooting": 3
}
]
},
"average_skill": 3,
"points": 0,
"name": "كوبرا",
"league": 25,
"logo": "/uploads/9_IApeihR.png",
"region_ar": "التجمع الخامس",
"region_en": "Fifth Settlement"
},
"away_team": {
"id": 68,
"home_strip": {
"id": 14,
"image": "/uploads/strip_6.png"
},
"away_strip": {
"id": 13,
"image": "/uploads/strip_5.png"
},
"players": [{
"id": 46,
"is_cap": true,
"average_skill": 3,
"region": {
"id": 13,
"name_ar": "التجمع الخامس",
"name_en": "Fifth Settlement",
"state": {
"id": 8,
"name_ar": "القاهره",
"name_en": "Cairo"
}
},
"first_name": "Karim",
"last_name": "Garrana",
"mobile": "01113332257",
"email": "karim.garrana#gmail.com",
"image": null,
"positions_ar": [{
"مهاجم": 3
},
{
"مدافع": 4
}
],
"positions_en": [{
"ST": 3
},
{
"CB": 4
}
],
"basic_skills_ar": [{
"السرعة": 3
},
{
"تمرير الكرة": 3
},
{
"تسديد": 3
}
],
"basic_skills_en": [{
"speeding": 3
},
{
"Passing": 3
},
{
"shooting": 3
}
]
}],
"cap": {
"id": 45,
"is_cap": false,
"average_skill": 4,
"region": {
"id": 11,
"name_ar": "ميامى",
"name_en": "Miami",
"state": {
"id": 7,
"name_ar": "الإسكندرية",
"name_en": "Alexandria"
}
},
"first_name": "Ahmed",
"last_name": "Wagdi",
"mobile": "01207199086",
"email": "ahmed.w.amin#gmail.com",
"image": "/uploads/90f1e1c9-b430-4f9c-8347-a86be57f58676954964268664537546.jpg",
"positions_ar": [{
"مدافع": 5
}],
"positions_en": [{
"CB": 5
}],
"basic_skills_ar": [{
"تسديد": 5
},
{
"تمرير الكرة": 5
},
{
"السرعة": 5
}
],
"basic_skills_en": [{
"shooting": 5
},
{
"Passing": 5
},
{
"speeding": 5
}
]
},
"average_skill": 4,
"points": 2,
"name": "المنتقمون",
"league": 25,
"logo": "/uploads/6.png",
"region_ar": "التجمع الخامس",
"region_en": "Fifth Settlement"
},
"location": {
"id": 8,
"name_ar": "مدرسة الكابيتال",
"name_en": "Capital School",
"location": "30.014650515430546,31.4582347869873",
"region": 13
}
}
}

Magento 2: Store in array level 3 category using Rest API

I'm using REST API with Magento 2.2.3. Below you can see the JSON response when I try to get the category tree.
{
"id": 2,
"parent_id": 1,
"name": "Only Beauty",
"is_active": true,
"position": 1,
"level": 1,
"product_count": 0,
"children_data": [
{
"id": 1372323,
"parent_id": 2,
"name": "Cura della Pelle",
"is_active": true,
"position": 1,
"level": 2,
"product_count": 0,
"children_data": [
{
"id": 1372335,
"parent_id": 1372323,
"name": "Creme Idratanti Viso",
"is_active": true,
"position": 1,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1372377,
"parent_id": 1372323,
"name": "Taglie da Viaggio",
"is_active": true,
"position": 2,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1372535,
"parent_id": 1372323,
"name": "Detergenti Viso",
"is_active": true,
"position": 3,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1375522,
"parent_id": 1372323,
"name": "Struccanti",
"is_active": true,
"position": 4,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1375540,
"parent_id": 1372323,
"name": "Altri Prodotti per la Pelle",
"is_active": true,
"position": 5,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1375649,
"parent_id": 1372323,
"name": "Esfolianti & Scrubs",
"is_active": true,
"position": 6,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1375716,
"parent_id": 1372323,
"name": "Anti-Età",
"is_active": true,
"position": 7,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1375816,
"parent_id": 1372323,
"name": "Prodotti per Cura Occhi",
"is_active": true,
"position": 8,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1375930,
"parent_id": 1372323,
"name": "Maschere & Esfolianti",
"is_active": true,
"position": 9,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1376342,
"parent_id": 1372323,
"name": "Prodotti Pelle per Uomo",
"is_active": true,
"position": 10,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1376883,
"parent_id": 1372323,
"name": "Creme da Notte",
"is_active": true,
"position": 11,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1486731,
"parent_id": 1372323,
"name": "Controllo Acne e Macchie della Pelle",
"is_active": true,
"position": 12,
"level": 3,
"product_count": 0,
"children_data": []
}
]
},
{
"id": 1372324,
"parent_id": 2,
"name": "Fragranze",
"is_active": true,
"position": 2,
"level": 2,
"product_count": 0,
"children_data": [
{
"id": 1372341,
"parent_id": 1372324,
"name": "Per Lui",
"is_active": true,
"position": 1,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1372347,
"parent_id": 1372324,
"name": "Per Lei",
"is_active": true,
"position": 2,
"level": 3,
"product_count": 0,
"children_data": []
},
{
"id": 1372583,
"parent_id": 1372324,
"name": "Unisex",
"is_active": true,
"position": 3,
"level": 3,
"product_count": 0,
"children_data": []
}
]
}
I need to store in array the ID of all level 3 subcategory using rest API request.
I tried to get ID using the following code:
$authToken = getToken();
$cat = getCategory( $authToken );
foreach ( $cat["children_data"] as $key => $row ) {
if ( $row["level"] == 3 ) {
$array_cat[] = $row["id"];
}
}
This is the API request function:
function getCategory( $token ) {
$ch = curl_init( "https://www.onlybeauty.shop/rest/V1/categories/" );
curl_setopt_array( $ch, array(
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Bearer '.$token,
),
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0
));
$response = curl_exec( $ch );
if( $response === FALSE ) {
die( curl_error( $ch ) );
}
$responseData = json_decode( $response, TRUE );
return $responseData;
}
Seems that this code works only for level 2 subcategory.
Thanks in adv.
Your code works only for level 2 because you need to go deeper in the "array-tree" of decoded json categories response.
Meaning your foreach procedure should be something like this:
$my_data = json_decode($my_json, 1);
print_r($my_data);
$level2_cat = $my_data["children_data"];
foreach($level2_cat as $key=>$row){
print_r($row["children_data"][0]["level"]);
}
Just tried an example with a sample of your json and with this you print the level of the third level category. Hope it helps

Postgresql json query

I have one table with one column jsonb with the text:
[
{
"id": 1,
"nome": "AUTOMÓVEL",
"partes": [
{
"fracao": 100,
"documento": "111.111.111-11"
}
],
"atributos": [
{
"id": 3,
"nome": "MARCA",
"valor": "FORD"
},
{
"id": 2,
"nome": "MODELO",
"valor": "FIESTA"
},
{
"id": 1,
"nome": "RENAVAM",
"valor": "RENAVAM"
}
]
},
{
"id": 1,
"nome": "AUTOMÓVEL",
"partes": [
{
"fracao": 100,
"documento": "111.111.111-11"
}
],
"atributos": [
{
"id": 3,
"nome": "MARCA",
"valor": "FIAT"
},
{
"id": 2,
"nome": "MODELO",
"valor": "PALIO"
},
{
"id": 1,
"nome": "RENAVAM",
"valor": "RENAVAM"
}
]
},
{
"id": 1,
"nome": "AUTOMÓVEL",
"partes": [
{
"fracao": 100,
"documento": "111.111.111-11"
}
],
"atributos": [
{
"id": 3,
"nome": "MARCA",
"valor": "HONDA"
},
{
"id": 2,
"nome": "MODELO",
"valor": "FIT"
},
{
"id": 1,
"nome": "RENAVAM",
"valor": "RENAVAM"
}
]
}
]
so i create a select:
select objetos
from protocolo
where objetos #> '[{"id": 1 , "atributos": [{"nome": "MARCA", "valor" : "FIAT"}]}]'
but this select will return the column with all text, but I need to return only the element that match in my where clause
so I need to return only this:
{
"id": 1,
"nome": "AUTOMÓVEL",
"partes": [
{
"fracao": 100,
"documento": "111.111.111-11"
}
],
"atributos": [
{
"id": 3,
"nome": "MARCA",
"valor": "FIAT"
},
{
"id": 2,
"nome": "MODELO",
"valor": "PALIO"
},
{
"id": 1,
"nome": "RENAVAM",
"valor": "RENAVAM"
}
]
}
Use the function jsonb_array_elements():
select value
from protocolo
cross join lateral jsonb_array_elements(objetos)
where value #> '{"id": 1 , "atributos": [{"nome": "MARCA", "valor" : "FIAT"}]}';
Note that the json expression in the where clause has changed.

find records by an array key in a document

I have some records like this
{
"_id": "test1",
"friend": {
"test2": {
"name": "ax",
"level": 1,
"intimacy": 0,
"status": 0
},
"test3": {
"name": "es",
"level": 1,
"intimacy": 0,
"status": 0
}
}
},
{
"_id": "test2",
"friend": {
"test2": {
"name": "ff",
"level": 1,
"intimacy": 0,
"status": 0
},
"test3": {
"name": "dd",
"level": 1,
"intimacy": 0,
"status": 0
}
}
}
i need find the node of friend.test2 in the document of _id=test1
i don`t want change the data struct to solve this problem.anyone can help me.
the result maybe like this
{
"test2": {
"name": "ax",
"level": 1,
"intimacy": 0,
"status": 0
}
}
Try below query.
db.<coll>.find({ _id:"test1" }, { "friend.test2":1 })
In mongo shell you can do this:
db.collection.find({_id:"test1"},{"friend.test2":1})
and for php you may try something like
$collection->find(array("_id"=>"test1"),array("friend.test2"=>true))
Following code is working correctly. Tested.
$results = $coll->find(array(), array("_id"=>"test1"),array("friend.test2"=> 1));
foreach($results as $test) {
print_r($test);
}