Laravel BelongsTo Through relationship

9k Views Asked by At

How to implement BelongsToThrough Relationship in Laravel?

I have Table:

**projects_table**
id 

**categories_table**
id
project_id 

**properties_table**
id
category_id

Category BelongsTo Project

public function project(){
    return $this->belongsTo('App\Project');
}

Property BelongsTo Category

public function category(){
    return $this->belongsTo('App\Category');
}

How can we make a relationship?

Property BelongsTo Project Through Category

public function project(){
     return $this->belongsToThrough('App\Project', 'App\Category');
}

EDIT QUESTION.

Because I want to do multi-tenancy on my application, and the tenancy is PORJECT. I want to separate Category and Property by Project.

CATEGORY is belongsTo PROJECT PROPERTY is belongsTo CATEGORY

so I want to make relationship between PROPERTY and PROJECT via CATEGORY. for now, I need to add: project_id on both categories and properties tables and I think that this is not the right way.

4

There are 4 best solutions below

2
zahid hasan emon On

Your property belongsTo is incorrect. Property belongs to Category.

public function category(){
    return $this->belongsTo('App\Category','category_id');
}

Now you can get project from property like below:

{{ $property->category->project->project_attribute }} 
11
Prafulla Kumar Sahu On

I think you can do $project->category->property as you have a one-to-one relationship between Project and Category and again a one-to-one relationship between Category and property, beside this, if you want to define a relationship between Project and Property through you may consider has-one-through relaationship.

In Project model

public function property()
{
    return $this->hasOneThrough('App\Property', 'App\Category');
}

and in Property model

public function property()
{
    return $this->hasOneThrough('App\Project', 'App\Category');
}

May be

In that case, you can also do something like

in Property model

public function project()
{    
   return $this->category->project( or projects);

   // or if Category and properties have many-to-many relationship you can do 
   return $this->categories->with('projects')->get();
}
0
Dilip Hirapara On

You can't make it like this. If you want to access project Using properties. Then check this following steps which I mention as per your requirement.

Category.php Model

public function project(){
    return $this->belongsTo('App\Project','project_id','id');
}

Property.php model here you're doing wrong. You can access it directly you've to made relationship with categories first and from categories will get project.

Property BelongsTo Category

public function categories(){
    return $this->belongsTo('App\Category','category_id','id');
}

Now if you want to access it from controller then you may use with();

$property = Property::with('categories.project')->first();

Here you'll get $property->categories->project->name

Note: If you want to get property from the project then you can use hasOneThrough but inverse relation you can't make it.

1
leevanoetz On

You want to use hasOneThrough with all keys specified like so

public function project()
    {
        return $this->hasOneThrough(
            Project::class,
            Category::class,
            'id', # foreign key on intermediary -- categories
            'id', # foreign key on target -- projects
            'category_id', # local key on this -- properties
            'project_id' # local key on intermediary -- categories
        );
    }