Why does this Laravel eloquent query give back more objects? - mysql

I am trying to get back a model that has relationships with other models in Laravel with eloquent but my query does not work. What i am trying to do is only
show the dataLog with the related groups, units and the related component and give that back as a object. The parameter $componentId is the only component that should be given back but it gives back other
component ids, groups and units aswell. Is there a way to only show the component with the given parameter componentId and skip the rest that is not relevant?
<?
public function getLogData( $componentId, $limit ) {
$dataLogs = Log::whereHas( 'groups', function( $group ) use (&$componentId) {
$group->whereHas( "units", function( $unit ) use (&$componentId) {
$unit->whereHas( "components", function( $component ) use (&$componentId) {
$component->where( "Component", $componentId );
} );
} );
} )->take( $limit )->get();
return response( )->json( $dataLogs );
}
?>
The response is
[
{
"Oid": 10409376,
"Active": false,
"Speed": "0",
"Weight": "0",
"Amount": "0",
"Code": "",
"Control": false,
"Type": 1,
"Event": 1,
"Name": "TestName",
"Number": "",
"Mode": 0,
"Recipe": "",
"DateTime": "2020-03-02 11:09:37.177",
"Check": 288,
"groups": [
{
"Oid": 11162074,
"Amount": "3.387",
"Cap": "0",
"Speed": "0",
"ActTachoVoltage": "0",
"Act": "0",
"Weight": "497717",
"Codes": "",
"Type": 1,
"Name": "Group1",
"units": [
{
"Oid": 15934577,
"Speed": "0",
"Counter": 0,
"Weight": "0",
"components": [
{
"oId": 18168546,
"Type": 1,
"component": 1102,
"Entry": 15934577
}
]
},
{
"Oid": 15934578,
"Speed": "0",
"Counter": 0,
"Weight": "0",
"components": [
{
"oId": 18168546,
"Type": 1,
"component": 1101,
"Entry": 15934577
}
]
},
}
]
The response that is needed with the given query
[
{
"Oid": 10409376,
"Active": false,
"Speed": "0",
"Weight": "0",
"Amount": "0",
"Code": "",
"Control": false,
"Type": 1,
"Event": 1,
"Name": "TestName",
"Number": "",
"Mode": 0,
"Recipe": "",
"DateTime": "2020-03-02 11:09:37.177",
"Check": 288,
"groups": [
{
"Oid": 11162074,
"Amount": "3.387",
"Cap": "0",
"Speed": "0",
"ActTachoVoltage": "0",
"Act": "0",
"Weight": "497717",
"Codes": "",
"Type": 1,
"Name": "Group1",
"units": [
{
"Oid": 15934577,
"Speed": "0",
"Counter": 0,
"Weight": "0",
"components": [
{
"Oid": 15934578,
"Speed": "0",
"Counter": 0,
"Weight": "0",
"components": [
{
"oId": 18168546,
"Type": 1,
"component": 1101,
"Entry": 15934577
}
]
},
}
]
If the parameter id given is 1101. Does any one know what i am doing wrong?
The models and the relation ships
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class log extends Model
{
// Define variables
protected $primaryKey = 'Oid';
protected $table = 'log';
protected $connection = 'testdb';
protected $appends = [ 'groups' ];
// Functions
public function getGroupsAttribute( )
{
if( $this->groups() )
return $this->groups()->get();
return [];
}
// Define model relationship logEntry = FK from log to group model
public function groups(){
return $this->hasMany(groupLog::class, 'logEntry');
}
}
?>
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class groupLog extends Model
{
// Define variables
protected $primaryKey = 'Oid';
protected $table = 'groupLog';
protected $connection = 'testdb';
// Functions
public function getUnitsAttribute( )
{
if( $this->units() )
return $this->units()->get();
return [];
}
// Define database relationships
public function log(){
return $this->belongsTo(log::class);
}
// Define model relationship groupEntry = FK from log to group model
public function units(){
return $this->hasMany(unitLog::class, 'groupEntry');
}
}
?>
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class unitLog extends Model
{
// Define variables
protected $primaryKey = 'Oid';
protected $table = 'unitLog';
protected $connection = 'testdb';
protected $appends = [ 'components' ];
// Functions
public function getComponentsAttribute( )
{
if( $this->components() )
return $this->components()->get();
return [];
}
// Database relationships with models
public function group(){
return $this->belongsTo(groupLog::class);
}
public function components(){
return $this->hasMany(componentLog::class, 'unitEntry');
}
}
?>
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class componentLog extends Model
{
// Define variables
protected $primaryKey = 'Oid';
protected $table = 'componentLog';
protected $connection = 'testdb';
// Define model database relationships
public function units(){
return $this->belongsTo(unitLog::class);
}
}
?>
Tried the solution with the answer like so
$machineLogs = MachineLog::whereHas( 'groups', function($group) use ($componentId) {
$group->whereHas( "units", function( $unit ) use ($componentId) {
$unit->whereHas( "components", function( $component ) use ($componentId) {
$component->where("component", $componentId);
} );
} );
} );
$filterComponents = $machineLogs->with(['groups.units.components' => function ($query) use ($componentId) {
$query->where('component', $componentId);
}])->take($limit)->get();
return response( )->json( $filterComponents );

You are querying Log that has the given units and it will always return all the units, no matter what ids they have. What you are looking for is to filter the relationship using with(). I would still use your full query, for getting the correct logs out.
Log::yourQueries() // insert your existing queries here.
->with('groups.units.components' => function ($query) use ($componentId) {
$query->where('component', $componentId);
});
This will preload components and filter them by the giving query, this should return your expected result.

Related

Mapping data that contains dots in React

I am trying to map the data in React that is coming from the API but I am having problems mapping the object that contains dots for example this: name.en_US.
What is the proper way to map this object and keeping the data structure that I have?
I am getting the date in this format from the API:
{
"user": "User",
"employeeId": "0000",
"businessCustomer": "customer",
"endCustomer": {
"name": "",
"address": "",
"place": ""
},
"device": {
"shipmentIds": "23",
"name.en_US": "wasi",
"name.fi_FI": " masi"
},
"task": {
"time": "2019-02-10T16:55:46.188Z",
"duration": "00:00:24",
"sum": "75€"
}
},
And then I am trying to map it using the following code.
const {
user,
employeeId,
businessCustomer,
endCustomer,
device,
task
} = task;
const{
endCustomerName,
address,
place
} = endCustomer;
const {
shipmentIds,
names
} = device;
const{
en_US,
fi_FI
} = names;
const {
time,
duration,
summa
} = task;
const data = {
"user": "User",
"employeeId": "0000",
"businessCustomer": "customer",
"endCustomer": {
"name": "",
"address": "",
"place": ""
},
"device": {
"shipmentIds": "23",
"name.en_US": "wasi",
"name.fi_FI": " masi"
},
"task": {
"time": "2019-02-10T16:55:46.188Z",
"duration": "00:00:24",
"sum": "75€"
}
};
const { device } = data;
const {
shipmentIds,
'name.en_US': name_en_US,
'name.fi_FI': name_fi_FI
} = device;
const nameUS = device['name.en_US'];
console.log(name_en_US, nameUS);
Use [ ] notation like, device['name.en_US'] .
You can destructure your propery as #Vishnu mentioned, or you could also destructure it by providing a valid key name
const {
shipmentIds,
'name.en_US': name_en_US,
'name.fi_FI': name_fi_FI
} = device;
And then you could access your variable with name_en_US.

How to store and retrieve nested JSON array in laravel 6

I am trying to retrieve the data saved as json in mysql. My migration looks like below:
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->nullable();
$table->json('add_ons')->nullable();
$table->timestamps();
});
I have tried saving the below JSON from postman and it saved perfectly.
{
"itemName": "chicken",
"addons": {
"required": false,
"min": 2,
"max": 3,
"data": [
{
"name": "sauces",
"type": [
{
"name": "white sauce",
"type": [
{
"name": "whiteOne",
"price": 10
},
{
"name": "whiteTwo",
"price": 20
}
]
},
{
"name": "red sauce",
"price": 10
}
]
}
]
}
}
Now, I trying to retrieve the price of 'whiteOne' under 'white sauce' and getting nothing other than null or laravel error response.
I have tried
Item::whereJsonContains('add_ons->data->name','sauces')->get()
Item::whereJsonContains('add_ons->data->name','sauces')->find(16)
After saving the 'add_ons' column has below data:
{
"required": false,
"min": 2,
"max": 3,
"data": [
{
"name": "sauces",
"type": [
{
"name": "white sauce",
"type": [
{
"name": "whiteOne",
"price": 10
},
{
"name": "whiteTwo",
"price": 20
}
]
},
{
"name": "red sauce",
"price": 10
}
]
}
]
}
Can anyone help me ?
I used this function to get the value of the index.
public function search($array, $key, $value) {
// RecursiveArrayIterator to traverse an
// unknown amount of sub arrays within
// the outer array.
$arrIt = new \RecursiveArrayIterator($array);
// RecursiveIteratorIterator used to iterate
// through recursive iterators
$it = new \RecursiveIteratorIterator($arrIt);
foreach ($it as $sub) {
// Current active sub iterator
$subArray = $it->getSubIterator();
if ($subArray[$key] === $value) {
//$result[] = iterator_to_array($subArray);
$result = iterator_to_array($subArray);
}
}
return $result;
}
Now when I pass the values in the function I get the appropriate values.
$item = Item::where('id','=',16)->first();
$res = $this->search($item->add_ons['data'], 'name', 'whiteTwo');
echo $res["name"]." - ".$res['price'] ."<br>";

How to optimize JsonResult after solving Self Referencing?

The following image describes my model relationship between User and Room.
There is a Many to Many relationship between them,
and I have resolved the Self Reference issue by JSON.NET
and adding some configurations to the Application_Start function.
It looks like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
};
}
I defined a API like this to return All the users in database as Json.
public ActionResult Index()
{
return Content(JsonConvert.SerializeObject(db.UserSet), "application/json");
}
The point is , when I get a JsonResult , it looks like
(Every "User" has a navigation attribute "Room" )
[
{
"Room": [
{
"User": [
{
"Room": [],
"Id": 3,
"Name": "waterball",
"Account": "pppaass",
"Password": "123"
}
],
"Id": 1,
"Name": "sadafsa"
}
],
"Id": 2,
"Name": "waterball",
"Account": "safasfasd",
"Password": "123"
},
{
"Room": [
{
"User": [
{
"Room": [],
"Id": 2,
"Name": "waterball",
"Account": "safasfasd",
"Password": "123"
}
],
"Id": 1,
"Name": "sadafsa"
}
],
"Id": 3,
"Name": "waterball",
"Account": "pppaass",
"Password": "123"
}, ........
Obviously , the result looks complex ,
How can I get only the Id,Name but NO User attributes of each Room ?
Or what exactly is the common way people handle with this problem?
===========================================================
I have changed my codes to reach my requirement,
but is this actually the common way to resolve this...?
Or does it have some potential problems?
public ActionResult Index()
{
var result = from u in db.UserSet
select new
{
Id = u.Id,
Account = u.Account,
Password = u.Password,
Room = from r in u.Room
select new
{
Id = r.Id,
Name = r.Name
}
};
return Content(JsonConvert.SerializeObject(result), "application/json");
}

Filtering JSON data with filter function in React- Redux

I have a JSON file with the following format:
const data = [
{
"quantity": "200",
"prodType": "stock",
"symbol": "LOL",
"prodDesc": "Εθνική τράπεζα",
"market": "Greece",
"averageCost": "131,16",
"totalCost": "123,47",
"lastPrice": "121,123",
"value": "123,34",
"positionPercentage": "10",
"valueEUR": "113,23",
"pl": "1300",
"plPercentage": "12",
"plEuro": "1238",
"results": "12-01-2017",
"dividend": "12-03-2017",
"isin": "1234566"
}
]
I want to filter the data using their Product Type.
As a result, im creating an action
export function fetchSearchData(product_type) {
const filtered_data = data.filter(record=>
{
return record.prodType.match(product_type)
});
return {
type: FETCH_SEARCH_DATA,
payload: filtered_data
};
}
But it does not seem to work. Do you have any idea why?

Remove proxies from Json Response Symfony2

I'm working in Symfony2 application and what I'm trying to do is to remove unwanted fields from response and show only fields that I want.
My JSON looks like this:
[
{
"id": 1,
"title": "Granit",
"typeId": {
"id": 1,
"name": "X or Y",
"acroname": "xory",
"__initializer__": null,
"__cloner__": null,
"__isInitialized__": true
},
"pushDate": {
"timezone": {
"name": "Europe/Berlin",
"location": {
"country_code": "DE",
"latitude": 52.5,
"longitude": 13.36666,
"comments": "most locations"
}
},
"offset": 7200,
"timestamp": 1460584800
},
"addedAt": {
"timezone": {
"name": "Europe/Berlin",
"location": {
"country_code": "DE",
"latitude": 52.5,
"longitude": 13.36666,
"comments": "most locations"
}
},
"offset": 7200,
"timestamp": 1460548644
},
"deviceToShow": {
"id": 2,
"name": "Mobile",
"__initializer__": null,
"__cloner__": null,
"__isInitialized__": true
},
"statusSurvey": false,
"slides": [
{
"id": 1,
"title": "First Question",
"picture1": "160413015724bazinga2.jpg",
"picture2": "160413015724th.jpg",
"idSurvey": 1,
"absolutePathpic1": "C:\\xampp\\htdocs\\stu-wrapper\\src\\AppBundle\\Entity/../../../web/uploads/slideSurvey/160413015724bazinga2.jpg",
"webPathpic1": "uploads/slideSurvey/160413015724bazinga2.jpg",
"absolutePathpic2": "C:\\xampp\\htdocs\\stu-wrapper\\src\\AppBundle\\Entity/../../../web/uploads/slideSurvey/160413015724th.jpg",
"webPathpic2": "uploads/slideSurvey/160413015724th.jpg",
"file": null,
"file1": null
}
],
"categories": []
}
]
I want to remove fields like "initializer": null,"cloner": null, "isInitialized": true and hide timezone object and show only "timestamp".
Here is my controller where I'm doing serializing and creating Json Response.
public function getAction()
{
$em = $this->getDoctrine ()->getManager ();
$survey = $em->getRepository ( 'AppBundle:Survey' )->findAll ();
if ( !$survey ) {
throw $this->createNotFoundException ( 'Data not found.' );
}
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer();
$normalizer->setCircularReferenceHandler ( function ( $survey ) {
return $survey->getid ();
} );
$serializer = new Serializer( array ( $normalizer ), array ( $encoder ) );
$jsonContent = $serializer->serialize ( $survey, 'json' );
return new Response( $jsonContent );
}
Thank you.
Try to exclude this fields:
$normalilzer->setIgnoredAttributes(
[
"__initializer__",
"__cloner__",
"__isInitialized__"
]);
Detach entity to remove doctrine2 links to the object
$em->detach($survey);