Laravel Multiple Foreign Keys on Intermediate Table - laravel

I have the following table structure:
default_tasks
id
...
locations
id
...
users
id
...
default_task_location
id
location_id
default_task_id
default_assignee_id (FK to users.id)
In my blade file I'm looping through the default tasks for the location, and trying to output the default assigned user. I can get the ID by doing $task->pivot->default_assignee_id, but I want to get the actual user model so I can output the user's name in my blade file
I've gathered from searching that the way to accomplish this is to create a pivot table model. So I've done this:
class DefaultTaskLocationPivot extends Pivot
{
public function user()
{
return $this->belongsTo(User::class, 'default_assignee_id');
}
public function defaultTask()
{
return $this->belongsTo(DefaultTask::class);
}
public function location()
{
return $this->belongsTo(Location::class);
}
}
and in my location model I've done this:
public function taskDefaultAssignee()
{
return $this->belongsToMany(User::class)
->using(DefaultTaskLocationPivot::class)->withPivot(['default_task_id', 'frequency_type_override', 'create_on_day_override', 'due_on_day_override', 'default_assignee_id']);
}
However, I'm still unable to access the user associated with the default_assignee_id. I've tried things like $task->location->taskDefaultAssignee, but it doesn't seem like the relationship is even available if I dump the object.

Related

Obtain the data from the first table and the data from the second table useful for connecting a third table

I have this tables:
clients
id - integer
name - string
wineshops
id - integer
client_id - integer
name - string
wines
id - integer
wineshop_id - integer
name - string
I need to print on the view that contains all the wines the name of the client and the name of the wineshop referring to that wine.
As I initially needed the wine count to view it in the client index, I used the hasManyThrough relationship as the code below shows.
To be clearer in the view where the wines of a specific wine shop are present I want to see the following line:
List of wines belonging to the wine shop (wine shop name) of (client name)
Obviously as a title (h1), so not repeated through a foreach loop
Relationship defined in the Client model:
public function wineshops()
{
return $this->hasMany(Wineshop::class);
}
public function wines()
{
return $this->hasManyThrough(Wine::class, Wineshop::class);
}
Relationship defined in the Wineshop model:
public function client()
{
return $this->belongsTo(Client::class);
}
public function wines()
{
return $this->hasMany(Wine::class);
}
Relationship defined in the Wine model:
public function wineshop()
{
return $this->belongsTo(Wineshop::class);
}
ROUTE:
Route::get('/wine/index/{id}', [WineController::class, 'index'])->name('wine.index');
CONTROLLER:
public function index($id)
{
$wines = Wine::where('wineshop_id', $id)->get();
$wines->load('wineshop');
return view('wine.index', compact('wines'));
}
I've tried this but can't work, I get the error Undefined constant "wines" when I try to pass the name of the wineshop into the view.
Anyone who can kindly help me?
write the return view('wine.index', compact('wines')); inside the index function...

Create new entry (One to One Polymorphic relationship)

Premise
I am creating a small app with User profiles that can host a list of items of different types.
Each Item can be a Link, Card, Video. So each layout can be optimized accordingly. A bit like Tumblr, if you like.
The setup
For this reason, I've opted to use a one-to-one a polymorphic relationship (maybe overkill?), with an items table that has additional columns like position (so that a user can reorder the items).
The items table:
id
user_id (foreign key)
itemable_id
itemable_type
position
...
My models look like:
Item model
public function itemable()
{
return $this->morphTo();
}
public function user()
...
Link model
public function item()
{
return $this->morphOne('\App\Item', 'itemable');
}
public function user()
...
Card model
public function item()
{
return $this->morphOne('\App\Item', 'itemable');
}
public function user()
...
…and so on for the other Item types.
Finally, in ItemController, I'm creating a dummy Link for debug purposes:
// ...
$newLink = new Link();
$newLink->url = 'example.org';
$newLink->title = 'Example Website NEW';
$newLink->user_id = $user->id;
$user->items()->save($newLink);
// ...
But, unlike how I expected, the new entry in the items table doesn't get created. I have to that myself instead, manually once I've stored the $newLink Link.
The question
Is this normal? I would have expected to have Link (with itemable_id and itemable_type created automatically.
If so, I'm definitely missing something here. How can I make Laravel create the items entry automatically?
use associate so it will be like below:
$user->items()->associate($newLink);

Laravel ORM relationship - manager-employee over the same table of users

I have a user_managers pivot table that gets both keys from the users table:
employer_user_id
employee_user_id
I believe users would have a many to many relationship as a user can be managed by more than 1 manager there will be users who manage 1 or more users, while other users (excluding those under them) would manage them while there will be users who don't manage at all and a User can have only 1 manager.
My first try at defining this was to build another model named Manager representing the user_managers pivot table, so in User model I wrote the following 2 functions:
public function managedBy()
{
return $this->belongsToMany('Manager', 'employer_user_id');
}
public function manages()
{
return $this->hasMany('Manager', 'employee_user_id', 'employer_user_id');
}
Does this make sense or do you know of a better way to implement this kind of structure?
If a user can have only 1 manager then you can define you relationship as one to many like
//User model
public function managedBy()
{
return $this->belongsTo(User::class, 'manager_id');
}
public function managees()
{
return $this->hasMany(User::class, 'manager_id');
}
you don't need to pass $id to your relationship definition.
For multiple managers, Yes you would need a many to many relationship by adding a junction/pivot table which i guess you already have user_managers, Now you need to define your relationships using belongsToMany for managers and mangees like
public function managers()
{
$this->belongsToMany(User::class, 'user_managers', 'employer_user_id')
}
public function managees()
{
$this->belongsToMany(User::class, 'user_managers', 'employee_user_id')
}

How to setup conditional relationship on Eloquent

I have this (simplified) table structure:
users
- id
- type (institutions or agents)
institutions_profile
- id
- user_id
- name
agents_profile
- id
- user_id
- name
And I need to create a profile relationship on the Users model, but the following doesn't work:
class User extends Model
{
public function profile()
{
if ($this->$type === 'agents')
return $this->hasOne('AgentProfile');
else
return $this->hasOne('InstitutionProfile');
}
}
How could I achieve something like that?
Lets take a different approach in solving your problem. First lets setup relationship for the various models respectively.
class User extends Model
{
public function agentProfile()
{
return $this->hasOne(AgentProfile::class);
}
public function institutionProfile()
{
return $this->hasOne(InstitutionProfile::class);
}
public function schoolProfile()
{
return $this->hasOne(SchoolProfile::class);
}
public function academyProfile()
{
return $this->hasOne(AcademyProfile::class);
}
// create scope to select the profile that you want
// you can even pass the type as a second argument to the
// scope if you want
public function scopeProfile($query)
{
return $query
->when($this->type === 'agents',function($q){
return $q->with('agentProfile');
})
->when($this->type === 'school',function($q){
return $q->with('schoolProfile');
})
->when($this->type === 'academy',function($q){
return $q->with('academyProfile');
},function($q){
return $q->with('institutionProfile');
});
}
}
Now you can access your profile like this
User::profile()->first();
This should give you the right profile. Hope it helps.
you can do this by use another method please check this:
a blog Post and Video model could share a polymorphic relation to a
Tag model. Using a many-to-many polymorphic relation allows you to
have a single list of unique tags that are shared across blog posts
and videos. First, let's examine the table structure:
https://laravel.com/docs/5.4/eloquent-relationships#many-to-many-polymorphic-relations
Looks like that should be $this->type rather than $this->$type - since type is a property, not a variable.

Laravel hasManyThrough, with belongs to between the other two models

Not sure how clear is the question title, I will try to elaborate:
Tables:
repairs (Model: Repair):
id
id_supplier
id_store
suppliers (Model: Supplier):
id
store (Model: Store):
id
Relations:
Repair:
public function supplier() {
return $this->belongsTo('App\Supplier', 'id_supplier');
}
Supplier:
public function repairs() {
return $this->hasMany('App\Repair', 'id_supplier');
}
Store:
public function repairs() {
return $this->hasMany('App\Repair', 'id_store');
}
What i need from here is to get the collection of all suppliers a given store worked with, through the repairs that were made there, so my first thought it was hasManyThrough, but no ideia what to pass as 4º parameter:
Store:
public function suppliers() {
return $this->hasManyThrough('App\Supplier', 'App\Repair', 'id_supplier', '<NO IDEIA WHAT'S HERE>');
}
What am I missing? Is this the right way?
I think you can't use HasManyThrough here. Try something like this in your code:
$store = Store::with('repairs.supplier')->find($id_store);//eager load
$repairs = $store->repairs->pluck('supplier');//get array of suppliers id
$suppliers = (new Collection($repairs))->unique();//get unique collection of suppliers (without duplicates)
where $id_store is id of store which suppliers you want to get

Resources