Reputation: 151
I need to filter the results given from a one to many relation directly from the model object, but I cant find the right way. Here, the relations:
I have a User model that can subscript to many companies (company model), and a company can have many users subscripted to it, so, is a many to many relation.
In every company, this user has a personal info, so, every user, could have many profiles (profile model) one for each company that is subscripted to. So It is a one to many relation.
Imagine I want to retrieve the company that a user is currently viewing directly from the model, this, Im achieving by filtering the many to many relation:
class User extends Authenticatable
{
///
public function obtainLoggedOnCompany()
{
return $this->belongsToMany('app\Company', 'user_company', 'id', 'company_id')->withPivot('selected')->wherePivot('selected', 1)
}
Then, if I want to return the selected company in a blade view I just call:
Auth::user()->obtainLoggedOnCompany->first();
All thanks to the withPivot and wherePivot clause.
Different is the case when I want to retrieve the registered profile of a currently selected company, I tried:
public function obtainSelectedProfile()
{
$SelectedCompany= $this->obtainLoggedOnCompany->first();
return $this->hasMany('app\Profile','user_id')->where('company_id', '=', $SelectedCompany->company_id);
}
But it throws a Trying to get property of non object Exception. Is there another way to filter one to many relations directly in the model relation function?
Iam using Laravel 5.2
Upvotes: 0
Views: 368
Reputation: 151
actually, this sentence works perfectly!:
public function obtainSelectedProfile()
{
$SelectedCompany= $this->obtainLoggedOnCompany->first();
return $this->hasMany('app\Profile','user_id')->where('company_id', '=',
$SelectedCompany->company_id);
}
My error was elswhere on my view!
Though I think Its a better practice to prepare the data on the controller before passing it to the view, because I would have to query to server every single time I want to get data from the user profile on the fly in the view.
Upvotes: 0
Reputation: 316
How about you do:
I assume that your Company.php model has
public function userProfile(){
return $this->hasMany('app\Profile','company_id');
}
And Try this on the controller:
$company_id=1; //suppose the current company viewing id is 1
$user = User::where('id',Auth::id())->with(['obtainLoggedOnCompany'=>function($query) use($company_id){
$query->where('company_id',$company_id);
$query->with(['company_user_profile'=>function($query){
$query->where('user_id',Auth::id());
$query->last();
}]);
//$query->last();
}])->first();
And you can fetch the profile using:
dd($user->obtainLoggedOnCompany->company_user_profile);
Upvotes: 1
Reputation: 550
You can achieve this by passing variable to eager loading and updating your relationship structure. Try this
User
Model:
class User extends Authenticatable
{
///
public function obtainLoggedOnCompany()
{
return $this->belongsToMany('App\Company', 'user_company', 'user_id', 'company_id');
}
}
Company
Model:
class Company extends Model
{
///
public function profile()
{
return $this->hasOne('App\Profile', 'company_id');
}
}
Example
A use case of this:
$user_id = 1;
$user = User::where('id', $user_id)->with(['company' => function($query) use ($user_id) {
return $query->with(['profile' => function($query2) use ($user_id) {
return $query2->where('user_id', $user_id);
}]);
}])->first();
// $user variable contains user details, company details, and profile
Upvotes: 1