Laravel 5.2 Eloquent - Finding all id's through multiple relationships - php

So here are my relationships:
A fund belongs to a planCode
A planCode belongs to a planType
What I need to do is find the fund_id's that are a part of certain plan types. I tried something like this:
$plans = (new 'App\PlanType')->with('planCode.fund')->whereIn('code', ['PENS', 'ANN', 'WEL'])->get();
With this I get the three plan codes with their relationships eager loaded. What I want is a list of all the fund_id's. I tried $plans->lists('planCode.fund.fund_id', 'code') but this returns null for the fund_id. Any ideas?

So if your relationships are like this -
PlanCode has many Funds
Fund belongs to a PlanCode
PlanType has many PlanCodes
PlanCode belongs to a PlanType
Then you can add another relationship like this -
PlanType has many Funds through PlanCodes
UPDATE
After adding a function like this to your PlanType class -
public function funds() {
return $this->hasManyThrough('fund', 'planCode', PT, PC);
}
You can simply access Funds on your PlanType model like this -
$planType->Funds
Take a look at the docs here.

Yep, atefth has it in one. Laravel has a really useful relationship so that you don't have to make repeated queries to the database to get relations of relations. This is the hasManyThrough relationship.
So here, for example, your planType model has many fund models through the planCode model. Your planType model should contain a funds method that looks like this, where PC is the planCode->id column name in the fund table, and PT is the planType->id column in the planCode table:
public function funds() {
return $this->hasManyThrough('fund', 'planCode', PT, PC);
}
You may have to fully namespace your models, depending on the structure of your application.

Related

L5.5 relationship of pivot table with another model

In my application, a model Device has a many-to-many relationship with model Task.
A combination of Device and Task could be assigned to a various number of model User.
example: Device A has a Task Check something and this should be done by User Frank and Steven.
From my point of view, this should be a "standard problem", but so far I could not find a proper solution.
Right now, I use following workaround:
a) added an unique ID id to the device_task pivot table
b) query id from the pivot table
c) create a new table device_task_user which contains user_id and device_task_id
b) use query builder to get/add users
But I am really not happy with this approche.
Would it be possible, that the pivot table also extends Model and then have a one-to-many relationship with User?
Or would you suggest to add a json colum to the pivot table and store the users there?
Any idea would be very welcome!
Would it be possible, that the pivot table also extends Model
Yes, it's possible. From the docs:
If you would like to define a custom model to represent the intermediate table of your relationship, you may call the using method when defining the relationship. All custom models used to represent intermediate tables of relationships must extend the Illuminate\Database\Eloquent\Relations\Pivot class
You also can create a new hasMany() and belongsTo() relationships between Task and Device models and use them as well as existing belongsToMany relationship. And you'll need to define a new relationship between pivot model and User model to be able to get data by device, task or user.
Modify many-to-many relationship to hold an extra field user_id
class Device extends Model
{
public function tasks()
{
return $this->belongsToMany(
Task::class,
'device_task',
'device_id',
'task_id'
)->withPivot('user_id');
}
}
And when updating do like this in controller
$device->tasks()->attach([$taskId]=>['user_id']=>$userId);
And of-course you need DeviceTask model and also a has-many relationship between User model and DeviceTask model to get user's task

Laravel: Which relationship to use?

I have the following scenario:
I'm building a site where Artists show their favorite spots in a city.
So:
There are some Cities and some Artists. A City hasMany Spots.
Artists and Spots also are related together via belongsToMany, because one Spot could have been featured by multiple Artists.
I now want to define a relation in City that gives me all the artists that have something featured in that City (so basically look for artists that are related to a spot from that City)
Is there a relationship type that I can use?
I've tried hasManyThrough but that's looking up spot_id in Artist which is obviously not existent because Artist<>Spot is many to many.
when you have relationship many to many you need to do normalisation for both table, create new table to store spot_id and artist_id. I think in laravel already handle that. This link might be helpful
https://laravel.com/docs/5.5/eloquent-relationships#many-to-many
https://www.captechconsulting.com/blogs/resolve-your-many-to-manys-for-accurate-requirements
Though it's many to many relationship so you have to use belongsToMany
Ex:
In city Model :
class City extends Model{
public function artists(){
return $this->belongsToMany('App\Artist')
}
}
In Artist Model :
class Artist extends Model{
public function city(){
return $this->belongsToMany('App\City')
}
}

Nested one to many relationships in Eloquent

Let's say I have three models with this relationsship
USER
hasMany (app/organisation)
ORGANISATION
hasMany (app/order)
ORDER
For one level I could just go
user->organisations()->get()
And get all the organisations tied to the user. But every organisation also have 0..many ORDER entities. So I want to do this:
user->organisations()->orders()->get()
To get a list of all the orders from all the organisations from a certain user. Is that possible this way?
What you can simply do is implement hasManyThrough() relationship on User model.
public function orders()
{
return $this->hasManyThrough(Order::class, organisation::class);
}
then you can query like,
$user->orders()->get();

Laravel multiple relationships

I am trying to get my head around some relationships between models in Laravel.
I would like to define the relationship between the following models:
User - the users
Campaign - a campaign
Call - a phone call
Lead - Lead/client
Sale - A sale
Appointment - A scheduled phone call.
This is the way the relationship should be:
A user can be assigned to many campaigns.
A user can have many calls.
One user can have many appointments.
One call belongs to one user.
One call belongs to one campaign.
A campaign can have many calls.
A campaign can have many sales
A lead can be assigned to many campaigns.
A lead can have many sales
One lead belongs to one user in one campaign.
One lead can have many calls
One sale belongs to one campaign
One sale belongs to one user
One appointments belongs to one lead.
I uncertain about how to setup the relationship. Its easy with the one-to-one or many-to-one.
But what about this:
Call->User (one-to-one)
Call->Campaign (one-to-one)
Campaign->Call (one-to-many)
User->Call (one-to-many)
Hopefully I managed to explain it clear enough. Thanks.
I'd recommend reading the Laravel docs on relationships again.
Taking the Call/User relationship as an example, here's what you're looking at:
User --------> Call
(one) (many)
This is clearly a one to many relationship. And if you want to set up both sides of this relationship in terms of an Eloquent model, the relationships are this:
A User hasMany Calls
A Call belongsTo a User
These terms are taken directly from the documentation, in the section entitled One To Many.
So, in code...
User Model
public function Calls()
{
$this->hasMany("Call");
}
(notice that I've made the method name plural - this is my own preference, since using $user->Calls will return a collection if items).
Call Model
public function User()
{
$this->belongsTo("User");
}
Rather than taking the two sides of a relationship in isolation, as you seem to have done in your analysis, consider both sides of the relationship at the same time.

Laravel 4 Polymorphic with multiple Pivot Tables

I'm trying to create a polymorphic relationship with multiple pivot tables. I have a table of requirements that can be assigned to accounts, roles, trips, and countries. This needs to be a many to many relationship because the same requirement could apply to multiple countries and/or trips and/or accounts etc.
I then need a table listing outstanding requirements for the user. For example: if a user has a certain account and there are requirements related to that account, then those requirements would be added to the user's list of requirements.
One solution I have is to first assign the requirements to the accounts, roles, trips, and countries using Pivot tables in a Many to Many relationship. Then using a polymorphic relationship I would connect the user to whichever pivot tables relate.
But I don't know how to do this or if it is even possible?
Here are my tables:
user_requirements
- id
- user_id
- requireable_id
- requireable_type
account_requirement
- id
- account_id
- requirement_id
role_requirement
- id
- role_id
- requirement_id
trip_requirement
- id
- account_id
- requirement_id
country_requirement
- id
- account_id
- requirement_id
Laravel 4.1 now has support for polymorphic many to many relationships.
Example below shows how I have implemented sharing Photos with both Products and Posts.
DB Schema
photos
id integer
filename string
alt string
photoable
id integer
photoable_id integer
photoable_type string
Models
Photo Model
class Photo extends Eloquent
{
public function products(){
return $this->morphedByMany('Product', 'photoable');
}
public function posts(){
return $this->morphedByMany('Post', 'photoable');
}
}
Product Model
class Product extends Eloquent
{
public function photos(){
return $this->morphToMany('Photo', 'photoable');
}
}
Post Model
class Post extends Eloquent
{
public function photos(){
return $this->morphToMany('Photo', 'photoable');
}
}
With the above, I can access all photos which are attached to a product as follows:
$product = Product::find($id);
$productPhotos = $product->photos()->all();
I can also iterate over to display all photos as any collection of models.
foreach ($productPhotos as $photo)
{
// Do stuff with $photo
}
The above can be replicated almost exactly to your requirements.
create a requirements table
create a requireable table
In Requirement model, declare all morphedByMany relationships
In Country, Trip, Role etc. declare morphToMany relationships
nb - I've typed this out freehand in S/O with no code editor, so there will probably be a typo, error or two - but concept remains the same.
A polymorphic relation in Laravel 4 is intended for single MODEL associations, therefore you cannot achieve what you are trying to build with this method. This is due to the fact that a pivot table doesn't represent a Model.

Categories