Problem with Retrieving Intermediate Table Columns Laravel - laravel

CONTEXT
in a relationship many to many, i have 3 tables
Avisos
Avisos_estados (Intermediate Table)
Estados
and the models:
Model Aviso:
public function estados(){
return $this->belongsToMany(Estado::class,'avisos_estados','estados_id','avisos_id')->withPivot('activo','created_at')->wherePivot('activo', 1);
}
Model Estado:
public function avisos(){
return $this->belongsToMany(Aviso::class,'avisos_estados','avisos_id','estados_id')->withPivot('activo','created_at');
}
The issue:
When i try to get the Aviso where id =1, with state (estados where activo =1)
My eloquent query:
$id=1;
$aviso = Avisos::select(
'Avisos.id',
'Avisos.titulo',
'Avisos.descripcion',
'Avisos.imagen',
'Avisos.created_at as fecha',
'Avisos.vistas',
'users.id as idUsuario',
'users.name',
'comunas.nombreComuna',
'ciudads.nombreCiudad'
)->join('categorias','categorias.id', '=','avisos.idCategoria')
->join('estados','estados.id', '=','avisos.idEstado')
->join('users','users.id', '=','avisos.idUsuario')
->join('comunas','comunas.id','=','avisos.idComuna')
->join('ciudads', 'ciudads.id','=','comunas.idCiudad')
->with('valoraciones')
->find($id);
//Aca uso el modelo para traer los estados y usuarios relacionados con el aviso
$aviso->users;
$aviso->estados;
The response has some states that has not relation with aviso.id=1
Response (just the important part) Complete response
"estados": [//these are the states in the response
{
"id": 2,
"descripcionEstado": "Cerrada",
"created_at": "2022-09-02T19:37:45.000000Z",
"updated_at": "2022-09-02T19:37:45.000000Z",
"pivot": {
"estados_id": 1,
"avisos_id": 2,//this is wrong, because i ask for aviso,id=1
"activo": 1,
"created_at": "2022-09-08T17:05:17.000000Z"
}
},
{
"id": 3,
"descripcionEstado": "Desierta",
"created_at": "2022-09-02T19:37:45.000000Z",
"updated_at": "2022-09-02T19:37:45.000000Z",
"pivot": {
"estados_id": 1,
"avisos_id": 3,//this is wrong, because i ask for aviso,id=1
"activo": 1,
"created_at": "2022-09-21T15:12:42.000000Z"
}
}
]
Expected response:
"estados": [//expected response
{
"id": 4,
"descripcionEstado": "Cerrada",
"created_at": "2022-09-02T19:37:45.000000Z",
"updated_at": "2022-09-02T19:37:45.000000Z",
"pivot": {
"estados_id": 2,
"avisos_id": 1,
"activo": 1,//With pivot only get where activo =1
"created_at": "2022-09-08T17:05:17.000000Z"
}
}
]
the question: is there something worng with my model relationship?, or should i use some filter in my query?
Structure many to many
table estados (abierta = open, cerrada=closed,desierta=deserted, eliminada= deleted)
all states where aviso.id=1
as you can see, when i create the aviso this has a default state (open), but later change the state to closed, for that reason the record with description "Abierta (open)" has activo=0

Related

How to select not null datas using whereHas in LARAVEL

Let me make it simple, In my models, I have countries and cities. My goal is, I want to select and display only the cities that has shops and it should also have datas and the employees should not be NULL
In the below given array, my city has two shops where id - 13 that doesn't have any datas and id - 19 which is having data.
[
{
"id": 1,
"created_at": "2022-06-02T06:07:31.000000Z",
"updated_at": "2022-06-02T06:07:31.000000Z",
"name": "Niue",
"cities": [
{
"id": 13,
"created_at": "2022-06-02T06:07:44.000000Z",
"updated_at": "2022-06-02T06:07:44.000000Z",
"country_id": 1,
"name": "North Michealbury",
"shops": [] //empty
},
{
"id": 19,
"created_at": "2022-06-02T06:07:44.000000Z",
"updated_at": "2022-06-02T06:07:44.000000Z",
"country_id": 1,
"name": "Millsmouth",
"shops": [
{
"id": 1,
"created_at": "2022-06-02T06:14:37.000000Z",
"updated_at": "2022-06-02T06:14:37.000000Z",
"city_id": 19,
"name": "Roberts-Okuneva",
"employees_count": 146
}
]
}
]
}
]
This is the code that, I have written in my controller. The goal is, I want to select and show only those cities that has shops with employees.
return Country::with(['cities','cities.shops'=>function($employee){
$employee->withCount('employees')->where('city_id',19);
}])->whereHas('cities',function($city){
$city->where('cities.id',19);
})->get();
These are my models, each of them has a hasMany relationship
Country model
public function Cities(){
return $this->hasMany(City::class);
}
City model
public function shops(){
return $this->hasMany(Shop::class);
}
Shop model
public function employees(){
return $this->belongsToMany(User::class,'shop_employees','shop_id','employee_id');
}
You can try
//Get all cities which have shops having at least one employee
return Country::with([
'cities',
'cities.shops' => function($query) {
$query->withCount('employees');
}
])
->whereHas('cities', function($query) {
$query->whereHas('shops', function($query) {
$query->has('employees');
});
})
->get();
i found another solution querying with clause.
return Country::whereHas('cities',function($cities){
$cities->where('country_id',1);
})->with(['cities'=>function($shops){
$shops->has('shops')->where('cities.country_id',1);
},'cities.shops'=>function($employee){
$employee->withCount('employees');
}])->get();

Laravel Eloquent with query

I want to pull the invoice detail with the "id" number of 3 in the tools table from the "invoice_details" table. "plate" "invoice_details" relationship "plate_no" in the "trucks" table, but when I pull the data, a different data is coming, where am I making a mistake?
public function getTruck($id)
{
$truck = Truck::find($id)->with(['truckHistory'])->first();
return $truck;
}
Truck extends Model
public function truckHistory(){
return $this->hasMany(InvoiceDetail::class,'plate_no','plate');
}
Normally the incoming data is TRUE when I don't write a with condition
THIS IS TRUE
$truck = Truck::find(3);
{
"id": 3,
"plate": "73AD323",
"created_at": "2021-10-13T08:38:23.000000Z",
"updated_at": "2021-10-13T08:38:23.000000Z"
}
When I type a condition, the id is wrong.
$truck = Truck::find(3)->with(['truckHistory'])->first();
{
"id": 1,
"plate": "33EER36",
"created_at": "2021-10-11T06:01:29.000000Z",
"updated_at": "2021-10-11T06:01:29.000000Z",
"truck_history": [
{
"id": 1,
"plate_no": "33EER36",
"created_at": "2021-10-11T06:03:16.000000Z",
"updated_at": "2021-10-11T06:03:16.000000Z"
},
{
"id": 2,
"plate_no": "33EER36",
"created_at": "2021-10-11T06:06:18.000000Z",
"updated_at": "2021-10-11T06:06:18.000000Z"
}
]
}
Using first will return the first record of the trucks table, to do so you can use
Truck::with(['truckHistory'])->find($id);

Laravel Many to Many Relationship with 2 foreign key

I have 3 tables - users, graduation_institutes, graduation_degrees
I defined a pivot table - graduation_degree_user
graduation_degree_user table has data like below -
id--------doctor_id--------graduation_degree_id----------graduation_institute_id---------year
In my User model, I defined relation like below -
public function graduations(){
return $this->belongsToMany('App\Models\User\GraduationDegree')->withTimestamps();
}
In my controller, I m doing -
if($request->has('graduations')){
$user->graduations()->sync($request->graduations);
}
return $user->graduations;
Where graduations is an array which contains multiple object.
I am getting the following response -
[
{
"id": 3,
"degree": "MD",
"created_at": null,
"updated_at": null,
"pivot": {
"user_id": 2,
"graduation_degree_id": 3,
"graduation_institute_id": 1,
"created_at": "2020-12-01T07:54:23.000000Z",
"updated_at": "2020-12-01T07:54:23.000000Z"
}
},
{
"id": 4,
"degree": "MBBS",
"created_at": null,
"updated_at": null,
"pivot": {
"user_id": 2,
"graduation_degree_id": 4,
"graduation_institute_id": 2,
"created_at": "2020-12-01T07:54:24.000000Z",
"updated_at": "2020-12-01T07:54:24.000000Z"
}
}
]
In response, I am getting graduation_institute_id but I also want the name of the institute which is a field 'institute' defined in graduation_institutes table.

Paginate on grouped queries

I'm writing a system to follow cash flow. The users register transactions they made:
(transactions index screenshot)
but I need to get these transactions separated by date. I tried using an Request to index, but it doesn't looked the best pratice (it worked, however). Now I'm trying to do another aproach: retrieve all transactions and paginate them by date. Is it possible?
ps: maybe grouping by months helps? like:
$transactions = Transaction::all()->groupBy(function($transaction) {
return Carbon::parse($transaction->date)->format('m-Y');
});
this returns:
{
"03-2019": [
{
"id": 1,
"title": "Teste 1",
"date": "2019-03",
"user_id": 1,
"description": "Primeiro teste, com entrada de 1500 reais.",
"value": "1500.00",
"flow": 1,
"created_at": "2019-03-24 05:39:45",
"updated_at": "2019-03-24 05:39:45"
},
{
"id": 2,
"title": "Teste 2",
"date": "2019-03",
"user_id": 1,
"description": "Segundo teste, com saída de 500 reais.",
"value": "500.00",
"flow": 0,
"created_at": "2019-03-24 05:39:45",
"updated_at": "2019-03-24 05:39:45"
}
]
}
ps²: yeah, front-end is in brazilian portuguese and english isn't my native language.. :)
Try this out
<?php
use Illuminate\Pagination\LengthAwarePaginator;
$transactions = Transaction::all()->groupBy(function($transaction) {
return Carbon::parse($transaction->date)->format('m-Y');
});
//new LengthAwarePaginator($data,$countOfData,$perPage,$currentPage);
$transactions=new LengthAwarePaginator($transactions->forPage($currentPage,$perPage),$transactions->count(),$currentPage);
Hope it helps...

Laravel get only one column from relation

I have a table user_childrens whose contains id_parent and id_user.
I'm trying to list all childrens of the parent with this:
code:
//relation in model via belongsTo
$idparent = auth('api')->user()->id;
$list = UserChildren::where('id_parent',$idparent)
->with('child:id,name,email')
->get();
return $list->toJson();
The return is:
[
{
"id": 1,
"id_parent": 1,
"id_user": 1,
"created_at": null,
"updated_at": null,
"child": {
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
}
},
{
"id": 4,
"id_parent": 1,
"id_user": 2,
"created_at": null,
"updated_at": null,
"child": {
"id": 2,
"name": "Krystel Lehner",
"email": "cernser#example.net"
}
}
]
But it's API so I want only the child column like:
[
{
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
},
{..}
]
UserChildren Model:
public function child() {
return $this->belongsTo('App\User','id_user','id');
}
I know that I could do this via .map() on collection but maybe there is other solution already on this query
You can use this code
$idparent = auth('api')->user()->id;
$childs = User::whereHas('user_childrens', function ($query) use ($idparent) {
$query->where('id_parent', $idparent);
})->get(['id', 'name', 'email']);
dd($childs->toJson());
And User model define user_childrens relation.
public function user_childrens()
{
return $this->hasMany('App\UserChildren','id_user','id');
}
See also docs https://laravel.com/docs/5.5/eloquent-relationships#querying-relationship-existence

Resources