Access an attribute through Laravel relationship - laravel

I would like to get the ID of a house related to a user but I get the famous Trying to get property of non-object error.
In my index.blade.php I use
{{ $user->house->id }}
User.php
public function house()
{
return $this->hasOne('App\House');
}
House.php
public function user()
{
return $this->belongsTo('App\User');
}
What should I do ?

Be sure that the user has house object. Try this:
#if ($user->house)
{{ $user->house->id }}
#endif

Related

Cannot call to model of polymorphic relation

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)

how to display the username of the comment in the post with relation table

my relational database image
{{ \App\User::where('id', $comment->user_id)->value('name') }}
if I use the code above
name user show in all post
my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Komen extends Model
{
protected $table='komentar_post';
}
my controller
public function index()
{
$post=Post::all();
$comment=Komen::all();
$user=User::all();
// dd($id);
return view('home',compact('post','comment','user'));
}
my view
#foreach($comments as $cm)
{{ \App\User::where('id', $cm->user_id)->value('name') }}
#endforeach
what the corect query i must use
You need to create relationship in your Komen model. It's something like this:
class Komen extends Model
{
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
Then, you can Eager Load that relationship when fetching the Komen.
PostsController.php
public function show(Post $post)
{
$comments = $post->comments()->with('user')->paginate();
return view('posts.show', compact('comments'));
}
Then, you can access user data when displaying each comments:
posts/show.blade.php
#foreach($comments as $comment)
{{ $comment->user->name }}
#endforeach
{!! $comments->links() !!}
Update
Ok, if you need to displaying comments when you're displaying all posts, first you need to setup the relationship!
Post.php
class Post extends Model
{
public function comments()
{
return $this->hasMany(Komen::class, 'post_id');
}
}
Komen.php
class Komen extends Model
{
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
PostsController.php
public function index()
{
$posts = Post::with('comments.user')->paginate();
return view('home', compact('posts'));
}
home.blade.php
#foreach($posts as $post)
#foreach($post->comments as $comment)
{{ $comment->user->name }}
#endforeach
#endforeach
{!! $posts->links() !!}

one to may relationship, Display all post along with there users

//Post table
user()
`belongsTo(User::class);`
//user table
posts()
hasMany(post::class);
//I want to get all the post available in the DB, Display along with the users associated with the post.
Use foreign key and primary key in relationships to get the results.
In Post
public function user()
{
return $this->belongsTo('App\User','users_id','users_id') //first parameter-foreign key,second parameter-local key
}
In User
public function posts()
{
return $this->hasMany('App\Post','users_id','users_id')
}
Now get all the posts using
$posts = Post::get();
return view('your-view')->with('posts',$posts);
You can retrieve user information in view using
#foreach($posts as $post)
$user = $post->user->name;
#endforeach
Hope it helps..
Guessing your relations look like this:
User:
public function posts()
{
return $this->hasMany('App\Post');
}
Post:
public function user()
{
return $this->belongsTo('App\User')
}
You could get all the posts in your controller, like this:
$posts = Post::get();
return view('your view', $posts);
And in your blade, to display posts and their users, do it like this:
#foreach($posts as $post)
$post->user->name
#endforeach
$posts = Post::with('user')->get();

Get username from ID

I have a blade template in a Laravel 5.5 app that is returning a user ID integer
I am looking for a way to get the users name from that value within the blade template
The value is just saved in the table and there is no relationship setup, is there a way to get the username without having to set up a relationship?
** UPDATE **
My products controller looks like this...
public function index()
{
$users = User::all();
$products= Product::all();
return view('products.index',compact('products', 'users'));
}
So now I have the users available inside the blade template but now I need to get the user from the id that is contained in produts
In your controller that's passing the user data to the view, you can either pass the entire $user object and print it in your view like {{ $user->name }} or set yourself a variable that holds just the username and pass that in for however you're using it.
I would do the first one though, something like:
public function index()
{
$user = User::where('id',$id)->firstOrFail();
return view('dashboard.index', compact('user'));
}
Or if you're getting all users from the database, an example would be:
public function index()
{
$users = User::all();
return view('dashboard.index', compact('users'));
}
Then in your view you can do
#foreach($users as $user)
{{ $user->name }}
#endforeach
Edit
Since seeing your updated question, you would benefit from making a relationship between your users and your products. So, you would say that a user has many products and that a product belongs to a user.
class User extends Model
{
/**
* Get all of the products for the user.
*/
public function products()
{
return $this->hasMany('App\Product');
}
}
And then
class Product extends Model
{
/**
* Get the user that is assigned to the product
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
Once you have set this up, you can loop through your products and get the username like this:
#foreach($products as $product)
{{ $product->user->name }}
#endforeach
Create helper file: follow this rule to make it : https://laravel-news.com/creating-helpers
and make one function like this:
function getUsername($uerId) {
return \DB::table('users')->where('user_id', $userId)->first()->name;
}
and call this function from your view like this :
{{getUsername($id))}} //it will print user name;
{{\App\User::findOrFail($id)->name}}
Auth::user()->name if user is online. if not you must have controller function like:
$users = User::all();
and in blade
#foerach($users as $user)
{{$user->name}}
#endforeach

query builder returns array instead of collection

User.php(User model)
class User extends Authenticatable
{
public function profiles(){
return $this->hasOne('App\Profile');
}
}
Profile.php (Profile model)
class Profile extends Model
{
public function users(){
return $this->belongsTo('App\User');
}
}
Function which returns data to view:
public function show_users(){
$users = User::where('id','!=',Auth::user()->id)->get();
return view('pages.show_users')->withUsers($users);
}
show_user.blade.php(View)
#foreach($users as $user)
{{$user->profile->first_name}} //Gives error:Trying to get property of non-object
{{$user->profiles['first_name']}} // Gives desired result
#endforeach
Why the result is returned in array instead of collection?
The reason that you are getting that error is beacause
Some users might not have a profile. so calling first_name on profile which is a null object will throw an error.
What you can is on php7 you can do
#foreach($users as $user)
{{$user->profiles->first_name ?? 'No first name'}}
#endforeach
php 5.6 and below
#foreach($users as $user)
#if($user->profiles->isNotEmpty())
{{$user->profiles->first_name}}
#else
No name
#endif
#endforeach
And moreover why don't use eager loading to load your profiles for performance benefit. Your query now will create the N+1 query problem.
You can change your query to
public function show_users()
{
$users = User::with('profiles')->where('id','!=',Auth::user()->id)->get();
return view('pages.show_users')->withUsers($users);
}
Hope it helps
The result returned is indeed a collection. It is just a typo issue
You forget an s here in profiles
{{ $user->profiles->first_name }}
Also please note that even if you access first_name as such
{{ $user->profiles['first_name'] }}
It doesn't mean it is not a collection.
If you check the source of Illuminate\Database\Eloquent\Model.php, you will see that it implements some cool functions such as offsetGet, offsetSet, and offsetExists
More information here. PHP ArrayAccess

Resources