Polymorphic relation in laravel for following a user - laravel

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');
}

Related

How do I retrieve all polymorphic relations for one model?

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?

Laravel self based polymorphic relationship

I have 3 tables:
categories
admins
users
Category can create users and admins. In categories table I have morphs field:
$table->nullableMorphs('userable');
And relations in Category model:
public function userable()
{
return $this->morphTo();
}
public function user()
{
return $this->morphOne(self::class, 'userable');
}
But when I tried do like this:
$category = Category::first();
$user = User::first();
$category->user()->save($user);
Get error with message:
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]:
Column not found: 1054 Unknown column 'userable_id' in 'field list'
(SQL: update users set userable_id = 1, userable_type =
App\Models\Category, users.updated_at = 2021-04-27 12:13:22 where
id = 1)'
How I can correctly create self morph relationship in laravel?
So I think that what you should be doing is adding to the User model and the Admin model the relation user you've added to the category, those models that have this relationship can be morphed into the category
class User {
...
public function user() {
return $this->morphOne(Category::class, 'userable');
}
...
}
class Admin {
...
public function user() {
return $this->morphOne(Category::class, 'userable');
}
...
}
so you can do your logic this way
$category = Category::first();
$user = User::first();
$user->user()->save($category);
and it will update you category record with userable_type beeing App\Models\User and userable_id beeing 1 or whatever the user id is
id
name
userable_type
userable_id
1
Category Test
App\Models\User
1
to make things easier you can create a trait and add that relationship to the trait
trait IsUserable {
public function user() {
return $this->morphOne(Category::class, 'userable');
}
}
and instead of adding the relationship to User and Admin model, you just use the trait instead
class User {
use IsUserable;
}
class Admin {
use IsUserable;
}

Issue with eloquent an relashionship many to many in laravel 6.0

I started to learn laravel 1 month ago and I have the next issue.
I have 2 models, user and role and they have M to N relationship, therefore I have 3 tables.
Class Role Class Role_User Class User
=========== =============== ===========
id | name id | user_id | role_id id | name | lastname
1 ADMIN 1 1 1 1 John Rambo
2 AUTOR 2 1 2
3 USER
In the models I have the next code
Model User
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user');
}
Model Role
public function users()
{
return $this->belongsToMany(User::class);
}
I need in my view to list all user with role ADMIN and I dont know waht code I need to put.
public function index($type)
{
$users = Role::all()->roles()->where('name', 'ADMIN');
return view('admin.user.list', compact('users'));
}
Could you help me pls?
Since you want a result composed of users, you need to launch your query on them. And dont forget to run the query with get() (this case), first(), find(..)....
$users = User::whereHas('roles', function ($role) {
$role->where('name','ADMIN');
})->get();
return view('admin.user.list', compact('users'));

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.

hasManyThrough Relationship for Eloquent laravel 4

After a lot of searching i couldn't find a real solution to my "problem", so if there any one how can help me, i’am all listening
…
I have tree models, Post, User and Profile
Post belongsTo user – user hasMany posts == One –to-Many relation
Profile belongsTo user – user hasOne profile == One-to-One relation
Database structure
User
---- id : primary key
---- email : string
---- name : string
…
Profile
---- id : primary key
---- user_id : foreign key
---- biography : text
---- facebook : strings
…
Post
---- id : primary key
---- user_id : foreign key
---- title : string
---- slug : string
---- body : text
…
User model
class User extends Eloquent {
public function posts(){
return $this->hasMany('Post');
}
public function profile(){
return $this->hasOne('Profile');
}
}
Profile model
class Profile extends \Eloquent {
public function user(){
return $this->hasOne('User');
}
}
Post model
class Post extends \Eloquent {
public function user(){
return $this->belongsTo('User');
}
}
HOW can i get the users biography (or any other properties) on profiles table through the posts
I hope i was clear enough
There's no hasManyThrough in your setup.
First fix this relationship:
//Profile
public function user(){
return $this->belongsTo('User');
}
Then simply:
$post->user->profile->biography;
$user->profile->biography;
There is no profiles data through the posts, since both post and profile belong to the user.
There's also another way to link posts and profiles tables:
// Post model
public function profile()
{
return $this->hasOne('Profile', 'user_id', 'user_id');
}
// Profile model
public function posts()
{
return $this->hasMany('Post', 'user_id', 'user_id');
}
Then:
$post->profile->biography;
$profile->posts; // collection of Post models
This way you save one query by not fetching the User model.

Resources