laravel 5.1: get relation in with - laravel

I have a model called user
with relation "travel" model
and travel model with relation "destination"
how can I get user in eloquent with travel and relation.
I know that I can get travel like this :
$row = $this->model
->find($reqId)
->with('travel')
->first();
I want get destination of travels .

If I understood your question correctly, you want to use nested eager loading:
$row = $this->model->with('travel', 'travel.destination')->find($reqId)

Related

Laravel eloquent without() in nested relationship

I am trying to exclude a few relations from my API call.
Right now I'm returning the records as following:
return response()->json(Ticket::where('status_id', '!=', 5)->get());
In the ticket model I have a belongsTo relation with customer.
In the customer model I have a hasOne relation with Address.
Now, I have included the address in the customer model, and the customer in the ticket model usin $with.
I want to get the customer with the ticket, but not the address. I tried using the without function as followed: Ticket::where('status_id', '!=', 5)->without(['customer.address'])->get().
This is not working, however the following does work: Ticket::where('status_id', '!=', 5)->without(['customer'])->get() I do get the ticket without any relations.
I assumed the first function would work, considering this also works in the with() function, but it does not.
To remove the relation address while keeping the address relation in the $with attribute of the customer class, use this:
Ticket::where('status_id', '!=', 5)->with(['customer' => function($customer){
$cutomer->without(['address']);
}])->get()
But I suggest you remove the address from the $with attribute or you will end up with more without(['address']) than with('address') if you remove it.
It should work provided there's no typo in the relation name (like address instead of addresses).
Another approach - try the following
return response()->json(
Ticket::with('customer', fn($query) => $query->without('address'))
->where('status_id', '<>' 5)
->get()
);
I think even this should work (without typos in relation name)
return response()->json(Ticket::without('customer.address')->where('status_id', '<>' 5)->get());
This should remove/unset address relationship from customer

Laravel eloquent for four tables

I'm new to Laravel. I am developing a project. and in this project I have 4 tables related to each other
-Users
-Orders
-OrderParcels
-Situations
When listing the parcels of an order, I want to get the information of that order only once, the user information of that order once again, and list the parcels as a table under it. so far everything ok. but I also want to display the status of the parcels listed in the table as names. I couldn't add the 4th table to the query. do you have a suggestion? I'm putting pictures that explain the structure below.
My current working code is
$orderParcels = Orders::whereId($id)
->with('parcels')
->with('users:id,name')
->first();
and my 'orders' model has method
public function parcels(){
return $this->hasMany(OrderParcels::class);
}
public function users(){
return $this->hasOne(User::class,'id','affixer_id');
}
Note[edit]: I already know how to connect like this
$orderParcels = DB::table('order_parcels as op')
->leftjoin('orders as o','op.orders_id','o.id')
->leftjoin('users as u','o.affixer_id','u.id')
->leftjoin('situations as s','op.status','s.id')
->select('op.*','o.*','u.name','s.situations_name')
->where('op.orders_id',$id)->get();
but this is not working for me, for each parcels record it returns me orders and user info. I want once orders info and once user info.
Laravel provides an elegant way to manage relations between models. In your situation, the first step is to create all relations described in your schema :
1. Model Order
class User extends Model {
public function parcels()
{
return $this->hasMany(OrderParcels::class);
}
public function users()
{
return $this->hasOne(User::class,'id','affixer_id');
}
}
2. Model Parcel
class Parcel extends Model {
public function situations()
{
return $this->hasOne(Situation::class, ...);
}
}
Then, you can retrieve all desired informations simply like this :
// Retrieve all users of an order
$users = $order->users; // You get a Collection of User instances
// Retrieve all parcels of an order
$parcels = $order->parcels; // You get a Collection of User instances
// Retrieve the situation for a parcel
$situations = $parcel->situations // You get Situation instance
How it works ?
When you add a relation on your model, you can retrieve the result of this relation by using the property with the same name of the method. Laravel will automatically provide you those properties ! (e.g: parcels() method in your Order Model will generate $order->parcels property.
To finish, in this situation where you have nested relations (as describe in your schema), you should use with() method of your model to eager load all the nested relation of order model like this :
$orders = Orders::with(['users', 'parcels', 'parcels.situations'])->find($id)
I encourage you to read those stubs of Laravel documentation :
Define model relations
Eager loading
Laravel Collection
Good luck !
Use join to make a perfect relations between tables.
$output = Orders::join('users', 'users.id', '=', 'orders.user_id')
->join('order_parcels', 'order_parcels.id', '=', 'orders.parcel_id')
->join('situations', 'situation.id', '=', 'order_parcels.situation_id')
->select([
'orders.id AS order_id',
'users.id AS user_id',
'order.parcels.id AS parcel_id',
'and so on'
])
->where('some row', '=', 'some row or variable')->get();

How to use OrderBy in Laravel using eloquent relationship?

I have two model: Category and PostAd model.
They two have relation with each other.
In laravel view i have passed data through Category Model to display PostAd data.
I want to apply OrderBy condition in query but it doesn't work
Code
$data['category'] = Category::with(['postads'])->where('id',$id)->get();
I want to do this
$data['category'] = Category::with(['postads'])->where('id',$id)->orderBy('adtitle','DESC')->get();
But it doesn't work because it is Category Model.
How can i solve this.
if you want to get PostAd data with an order by then you can do an eager load Order by.
And here you're using get() method so it should be first(); because ->where('id',$id) always get one record.
$data['category'] = Category::with(['postads' => function($query) {
$query->orderBy('adtitle', 'DESC');
}])->where('id',$id)->first();

How can I use higher order messages with Eloquent?

I have a teacher model and that teacher has a belongToMany relationship with a student model.
I want to leverage a higher order message function to sync a student to many teachers.
Usually I would do the following:
$teachers = Teacher::limit(5)->get();
$student = Student::first();
$teachers->each(function($teacher) use ($student) {
$teacher->students()->sync($student)
});
With higher order functions I should be able to do:
// Throws error BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::sync does not exist.
$teachers->each->students()->sync($student);
Unfortunately due to how higher order messages work as defined inside of the class HigherOrderCollectionProxy the relationship students() will be executed returning a collection of all the students that teacher has instead of a belongsToMany relationship instance.
How can I use higher order messages with Laravel Eloquent relationships?
Reverse the logic.
$teacherIds = Teacher::limit(5)->pluck('id')->toArray();
$student = Student::first();
$student->teachers()->sync($teacherIds);

Get pivot from two model instance

I have a question. Activity model and User model have many-to-many relationships. I know I can get pivot model like this:
$activities = $user->activities;
foreach($activities as $activity)
{
$pivot = $activity->pivot;
}
But now I already have two model instance:$user and $activity .Get them by id individually. Not access from their relationship. So I want to know is there a method to get their pivot model?
Its not necessary for you to call the relationship chain to access pivot, you can query individual model and access pivot too,
$model = Activity::find(1); //get the activity model by primary key
$model->pivot->activityId;

Resources