I have a Payment model that belongs to a FinancialGoal model which in turn belongs to a User model. I have these relationships methods defined:
Payment model:
public function financialGoal()
{
return $this->belongsTo(FinancialGoal::class);
}
public function user()
{ //not sure this is correct
return $this->hasOneThrough(User::class, FinancialGoal::class);
}
User model:
public function financialGoals()
{
return $this->hasMany(FinancialGoal::class);
}
public function payments()
{
return $this->hasManyThrough(Payment::class, FinancialGoal::class);
}
Financial Goal model:
public function user()
{
return $this->belongsTo(User::class);
}
public function payments()
{
return $this->hasMany(Payment::class);
}
The question is how do I define the inverse of the payments method in the user model, in the payment model. I have used one of these two definitions on the payment model at some point and both work but just not sure if it's OK to use either and would love to know the correct approach.
public function user()
{
return $this->financialGoal->user();
}
public function user()
{ // had to ignore static analysis error for this but it returns the relationship
return $this->financialGoal->belongsTo(User::class);
}
Based on your relationships, I'm guessing this is your table structure
payments |
---|
id |
financial_goal_id |
financial_goals |
---|
id |
user_id |
users |
---|
id |
Your first user
relationship on the Payment
model ( $this->hasOneThrough(User::class, FinancialGoal::class)
) is incorrect as you need the inverse of it. It's not well documented in the Laravel docs, but if you play around with all the parameters of the hasOneThrough
method you can achieve your goal. The user relationship would look like
class Payment extends Model
{
public function user()
{
return $this->hasOneThrough(User::class, FinancialGoal::class, 'id', 'id', 'financial_goal_id', 'user_id');
}
}
This would be better than your other two attempts as this can be Eager loaded with ease and doesn't rely on other existing relationships.