Accessing Pivot table "3rd Model relationship" in Laravel Eloquent - php

I have this Many-to-Many relation Laravel Eloquent relationship
The Models are:
class Email extends Model //actually represent the email account
{
protected $table = 'emails';
protected $fillable = [
'user_id',
'name',
];
public function messages() {
return $this->belongsToMany(Message::class)->withPivot('email_subtype_id');
}
}
class Message extends Model //actually represent the email message
{
protected $table = 'messages';
protected $fillable = [
'subject',
'body ',
];
public function emails() {
return $this->belongsToMany(Email::class)->withPivot('email_subtype_id');
}
}
class EmailMessage extends Pivot //actually represent the pivot table
{
protected $table = 'email_message';
protected $fillable = [
'email_id',
'message_id',
'email_subtype_id',
];
public function email() {
return $this->belongsTo(Email::class);
}
public function message() {
return $this->belongsTo(Message::class);
}
//this is the relation to a third model called EmailSubtype
//I want to include this relation to the Pivot when using it
public function subtype() {
return $this->belongsTo(EmailSubtype::class, 'email_subtype_id');
}
}
class EmailSubtype extends Model //3rd Model need to be included with Pivot
{
protected $table = 'email_subtypes';
protected $fillable = [
'name'
];
public function pivotEmailSubtype(){
return $this->hasMany(Pivot::class, 'email_subtype_id');
}
}
I am able to do this in the Controller:
$email = Email::find(1);
foreach($email->messages as $message) {
$subtype_id = $message->pivot->email_subtype_id;
dd($subtype_id); //1 that relates to subtype: CC Email Account
//also I can get the name indirectly away from the relation as follows:
$subtypeName = EmailSubtype::find($subtype_id)->first()->name;
dd($subtypeName);
}
Here I am getting the email_subtype_id only by direct pivot relation but have to do extra work to get the related email sub-type name.
I need to get the email sub-type name [Directly] from the 3rd Model EmailSubtype relationship oneToMany [hasMany and belongsTo] that relates to Pivot model with EmailSubtype model using something like:
$message->pivot->subtypeName;
Any help please!

Use this:
public function messages() {
return $this->belongsToMany(Message::class)->withPivot('email_subtype_id')
->using(EmailMessage::class);
}
$message->pivot->subtype->name

Related

How to obtain three level model data laravel

Updated
User model
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens, HasRoles;
const MALE = 'male';
const FEMALE = 'female';
protected $guard_name = 'sanctum';
public function educationalBackgrounds()
{
return $this->hasMany("App\Models\Users\EducationalBackground", "user_id");
}
public function seminars()
{
return $this->hasMany("App\Models\Users\Seminar", "user_id");
}
}
I have child table EducationalBackground which is related to User table
class EducationalBackground extends Model
{
use HasFactory;
protected $table = 'users.educational_backgrounds';
protected $fillable = [
'user_id',
'studies_type',
'year',
'course',
];
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function educationalAwards()
{
return $this->hasMany("App\Models\Users\EducationalAward", "educational_background_id");
}
}
And a third table that i want to access the award field
class EducationalAward extends Model
{
use HasFactory;
protected $table = 'users.educational_awards';
protected $fillable = [
'educational_background_id',
'award',
'photo',
];
public function educationalBackground()
{
return $this->belongsTo('App\Models\Users\EducationalBackground', 'educational_background_id');
}
}
I have api get route here
Route::get('/educational-background/{id}', [UserProfileController::class, 'getEducationalBackground']);
Here is my api method it works fine. But i want to go deeper and access the data of third table.
public function getEducationalBackground($id)
{
$educationalBackground = EducationalBackground::with('user')->where('user_id', $id)->get();
return response()->json($educationalBackground, 200);
}
It looks like you're not really grasping the concept of relations yet. Also, I'd advise you to look into route model binding :) What you basically want to be doing is:
public function getEducationalBackground($id)
{
$user = User::find($id);
return $user->educationalBackgrounds()->with('educationalAwards')->get();
}
Also, when you're pretty sure that whenever you want to use backgrounds, you also want to use the awards, you can add the with(...) to the model definition like so:
class EducationalBackground extends Model
{
...
protected $with = ['educationalAwards'];
}
That way, you can simplify your controller method to:
public function getEducationalBackground($id)
{
$user = User::find($id);
return $user->educationalBackgrounds;
}

laravel eloquent: many to many relations

I would like to add some items in my db table pivot using eloquent ->attach but i don' t understand why it don't work:
I have 2 models (Salade=>(table 'salades' in DB) and Ingredient=>(table 'ingredients' in DB),
the pivot table is ingredient_salade( 3columns : id, ingredient_id,salade_id).
My Models:
class Ingredient extends Model
{
protected $table = 'ingredients';
protected $fillable = ['nom'];
public function Salades()
{
return $this->belongsToMany('App\Salade');
}
}
class Salade extends Model
{
protected $table = 'salades';
protected $fillable = ['nom','prix'];
public function ingredients()
{
return $this->belongsToMany('App\Ingredient');
}
}
SaladeController#Store
public function store(Request $request)
{
$this->validate($request, [
'nom' => 'required',
'prix' => 'required' ]);
$salade = $request->only(['nom', 'prix']);
// insert new salade in DB
$lanouvelleSalade = \App\Salade::create($salade);
//insert relation in pivot table
$lanouvelleSalade->ingredients()->attach([21,22,23]);
return redirect('salade')->withOk("Le Salade " . $request->input('name') . " a été modifié.");
}
the tables:
image of the tables
the new salade is insert in table salades but the relation in Pivot is not insert. Why?
change:
$lanouvelleSalade->ingredients()->attach([21,22,23]);
to:
$lanouvelleSalade->ingredients()->sync([21,22,23]);
replace your relation codes with this codes and check it:
Ingredient Class:
public function Salades()
{
return $this->belongsToMany('App\Salade','ingredient_salade','ingredient_id','salade_id');
}
And Salade Class:
public function ingredients()
{
return $this->belongsToMany('App\Ingredient','ingredient_salade','salade_id','ingredient_id');
}
let me know if you have any error

Laravel retrieve values from foreign key

I have these models with their related db tables,at the moment I can retrieve all the requirement
Requirement::all()
but I just have a list of foreigns key (destination_id,applier_id,doc_id). How can i retrieve directly the row connected to that foreigns key?
class Requirement extends Model
{
protected $fillable = [
'required',
'destination_id',
'applier_id',
'doc_id'
];
public function destination()
{
return $this->belongsTo(Destination::class);
}
public function applier()
{
return $this->belongsTo(Applier::class);
}
public function doc()
{
return $this->belongsTo(Doc::class);
}
}
class Doc extends Model
{
protected $fillable = [
'type',
'description',
'note'
];
public function requirements()
{
return $this->hasMany(Requirement::class);
}
}
class Destination extends Model
{
protected $fillable = [
'country',
'passying_country',
'transfer_conditions',
'passing_conditions'
];
public function requirements()
{
return $this->hasMany(Requirement::class);
}
}
You can call with() function instead of all(). So if you try this following :
$requirements = Requirement::with('destination', 'applier', 'doc')->get();
Make it dd($requirements) and look the output.
Hope it will work.

Accessing nested relationship with Laravel 4

I'm having trouble figuring out how to access a nested relationship within Laravel. The specific example I have is a Movie that has many entires in my Cast table which has one entry in my People table. These are my models:
MOVIE
class Movie extends Eloquent {
protected $primaryKey = 'movie_id';
protected $table = 'movie';
// Relationships
public function cast()
{
return $this->hasMany('MovieCast', 'movie_id');
}
}
MOVIECAST
class MovieCast extends Eloquent {
protected $table = 'movie_cast';
public function person()
{
return $this->hasOne('Person', 'person_id');
}
public function netflix()
{
return $this->belongsTo('Movie', 'movie_id');
}
}
PERSON
class Person extends Eloquent {
protected $primaryKey = 'person_id';
protected $table = 'people';
public function movieCast()
{
return $this->belongsTo('MovieCast', 'person_id');
}
}
In my controller I can access the cast (containing person_id and role_id) like so:
public function movie($id)
{
$movie = Movie::find($id);
$cast = $movie->cast();
return View::make('movie')->with(array(
'movie' => $movie,
'cast' => $cast
));
}
...but I don't know how to access the corresponding name field in my People table.
EDIT 1:
Using the classes exactly as defined below in #msturdy's answer, with the controller method above I try to render the person names like so inside my view:
#foreach($cast->person as $cast_member)
{{$cast_member->person->name}}
#endforeach
Doing this i get the error:
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$person
I don't know if it makes a difference or not but I have no id field on my People table. person_id is the primary key.
It should be simple, once you have accessed the cast...
Route::get('movies', function()
{
$movie = Movie::find(1);
$cast = $movie->cast;
return View::make('movies')->with(array(
'movie' => $movie,
'cast' => $cast));
});
Note: at this point, $cast is an instance of the Collection class, not a single object of the MovieCast class, as the
relationship is defined with hasMany()
you can iterate over it in the View (in my case /app/views/movies.blade.php
#foreach($cast as $cast_member)
<p>{{ $cast_member->person->name }}</p>
#endforeach
Class definitions used for testing:
class Movie extends Eloquent {
protected $primaryKey = 'movie_id';
protected $table = 'movie';
public $timestamps = false;
// Relationships
public function cast()
{
return $this->hasMany('MovieCast', 'movie_id');
}
}
class MovieCast extends Eloquent {
protected $table = 'movie_cast';
public $timestamps = false;
public function person()
{
return $this->hasOne('Person', 'person_id');
}
}
class Person extends Eloquent {
protected $primaryKey = 'person_id';
protected $table = 'people';
public $timestamps = false;
public function movieCast()
{
return $this->belongsTo('MovieCast', 'person_id');
}
}

How to use the `where` method along with the `with` method in laravel 4?

Given the following, very simple, example:
Country Class
class Country extends Eloquent {
protected $table = "countries";
protected $fillable = array(
'id',
'name'
);
public function state() {
return $this->hasMany('State', 'country_id');
}
}
State Class
class State extends Eloquent {
protected $table = "states";
protected $fillable = array(
'id',
'name',
'country_id' #foreign
);
public function country() {
return $this->belongsTo('Country', 'country_id');
}
}
How can I list all the states, based on the id or the name of the country.
Example:
State::with('country')->where('country.id', '=', 1)->get()
The above returns an area, as country is not part of the query (Eloquent must attach the join later, after the where clause).
I think you're either misunderstanding the relations or over-complicating this.
class Country extends Eloquent {
public function states() {
return $this->hasMany('State', 'state_id');
}
}
$country = Country::find(1);
$states = $country->states()->get();

Categories