Reputation: 4682
I have the following table structure in MySQL database:
Products
id - integer
name - string
user_id -string
Users
user_id - string
password - string
person_id - integer
Persons
person_id - integer
name - string
email - integer
I am using hasOneThrough
relationship on Products model to get the details about the Person
, who is linked through Users
. The code that defines the relation is as follows :
public function product_user()
{
return $this->hasOneThrough(
'App\Person',
'App\User',
'person_id',
'person_id',
'user_id',
'user_id'
);
}
But I am getting null
when I try to access the property product_user
, it is giving me null
all the time. I cannot change the database structure. How can I define a proper relationship in this scenario ?
Upvotes: 1
Views: 1538
Reputation: 3764
I always find the documentation for customized relationships a little bit lacking. I will expand on HasOneThrough here:
Lets say A has one C through B.
This relationship means the following would be our schema:
model_a
| a_id | name |
model_b
| b_id | model_a_id | name |
model_c
| c_id | model_b_id | name |
To write out our relationship explicitly defining the keys:
class ModelA extends Model
{
...
public function cModel()
{
return $this->hasOneThrough(
ModelC::class,
ModelB::class,
'model_a_id', // Key on B that relates to A
'model_b_id', // Key on C that relates to B
'a_id', // Key on A that relates to B
'b_id', // Key on B that relates to C
);
}
So for your case, it won't quite work. You would like to have "Products has one Person through User", but you actually have "Product belongs to User which belongs to Person" which means you need this custom package (staudenmeir/belongs-to-through) to add that relationship. You can use it like so:
User.php
public function person()
{
return $this->belongsTo(Person::class, 'person_id', 'person_id');
}
Products.php
use \Znck\Eloquent\Relations\BelongsToThrough;
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'user_id');
}
public function person()
{
return $this->belongsToThrough(
Person::class,
User::class,
null, // PK on products, null === 'id'
'', // The foreign key prefix for the first "through" parent model, in case you need aliasing.
[
Person::class => 'person_id', // PK on persons
User::class => 'user_id', // PK on users
],
);
}
Upvotes: 5