Cannot call to model of polymorphic relation - laravel

I'm trying to reach a (ex.) visitable_id: 38 visitable_type: App\Thread in a polymorphic relationship. I can do it with the User with the code below, but can't seem to do it with the thread:
Blade:
#foreach ($visits as $visit)
#if($visit->visitable_type == 'App\User')
Viewing member profile {{ $visit->user->name }}
#endif
#if($visit->visitable_type == 'App\Thread')
Viewing thread <a href="/forums/{{ $visit->channel->slug }}/{{ $visit->slug }}/">
{{ $visit->title }}</a>
#endif
#endforeach
Controller:
$visits = Visit::where('user_id', $user->id)->get();
Models:
User:
public function visits()
{
return $this->morphMany(Visit::class, 'visitable');
}
public function visit()
{
return $this->morphOne(Visit::class, 'visitable');
}
Models: Visit:
public function user()
{
return $this->belongsTo(User::class);
}
public function thread()
{
return $this->belongsTo(Thread::class);
}
public function visitable()
{
return $this->morphTo();
}
Models: Thread:
public function visits()
{
return $this->morphMany(Visit::class, 'visitable');
}
public function visit()
{
return $this->morphOne(Visit::class, 'visitable');
}
Yeah I truly don't understand what is the issue here because I can get the visitable_id and visitable_type when it is the User, but not when it is a thread. Can anyone please help me?
Thank you!!

I have to call the relationship in the case of a thread (so $visit->visitable->channel->slug)

Related

How can I get video of specific model?

I want to display videos for each model in my table, where to define they are connected by their ids?
In my controller:
public function index()
{
$model_video = NewModelVideos::all();
return view('admin.model_new_videos.index')
->with('models', $models)
->with('model_video', $model_video);
}
in my Model:
class NewModelVideos extends Model
{
public function model()
{
return $this->belongsTo('App\Models\NewModels\NewModel', 'model_id');
}
}
class NewModel extends Model
{
public function videos()
{
return $this->hasMany('App\Models\NewModels\NewModelVideos', 'model_id', 'id');
}
}
and View:
#foreach($model_video as $model)
{{ $model->video }}
#endforeach
You should update your code like this:
public function index()
{
$model_video = NewModelVideos::all();
$models = NewModel::all();
return view('admin.model_new_videos.index')
->with('models', $models)
->with('model_video', $model_video);
}
and blade:
#foreach($models as $model)
{{ $model->videos }} //get videos
#endforeach
#foreach($model_video as $video)
{{ $video->model }} //get model
#endforeach

One-to-many and one-to-many relationship 1 laravel

i did this(sorry my english it's bad bad....)
controller:
public function index()
{
$lessons = course::find(1)->lesson;
return view('home',compact('lessons'));
}
model lesson
public function course() {
return $this->belongsTo(Course::class);
}
model courses
public function lesson() {
return $this->hasMany(Lesson::class);
}
blade
#foreach ($lessons as $lesson )
<h4>{{$lesson->title}}</h4>
#endforeach
in browser nothing appears
why?:(
First rename your lesson method with plural lessons.
// Course model
public function lessons() // plural
{
return $this->hasMany(Lesson::class);
}
Now get the lesson's collection.
public function index()
{
$lessons = Course::find(1)->lessons;
return view('home', compact('lessons'));
}
#foreach ($lessons as $lesson )
<h4>{{$lesson->course->title}}</h4>
#endforeach
Have you tried it like this:
return view('greeting')->with('lessons', $lessons);
Now you can call '$lessons' in your view. Take a look at this link
https://laravel.com/docs/5.6/views
Can you try to use return $lessons; and show me what it says?

Counting total posts by a user in the blade view

I have sent a collection of all posts in my blog to my index view and then used the following code to count the total posts made by each user.
<p class="joined-text">Posts: {{count(App\Posts::where('user_id', $post->user->id)->get())}}</p>
Is this bad practice to do this from within the blade view? If it is how would I achieve this?
Models
class Posts extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comments::class, 'post_id');
}
}
class User extends Authenticatable
{
public function posts()
{
return $this->hasMany('\App\Posts::class');
}
public function comments()
{
return $this->hasMany(Comments::class);
}
}
Simple solution:
<p class="joined-text">Posts: {{ App\Posts::where('user_id', $post->user_id)->count() }}</p>
Updated
Complete and better solution:
Post.php:
public function user(){
return $this->belongsTo(App\User::class);
}
User.php:
public function posts(){
return $this->hasMany(App\Post::class);
}
public function getPostsCountAttribute(){
return $this->posts()->count();
}
blade:
<p class="joined-text">Posts: {{ $post->user->posts_count }}</p>
Yes it is bad.
You could use relationships if have the user_id field in posts table
class User extends Model
{
public function posts()
{
return $this->hasMany('App\Post');
}
}
In controller
return view('sth')->with(['posts'=>$user->posts]);
Then in view
$posts->count();
Or just getting counts if you don't need posts
$postCount = $user->posts()->count();

Laravel Retrieve related model through pivot table

So i'm a bit confused with this situation, I have the current relations:
User hasmany Favourite
favourites references to a Recipe model
favourites is a pivot table but when I retrieve the favourites for a given user like:
$user->favourites
i get the favourite with the pivot data, but I want to get the fields of the recipe
Recipe.php:
public function favourites()
{
return $this->hasMany('App\Favourite');
}
User.php:
public function favourites()
{
return $this->hasMany('App\Favourite');
}
Favourite.php:
public function user()
{
return $this->belongsTo('App\User','user_id');
}
public function recipes()
{
return $this->belongsTo('App\Recipe','recipe_id');
}
EDIT : there was no problem at all, just needed to call:
#foreach($user->favourites as $favourite)
{{ $favourite->recipe->name }}
#endforeach
You need to set your relation to Has Many Through instead of just has Many.
https://laravel.com/docs/5.2/eloquent-relationships#has-many-through
Recipe.php:
public function favourites()
{
return $this->hasManyThrough('App\Favourite', 'App\User');
}
User.php:
public function favourites()
{
return $this->hasManyThrough('App\Favourite', 'App\Receipe');
}
Favourite.php:
public function user()
{
return $this->hasManyThrough('App\User','App\Receipe');
}

Laravel, Using two user relationships in model

Connection Model :
protected $table = 'connections';
protected $fillable = ['user_id_1','user_id_2','connection_status'];
public function user_id_1()
{
return $this->belongsTo('App\User', 'user_id_1');
}
public function user_id_2()
{
return $this->belongsTo('App\User', 'user_id_2');
}
Controller :
public function show($id){
$user_id_1_connections = Connection::whereUser_id_1AndConnection_status($id, 1)->get();
$user_id_2_connections = Connection::whereUser_id_2AndConnection_status($id, 1)->get();
return view('connection.showConnection',['user_id_1_connections' => $user_id_1_connections, 'user_id_2_connections' => $user_id_2_connections]);
}
Blade:
#foreach($user_id_1_connections as $user_id_1_connection)
{{ $user_id_1_connection->user_id_1 ? $user_id_1_connection->user_id_1->name : 'unknown' }}
#endforeach
#foreach($user_id_2_connections as $user_id_2_connection)
{{ $user_id_2_connection->user_id_2 ? $user_id_2_connection->user_id_2->name : 'unknown' }}
#endforeach
I am making two relationships to user in my model Connection.php. I'm getting the error: "Trying to get property of non-object " in line 2nd and 5th in blade.
First change:
public function user_id_1()
{
return $this->belongsTo('App\User', 'user_id_1');
}
public function user_id_2()
{
return $this->belongsTo('App\User', 'user_id_2');
}
into:
public function user1()
{
return $this->belongsTo('App\User', 'user_id_1');
}
public function user2()
{
return $this->belongsTo('App\User', 'user_id_2');
}
to avoid collisions between table columns and relationships
Instead of this:
public function show($id){
$user_id_1_connections = Connection::whereUser_id_1AndConnection_status($id, 1)->get();
$user_id_2_connections = Connection::whereUser_id_2AndConnection_status($id, 1)->get();
return view('connection.showConnection',['user_id_1_connections' => $user_id_1_connections, 'user_id_2_connections' => $user_id_2_connections]);
}
you can do:
public function show($id){
return view('connection.showConnection', ['connection' => Connection::findOrFail($id)]);
}
And now your template could look like this:
User 1 name: {{ $connection->user1 ? $connection->user1->name : 'unknown' }}
User 2 name: {{ $connection->user2 ? $connection->user2->name : 'unknown' }}
But to be honest it's hard to get what you really want to achieve - you are using strange function whereUser_id_1AndConnection_status what you should rather don't do so probably you should read carefully relationships documentation for Laravel.

Resources