How do I retrieve all polymorphic relations for one model? - laravel

I have setup a User model to be able to be linked with a polymorphic many to many to 3 models, let's call them A, B and C.
I have setup the models as follows:
// User.php
public function a(): MorphToMany
{
return $this->morphedByMany(A::class, 'shareable')->withPivot('view_mode');
}
public function b(): MorphToMany
{
return $this->morphedByMany(B::class, 'shareable')->withPivot('view_mode');
}
public function c(): MorphToMany
{
return $this->morphedByMany(C::class, 'shareable')->withPivot('view_mode');
}
// A, B and C.php
public function users(): MorphToMany
{
return $this->morphToMany(User::class, 'shareable');
}
Of course I created a pivot table to store the relations.
I am now trying to find a way to find ALL relations linked to a given user based on the pivot table. Let's say this is currently my data:
user_id
view_mode
shareable_type
shareable_id
1
RW
App\Models\A
1
1
R
App\Models\A
2
1
W
App\Models\B
5
2
R
App\Models\A
2
1
W
App\Models\C
8
How can I retrieve all the related content for User with id 1?
My goal would be for it to look like this:
relations: [
a: [
- A entity with id 1
- A entity with id 2
],
b: [
- B entity with id 5
],
c: [
- C entity with id 8
]
]
I tried by created a model named Shareable, and adding the following:
protected $table = 'shareables';
public function shareable()
{
return $this->morphTo();
}
public function a()
{
return $this->morphedByMany(A::class, 'shareable');
}
I then added the following to the User model:
public function shared()
{
return $this->hasMany(Shareable::class)->with('a');
}
But when I call it by doing
$user->shared
I don't get my a instances, only an empty collection.
What am I doing wrong?

Related

Getting issue while fetching data using Relationship in laravel7

I have three table country, state, customer_contacts. I want display all customer details into list view structure. But in my customer table only id save of country and state respectively. I want to fetch Country nad state Name from other two table .
Table structure as follows :
1. Country
id name
1 India
2 Canada
2. State
id name country_id
1 Mumbai 1
2 Delhi 1
3 abc 2
4 xyz 2
3. Customer_contact
id c_name country_id state_id
1 abcdee 1 2
2 xyzerr 1 1
3 extraa 2 3
4 newsss 2 4
i want to fetch customer name with country name and state name.
I am using below query to fetch data but getting only customer_contact data how to fetch name using any query or relationship.
$data = CustomerContact::with('Country', 'State')->get();
I am using relationship as follow:
1) Country Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
public function state()
{
return $this->hasMany(State::class);
}
public function customercontact()
{
return $this->hasMany(CustomerContact::class);
}
}
2) State Model
class State extends Model
{
public function customercontact()
{
return $this->hasMany(CustomerContact::class);
}
public function country()
{
return $this->belongsTo(Country::class);
}
}
3) CustomerContact
use Illuminate\Database\Eloquent\Model;
class CustomerContact extends Model
{
protected $guarded = [];
public function country()
{
return $this->belongsTo(Country::class);
}
public function state()
{
return $this->belongsTo(State::class);
}
}
I want show data in list view like CustomerName, CountryName,StateName.
When i do
dd($data)
getting data with country and state id but relationship getting null value.
Help me in this.
On CustomerSupport you defined two function country() and state(), so your code will be :
$data = CustomerContact::with('country','state')->get();
Or,
$data = CustomerContact::with('country')->with('state')->get();

Laravel how to define 3 relationships with one model?

I have a Model which is called Championship. Championship may have 3 judges which are called Main Judge, Main Secretary and Judge Operator.
All of them linked to User Model and stored in the database as user ID.
My relationships looks like this
class Championship extends Model
{
protected $table = 'championships';
public function mainJudge()
{
return $this->hasOne('App\User', 'id', 'main_judge');
}
public function mainSecretary()
{
return $this->hasOne('App\User', 'id', 'main_secretary');
}
public function judgeOperator()
{
return $this->hasOne('App\User', 'id','judge_operator');
}
}
But I can't undertand how to define inverse relationship in User model
class User extends Authenticatable
{
public function sex()
{
return $this->belongsTo('App\Models\Sex');
}
public function player()
{
return $this->hasOne('App\Models\Player', 'user_id');
}
public function championship()
{
????
}
You just have to add it like you are adding other relations :
public function championship()
{
return $this->belongsTo('App\Championship');
}
When you do :
$championship = Championship::find($id);
$mainJudge = $championship->mainJudge;
$mainSecretary = $championship->mainSecretary;
// All objects will be exactly same
dd($mainJudge->championship,$mainSecretary->championship,$championship);
I assume all the user records have a foreign key to championships table championship_id
When you call the $user->championship relation it will return you the championship wrt to its foreign key championship_id
No need to worry you are just confusing the inverse relations:
See it this way:
Your mainJudge, mainSecretary, judgeOperators are of type App\User and every user have a championship_id when you will call the (App\User)->championship it will always return you its respective championship or null if the championship_id is empty.
Its just matter of perspective.
Just try the above code it will clear out your confusion.

BelongsToMany with one or vice versa relationship

I'm using Laravel and Eloquent.
I have a courses table and a Pivot table that holds the related courses.
My pivot table named relatedCourses has 2 columns, course1 & course2.
In the above example, Course ID 5 is related with Course ID 7.
$data["course"] = course::where("isActive",1)->with('related')->find(5);
This works and brings ID 7 as related.
If i try
$data["course"] = course::where("isActive",1)->with('related')->find(7) it should bring ID 5 as related, this is what i'm trying to achieve.
My code is like this in the model :
class course extends Model
{
public function category()
{
return $this->hasOne('App\courseCategory',"categoryId");
}
public function related()
{
return $this->belongsToMany('App\Models\course', 'relatedCourses', 'course1', 'course2');
}
}
You can define two relationships for this query.
class course extends Model
{
public function category()
{
return $this->hasOne('App\courseCategory',"categoryId");
}
public function relatedCourses()
{
return $this->belongsToMany('App\Models\Course', 'relatedCourses', 'course1', 'course2');
}
public function originalCourses()
{
return $this->belongsToMany('App\Models\Course', 'relatedCourses', 'course2', 'course1');
}
}
Then you can query your relations,
$data["course"] = course::where("isActive",1)->with('relatedCourses')->find(5);
and
$data["course"] = course::where("isActive",1)->with('originalCourses')->find(7);
To merge both relations you can do like this
$course = course::where("isActive",1)->with('originalCourses', 'relatedCourses')->get();
Hope this will help you.

Laravel Eloquent relationship only returns minimal results

Tables:
Posts
id | console_id | game_id | etc
Games
id | name
Console
id | name
Now when i am querying this relationship I am constantly getting the "Trying to get property of non-object" error. Now if i limit my results to say the top 3 (which is all i have in the games table) then it will run but anything more then that it will throw the exception... is the relationship wrong?
Relationships:
Game
public function Post()
{
return $this->belongsTo('App\Post', 'game_id');
}
Post
public function console()
{
return $this->hasOne('App\Console', 'id');
}
public function games()
{
return $this->hasOne('App\Game', 'id');
}
Console
public function Post()
{
return $this->belongsTo('App\Post', 'console_id');
}
Update
#joel #rashmi So actually dumping the $post I am seeing this on my 4th entry... it is returning NULL
["relations":protected]=>
array(2) {
["games"]=>
NULL
The first 3 return values. But then the 4th on are all returning NULL's. Again i have only 3 values in the Games table
Games Table:
1 | game 1
2 | game 2
3 | game 3
And actually on the third entry it it has a value of 2 but showing game 3 name
posts table:
id | game id
1 | 2
2 | 3
3 | 2 (but showing "game 1" text)
Looks like your posts each belong to a console and a game - not the other way around. And hasOne means there can only ever be one, but each console and game can have many posts. So it should be like this:
// Game
public function posts()
{
return $this->hasMany('App\Post');
}
// Post
public function console()
{
return $this->belongsTo('App\Console');
}
public function game()
{
return $this->belongsTo('App\Game');
}
// Console
public function posts()
{
return $this->hasMany('App\Post');
}
If your tables are named consoles, games, and posts, respectively, then you don't need to supply the ids, so I removed them. You can just re-add them if you need to.
It seems that your relationships are not proper. It should be like this:
// Game Model
public function posts()
{
return $this->hasMany('App\Post');
}
// Post Model
public function console()
{
return $this->belongsTo('App\Console');
}
public function game()
{
return $this->belongsTo('App\Game');
}
// Console Model
public function posts()
{
return $this->hasMany('App\Post');
}
And your Eloquent Query for post will be:
$this->model->select(SELECTED_FIELDS)
->with(array('game','console'))
->get();
where SELECTED_FIELDS means table fields you want to fetch.

Polymorphic relation in laravel for following a user

I've a User model and a likes table. I applied polymorphic relation to it.
likes table has the following structure:
user_id --- likeable_id ---- likeable_type
eg: 1 ---- 5 ---- App\User //This indicates user 1 follows 5
eg: 3 ---- 1 ---- App\User //This indicates user 3 follows 1
Now I'm trying to get the followers and following list.
In the User model I added
public function likes()
{
return $this->morphMany(Like::class, 'likeable');
}
public function followers()
{
return $this->belongsTo('App\Like', 'likeable_id', 'user_id');
}
and from the controller, I've tried to do this:
$user1 = User::with('followers')->where('username', $username)->first();
But it's returning null for the followers relation. Am I doing it right?
Got the answer by myself: In User model -
public function followers()
{
return $this->morphMany('App\Like', 'likeable')->with('user');
}
public function following()
{
return $this->morphMany('App\Like', 'user', 'likeable_type')->with('user');
}

Resources