Eloquent Relationship. Has Many relation with different keys - laravel

Background
I have a model, Contract that belongs to the User model through two keys, user_id and recipient_id. How would I be able to query all the contracts for a user using $user->contracts keeping the two key into consideration.
\App\Contract model has this
$protected $fillable = [
...
'user_id',
'recipient_id',
...
];
public function user ()
{
return $this->belongsTo(User::class);
}
public function recipient()
{
return $this->belongsTo(User::class, 'recipient_id', 'id');
}
\App\User model has this
public function contracts ()
{
return $this->hasMany(Contract::class);
}
To get the user contracts, I have to do this
$contracts = Contract::where('user_id', $user->id)
->orWhere('recipient_id', $user->id)
->get();
What I would like is something like this. \App\Contract
public function user () {
return $this->belongsTo([User::class, User::class], ['user_id', 'recipient_id']);
}
I am aware of https://github.com/staudenmeir/eloquent-has-many-deep and it doesn't solve my problems.
How do I go about it?

I couldn't find a way, so, I ended doing this in ContractController.php
public function index()
{
$user = Auth::user();
if ($user->isAdmin()) {
return Contract::latest()->get();
}
$contracts = Contract::where('user_id', $user->id)
->orWhere('recipient_id', $user->id)
->get();
return $contracts;
}

Related

How would I edit the Laravel Nova indexQuery for a Resource to only show records through multiple relationships?

firstly thank you in advance.
I have the following Models , User , Location, Listing, Offer.
The relationships are:
User Model:
public function location()
{
return $this->hasOne(Location::class);
}
Location Model:
public function listings()
{
return $this->hasMany(Listing::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
Listing Model:
public function offers()
{
return $this->hasMany(Offer::class);
}
public function location()
{
return $this->belongsTo(Location::class);
}
Offer Model:
public function listing()
{
return $this->belongsTo(Listing::class);
}
In my Offer Resourse I would like to show only the offers that belongTo the listings that in turn belongsTo the location that in turn belongTo the authenticated user. I have tried the following.
public static function indexQuery(NovaRequest $request, $query)
{
$user = Auth::user();
if ($user->is_admin === 1){
return $query;
}elseif($user->is_admin === 0) {
return $user->location->listings->offers;
}
}
But get an error Property [offers] does not exist on this collection instance. Any assistance will be greatly appreciated.
I would try something like this.
More information here on querying relationship existence:
https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence
public static function indexQuery(NovaRequest $request, $query) {
$user = Auth::user();
if (!$user->is_admin) {
$query = $query->whereHas('listings.location.user', function ($builder) use ($user) {
return $builder->where('id', $user->id);
});
}
return $query;
}
The reason you are getting the "Property does not exist" error is due to you not pulling it from database.
Two alternative solutions include
Querying them separately: ...->listings()->offers()
Eager loading: ->with(['location.listings.offers']);

Laravel Single User Data In A Multichained Distant Relationship

I have three models as per the code below.I have a problem of returning a single savings data for authenticated users. Any help will be highly appreciated.
I want a low like this:
$savings =Savings::client()->client_users()->where('user_id', '=', Auth::user()->id)->get();
Savings Model
class Savings extends Model
{
public function client()
{
return $this->hasOne(Client::class, 'id', 'client_id');
}
}
Client Model
class Client extends Model
{
public function client_users()
{
return $this->hasMany(ClientUser::class, 'client_id', 'id');
}
}
Client User Model
class ClientUser extends Model
{
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
}
You can try this query:
$user = Auth::user();
return Savings::whereHas('client.client_users', function ($query) use ($user){
$query->where('user_id', $user->id);
}])->get();
I have fixed the above error. Thanks #Maik Lowrey
$user = Auth::user();
$savings= Savings::whereHas('client.client_users', function ($query) use ($user){
$query->where('user_id', $user->id);
})->get();
return response()->json($savings);
//return response($savings);

how to connect multiple tables with Laravel models

I am using Laravel 7.
I want to retrieve all the users that are active and belong to Austria.
I would like to do that using laravel relationships.
There are three tables that should be connected through the models: countries, users and user_details.
Country.php:
public function user_details()
{
return $this->hasMany('App\UserDetail', 'citizenship_country_id', 'id');
}
User_detail.php:
public function country()
{
return $this->belongsTo('App\Country', 'citizenship_country_id', 'id');
}
public function user()
{
return $this->belongsTo('App\User', 'user_id', 'id');
}
User.php:
public function user_detail()
{
return $this->hasOne('App\UserDetail', 'user_id', 'id');
}
In the controller I used the following code to retrieve all austrian users that are active:
return Country::where('name', 'Austria')->first()->user_details()->first()->user()->where('active', '1')->get();
I should visualize two users but I get only one user. I suppose the error is the second first.
Can help?
Try This.
$users = User::whereHas('user_details.country', function ($query) {
$query->where('countries.name', "Austria");
})
->where("active",1)
->get();

simple One to many relationship laravel

i have a user(ADMIN) and a student i want them to be in one table that is on the dashboard controller i cant find and exact answer in the searching please help me
Student model
public function user()
{
return $this->belongsTo("App\User", 'User_id', 'id');
}
User model
public function student()
{
return $this->hasMany("App\Student");
}
DashboardController
$users = User::with('user_id');
return view('superadminpage.admin_table')->with('users', $users);
Edit Student model code like this:
public function user(){
return $this->belongsTo("App\User");
}
Also edit User model:
public function students(){
return $this->hasMany("App\Student");
}
then use in DashboardController
$users = User::query()->with("students")->all();
return view('superadminpage.admin_table')->with('users', $users );
then you can do this:
foreach($users as $user){
$students = $user->students;
// use
}
first change the User_id to user_id at student model
public function user()
{
return $this->belongsTo("App\User", 'user_id');
}
second change at DashboardController
$users = User::with('user_id'); to $users = User::with('student')->all();
first change the User_id to user_id at student model
public function user()
{
return $this->belongsTo("App\User", 'user_id' , 'id');
}
second change at DashboardController
$users = User::with('user_id'); to $users = User::with('student')->all();
it's also good to change at user model public function student() to public function students() and call at DashboardController $users = User::with('students')->all();
public function users()
{
return $this->hasMany('App\User');
}
public function role()
{
return $this->belongsTo('App\Role');
}

How to get posts of people I am following in Eloquent

I have a User model, a Post model.
In my User model, I have the following:
public function followers()
{
return $this->belongsToMany(User::class, 'followers', 'follower_id', 'user_id')->withTimestamps();
}
public function following()
{
return $this->belongsToMany(User::class, 'followers', 'user_id', 'follower_id')->withTimestamps();
}
public function posts()
{
return $this->hasMany(Post::class);
}
So basically, $user->following gives me a collection of users I am following and $user->posts gives me the collection of posts. I want to do this:
$posts = [];
$user->following->each(function($f) use($posts) {
$posts[] = $f->posts;
});
but more Eloquenty way, if that makes sense. Because I want to paginate the result after this. I was thinking of doing hasManyThrough, but cannot figure out how?
Here is link to similar question with an answer.
I think you wan tot do something like this:
User::where('id', $id)->with(['following.posts' => function ($q) use (&$posts) {
$posts= $q->get()->unique();
}])->first();

Resources