return separate result for each relation in many to many - laravel

Hi i have a many to many relationship with the following structure:
services
apps
service_app
I would like to have an eloquent query to return a separate result for each relationship(basically the pivot table). I have the following :
$all = App::with('services')->get();
this will return an app with nested services, I would like to have this return a separate result for each app-service combination along with data from the pivot table. how is this possible using eloquent?

It's a bit strange, but it can easily be done if you don't think of the pivot table as a pivot table, but as an AppService.
So what you can do is create a model for it, probably named AppService. In that model, you would then have 2 belongsTo() relationships. One for App and one for Service.
Then you can query your pivot table directly and use those relationships to get what you need.
$appServices = AppService::all();
foreach($appServices as $appService) {
echo $appService->app->description;
echo $appService->service->description;
}

Related

Using Laravel Eloquent to count how many times something exists in an efficient manner

I have a table called rentals, within each row are columns state,city,zipcode which all house ids to another table with that info. There are about 3400 rentals. I am pulling each column to display the states,city and zipcode distinctly. I need to show how many rentals are in each one. I am doing this now via ajax, the person starts typing in what they want to see and it auto completes it with the count, but its slow because of the way im doing it.
$rentals_count = Rentals::where('published',1)->get();
foreach($states as $state) {
echo $state.”-“.$rentals_count->where(‘state’,$state->id)->count();
}
Above is roughly what im doing with pieces removed because they are not related to this question. Is there a better way to do this? It lags a bit so the auto complete seems broken to a new user.
Have you considered Eager loading your eloquent query? Eager loading is used to reduce query operations. When querying, you may specify which relationships should be eager loaded using the with method:
$rental_counts = Rentals::where('published',1)->with('your_relation')->get();
You can read more about that in Laravel Documentation
$rentals = Rentals::wherePublished(true)->withCount('state')->get();
When you loop through $rentals, the result will be in $rental->state_count
Setup a relation 'state' on rentals then call it like this
$rentals_count = Rentals::where('published',1)->with('state')->get()->groupBy('state');
$rentals_count->map(function($v, $k){
echo $v[0]->state->name .' - '. $v->count();
});
Meanwhile in Rentals Model
public function state(){
return $this->hasOne(State::class, 'state'); //state being your foreign key on rentals table. The primary key has to be id on your states table
}

ManyToMany with and whereIn

I have a ManyToMany relationship between AdInterest and AdInterestGroup models, with a belongsToMany() method in each model so I can use dynamic properties:
AdInterest->groups
AdInterestGroup->interests
I can find all the "interests" in a single group like this:
$interests = AdInterestGroup::find(1)->interests->pluck('foo');
What I need is a merged, deduplicated array of the related 'foo' field from multiple groups.
I imagine I can deduplicate with ->unique(), but first, as you'd expect, this:
AdInterestGroup::whereIn('id',[1,2])->interests->get();
throws:
Property [interests] does not exist on the Eloquent builder instance.
The advice seems to be to use eager loading via with():
AdInterestGroup::with('interests')->whereIn('id',[1,2])->get();
Firstly, as you'd expect that's giving me an array of two values though (one for each ID).
Also, if I try and pluck('foo') again, it's looking in the wrong database table: from the AdInterestGroup table, rather than the relationship (AdInterest).
Is there a nice, neat Collection method / pipeline I can use to combine the data and get access to the relationship fields?
Use pluck() and flatten():
$groups = AdInterestGroup::with('interests')->whereIn('id', [1, 2])->get();
$interests = $groups->pluck('interests')->flatten();
$foos = $interests->pluck('foo')->unique();

How to combine three many to many relationship results in a single collection in Laravel?

I have a many to many relationship between the following:
actor <-> theater_play, actor <-> musical, actor <-> ballet_play
How can I make a single array to display all the results from these relationships in Laravel?
I have now:
$actor->theaterPlays, $actor->musicals, $actor->balletPlays
And I need to have something like this:
$actor->allPerformances
EDIT:
And I have to order theym by name, or by date of the performance etc.
Untested, however you should be able to create a new accessor within your Actor model which is responsible for merging all types together:
public function getAllPerformancesAttribute()
{
return $this->theaterPlays()
->get()
->merge($this->musicals()->get())
->merge($this->balletPlays()->get())
->all();
}

how to make relation between table and array of ids from another table laravel

i have 2 tables, stores and products
stores table has field called products_ids
in this case i am saving the products in the stores by their ids in products_ids field as an array like this [1,2,3,4,5] i know it's not good practice to do it like this but this is the situation.
how can i make a relation in the model to achieve thing like this
Store::with('products')->get();
thanks
I don't know if this would work for you, but try it anyway:
in your Store model add the following:
public function products ()
{
return Product::whereIn('id', $this->products_ids)->get();
}

Laravel how many relationship can be chained

I have a database composed by users, users_child, child.
I create a ONE to MANY relationship between Users and users_child, then i create a relationship between users_child and child. Now the below code work:
$test = users::find(1)->users_child
$test1= users_child::find(1)->child
Now i want to know if is possible to create a single row that link the three table like this:
$test = users::find(1)->users_child->child
I create the relationship in the model but in the db i don't create Foreign Key, it's a problem? on the model i specify the field for link table.
http://laravel.com/docs/5.1/eloquent-relationships#querying-relations
You can chain relationships like this:
$user = Users::with("users_child.child")->where("id",1)->first();
Each point will mean a relation stored in the first.
Out of users users_child will be taken and out of users_child child will be taken. (Relations)
foreach($user->users_child as $user_child) {
$user_child->child;
}
will get you the data you need.

Resources