laravel select statement calling sub model using "with" statement - laravel

When I call a select statement using a with clause calling supplier model I want the supplier class to call the user related model. how do I do that
$products = Product::select(['id', 'title', 'slug', 'unit_price',
'sell_price', 'created_at', 'updated_at', 'created_by',
'updated_by', 'supplier_id'])->with('supplier');
// when calling supplier model call user model as well
class Supplier extends Model
{
protected $table = "suppliers";
protected $fillable = ['company', 'email'];
public function user() {
return $this->belongsTo('App\User', 'email', 'email');
}
}

According to the documentation you can perform nested eager loading using the dot notation.
So in you example
...->with('supplier');
becomes
...->with('supplier.user');

Related

Laravel 9 - specular model relations not working

i can't figure out why my eloquent relationship is not working.
I have the grid and details tables related (es. grid.id = details.order_id). This works for first 2 tables but not for other 2 that are almost a copy of the first.
Working relationship code :
OrderGrid model:
use HasFactory;
protected $table = 'orders_grid';
protected $fillable = [
'user_id',
// more data
];
public function order_detail()
{
return $this->hasMany('App\Models\OrderDetail');
}
OrderDetail model:
use HasFactory;
protected $table = 'orders_detail';
protected $fillable = [
'order_id',
// more data
];
public function order_grid()
{
return $this->belongsTo('App\Models\OrderGrid', 'order_id', 'id');
}
In controller
$data_details = OrderDetail::where('order_id', $id)->get();
in view
$data_details->first()->order_grid->id
// so i can get the ID from the related table
Now i have two more very similar models which relations are not working:
OrderGrid model 2
use HasFactory;
protected $table = 'orders_grid_jde';
protected $fillable = [
'total_order',
// more data
];
public function detail_jde()
{
return $this->hasMany('App\Models\OrderDetailJde');
}
OrderDetail model 2 :
use HasFactory;
protected $table = 'orders_detail_jde';
protected $fillable = [
'order_jde_id',
];
public function grid_jde()
{
return $this->belongsTo('App\Models\OrderGridJde', 'order_jde_id', 'id');
}
In controller:
$data_details = OrderDetailJde::where('order_jde_id', $id)->get();
In view:
$data_details->first()->order_jde_id->id
This is not working, if i dump($data_details->first()) relations is empty array, not as in the screen shown before
Another weird behaviour on working relation: if i dump $data_details->first() in the controller i don't see the relation, but if i do it in view it shows as in the screen.
Sorry for the long post, tried to be understandble as possible
In your Controller call the relation like this:
$data_details = OrderDetailJde::where('order_jde_id', $id)->with("grid_jde")->get();
In view:
$data_details->first()
It will give all the detils.
It should work now.
In the view where you have the error, you are accessing the directly to the field named order_jde_id instead of the relationship grid_jde.
Tips:
You should eager load the relationships if you are planning to use these in the view.
$books = Book::with('author')->get();
https://laravel.com/docs/9.x/eloquent-relationships#eager-loading

Laravel Eloquent query relations with 3 levels

I want some help of forming queries on Laravel Eloquent
I have 4 models in my application
Item Model
class Item extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'code', 'name', 'type', 'price', 'cost', 'reorder_level', 'status'
];
public function grnoteitems()
{
return $this->hasMany(Grnoteitem::class);
}
}
Grnote Model
class Grnote extends Model
{
use HasFactory;
protected $fillable = [
'date', 'number', 'warehouse_id','user_id', 'authorized_id', 'approved_id', 'notes'
];
public function grnoteitems()
{
return $this->hasMany(Grnoteitem::class);
}
public function warehouse()
{
return $this->belongsTo(Warehouse::class);
}
}
Grnoteitem Model
class Grnoteitem extends Model
{
use HasFactory;
protected $fillable = [
'grnote_id', 'item_id', 'description', 'packing', 'quantity', 'price', 'total'
];
public function grnote()
{
return $this->belongsTo(Grnote::class);
}
public function item()
{
return $this->belongsTo(Item::class);
}
}
Warehouse Model
class Warehouse extends Model
{
use HasFactory;
protected $fillable = ['name', 'address'];
public function grnotes()
{
return $this->hasMany(Grnote::class);
}
}
Quantity of the item is calculated by multiplying quantity and packing columns in the grnotes table.
Now I want to retrieve all the items with their quantity(quantity * packing) from a particular warehouse.
I tired the below query
$items = Item::withSum('grnoteitems', 'quantity', function($query) use($warehouse, $from, $to){
$query->with('grnote', function($query1) use($warehouse, $from, $to){
$query1->where('warehouse_id', $warehouse->id)
->whereBetween('date', [$from, $to])->get();
})->get();
})->get();
This is working fine. But I don't find any way to get sum of two multiplied columns
I want something like
$items = Item::withSum('grnoteitems', '(quantity * packing)', function($query) use($warehouse, $from, $to){
$query->with('grnote', function($query1) use($warehouse, $from, $to){
$query1->where('warehouse_id', $warehouse->id)
->whereBetween('date', [$from, $to])->get();
})->get();
})->get();
Please help me to solve this.
It's a bit long to write all the code to do this, but my idea would to :
start your query from the wareHouse you want items from
so Warehouse::first() [with grnote [with item]] and custom where stuff
then the data you need to calculate are on the pivot table between Item and Grnote, so I would add withPivot to both relations
in this query order, the pivot value will be appended as a relation to the Item object
I would add a new attribute to the item model. Checking if the pivot attribute is set (so it comes from a query with pivot), calculate the quantity, and append it to the Item instance
You can also loop on the resulting Collection to append your new attribute.

How do i get all the Units that satisfy the criteria of being in a certain city (where city is a column in the Property Table)

Property Model:
class Property extends Model {
use HasFactory;
protected $table = 'properties';
protected $fillable = ['name', 'address', 'city', 'poskod', 'state', 'facilities'];
/* Get all the units in this property */
public function units()
{
return $this->hasMany(Unit::class);
}
}
Unit Model
class Unit extends Model {
use HasFactory;
protected $fillable = [
'user_id',
'property_id',
'type',
'no',
'owner',
'commission',
'agent',
'availability',
'bed',
'bath',
'sqft',
'rental',
'sale',
];
/* Get the property the unit is in */
public function property() {
return $this->belongsTo(Property::class);
}
}
I need to get all the units which are in a certain city. And city is defined inside a property which is a foreign key to units.
I did it by memory, so it is not tested.
$units = Unit::with('property')
->whereHas('property' function ($query) {
$query->where('city', 'Amsterdam');
});
Very good explanation of eager loading and whereHas here: Laravel - Eloquent "Has", "With", "WhereHas" - What do they mean?

Laravel Relationship Without Timestamps

Is there away to call a model with a relationship without timestamps when calling the with statement in the model itself - instead of going into that relationship model and saying $protected timestamps = false;
e.g
class Post Extends Eloquent {
public function template() {
return $this->hasOne('App\Template', 'id', 'template_id')->timestamps(false);
}
}
You can add this in following model to skip the values
protected $hidden = [
'created_at',
'updated_at'
];

call collection with other model to lists

How do I call the relational data in the statement below using a with statement.
$suppliers = Supplier::with('user')->lists('user.company', 'user.id'); // doesn't work
class Supplier extends Model
{
protected $table = "suppliers";
protected $fillable = ['email'];
public function user() {
return $this->belongsTo('App\User', 'email', 'email');
}
}
You achieve your goal using the pluck method:
Supplier::with('user')->get()->pluck ('user.company', 'user.id');
The get method returns a Collection, then you can use its methods.

Resources