I am following a Laravel course on Udemy and while I followed everything the instructor did, for some weird reason I am not getting the expected result.
This is the Relationship One to One lesson and I added a function in User Model to check if it has any posts.
Then added the route to display post if user_id equals.
app\User.php
public function post() {
return $this->hasOne('App\Post');
}
app\Http\routes.php
Route::get('/user/{id}/post', function($id) {
return User::find($id)->post;
});
Below is the screenshot from the database showing that I have a post with user_id = 1 in the posts table. I also have a user with id=1 in the user's table.
MySQL data
Why do I get a blank page when visiting domain/user/1/post?
Sohel, i got a result from your function, but had to use
var_dump(User::with('post')->where('id',1)->first());
Then tried something else:
return User::with('post')->where('id',$id)->first();
And this is the result:
{"id":1,"name":"Nick","email":"nick#kriogen.name","created_at":"2018-03-15 09:49:51","updated_at":"2018-03-15 09:49:51","post":null}
Your one to one relationship should go as:
app\User.php
public function post() {
return $this->hasOne('App\Post');
}
app\Post.php
public function user() {
return $this->hasOne('App\User');
}
you can try doing this function in controller:
public function getPost {
$user= User::find($id);
return $user->post();
}
The issue was not with the functions, the issue was in the database.
Column deleted_at was not NULL and it was marking the post as being soft deleted, therefore not being displayed.
Since the "user_id" field is in the "posts" table, the relation in the App\User model need to be:
public function post() {
return $this->hasMany('App\Post');
}
then, call it without the parenthesis to get the result:
public function getPost {
$user= User::find($id);
return $user->post;
}
When you use the parenthesis, you get the builder and not the result. example:
public function getPost {
$user= User::find($id);
return $user->post()->get();
}
OR
public function getPost {
$user= User::find($id);
return $user->post()->where('name', 'like', '%hello%')->get();
}
I think you need ->hasMany() relation if you want to check if user has any posts because the user can has many posts... and the code would be:
public function posts() {
return $this->hasMany('App\Post');
}
The call:
User::find($id)->posts;
Related
I'm trying write an website with Laravel (current version is 5.7) and I have 3 models as: Post, User and Fav. I'm using a simple form to add posts to "favs" table which has 3 columns as; id, user_id and post_id. And I want to list posts that user added favorites bu I can't use "hasMany" method properly.
I can use variables like; $post->user->name but I can't figure it out how to use relationship with "favs" table.
Post Model
public function user() {
return $this->belongsTo('App\User');
}
public function favs() {
return $this->hasMany('App\Fav');
}
Fav Model
public function users() {
return $this->hasMany('App\User');
}
public function posts() {
return $this->hasMany('App\Post', 'post_id', 'id');
}
User Model
public function posts() {
return $this->hasMany('App\Post');
}
public function favs() {
return $this->hasMany('App\Fav');
}
Controller
public function user($id){
$favs = Fav::orderBy('post_id', 'desc')->get();
$user = User::find($id);
$posts = Post::orderBy('id', 'desc')->where('user_id', $id)->where('status', '4')->paginate(10);
return view('front.user')->with('user', $user)->with('posts', $posts)->with('favs', $favs);
}
The Fav model only has one User and Post each, so you need to use belongsTo() instead of hasMany and change the method names to singular. You can also remove the additional parameters in post() since they're the default values.
public function user() {
return $this->belongsTo('App\User');
}
public function post() {
return $this->belongsTo('App\Post');
}
Loading all Posts that a user has favorited:
$user->favs()->with('post')->get();
The with() method is used to eager load the relationship.
Now you can loop through the Favs:
#foreach($favs as $fav)
{{ $fav->post->name }}
#endforeach
I think you can change these two lines of your code to
$posts = Post::orderBy('id', 'desc')->where('user_id', $id)->where('status', '4')->paginate(10);
return view('front.user')->with('user', $user)->with('posts', $posts)->with('favs', $favs);
to
$posts = Post::where('user_id', $id)->where('status', '4')->latest()->paginate(10);
return view('front.user', compact('user', 'posts', 'favs'));
And for retrieving favorite posts of an user,
if you will change the fav table to make it a pivot table only to handle a many to many relationships between Post and User, you can get it as $user->posts, for a separate model, I think you can consider something like $user->favs and in view
In Fav model
public function user() {
return $this->belongsTo('App\User');
}
public function post() {
return $this->belongsTo('App\Post');
}
and in view
#foreach ( $user->favs as $fav )
{{ $fav->post->id }}
#endforeach
If an User, per example, have many Favs you need to use a Iteration Block, like foreach.
Example:
foreach($user->favs as $fav) {
dd($fav) // do something
}
Ps.: Be careful not to confuse hasMany and belongsToMany.
I'm trying to retrieve a group of post IDs from my likes table where the user ID is equal to the ID stored in the Auth Session.
So far I have tested retrieving data in multiple ways, if I select all the likes from the table it works fine, the auth ID retrieved from the session is the same as the one stored in the likes table so should produce a match and return data.
Here's the code I'm currently working with:
public function index()
{
$userid = Auth::id();
$userLikes = likes::all()->pluck('post_id')->where('user_id', $userid);
dd($userLikes);
}
The columns names within the table are as follows:
id
created_at
updated_at
user_id
post_id
I have tried this method of writing the query however am experiencing the same issue, no errors and no data.
DB::table('likes')->pluck('post_id')->where('user_id', $userid)->toArray();
I am looking to have an array of post ids for the posts liked by the logged in user so that it can be passed into the view.
Thanks in Advance
If you've created User, Post, and Like models with the appropriate relationships, you can do the following:
$ids = auth()->user()->likes->pluck('post_id')->toArray();
The model's would have relations defined as:
// User.php
public function likes()
{
return $this->hasMany(Like::class);
}
public function posts()
{
return $this->hasMany(Post::class);
}
// Like.php
public function user()
{
return $this->belongsTo(User::class);
}
public function post()
{
return $this->belongsTo(Post::class);
}
// Post.php
public function user()
{
return $this->belongsTo(User::class);
}
public function likes()
{
return $this->hasMany(Like::class);
}
Alternatively, using the query builder:
DB::table('likes')->where('user_id', auth()->id())->get('post_id')->toArray();
I am using laravel 5.6 and i want to get user posts with comments (only id field)
User Model
public function posts()
{
return $this->hasMany('App\Post');
}
Post Model
public function user()
{
return $this->belongsTo('App\User');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
Comment Model
public function post()
{
return $this->belongsTo('App\Post');
}
In my controller i am using this code to get user posts with their comments
$posts = $request->user()->posts()->with(['comments' => function($query) {
$query->select(['id']);
}]);
But its not working...
When i comment $query->select(['id']); it works fine but returns Comment model all fields. I want to only select id field.
What i am missing here?
You also have to select the foreign key column (required for matching the results):
$posts = $request->user()->posts()->with('comments:id,post_id');
If you want to only one column, you can use ->pluck('id')
https://laravel.com/docs/5.6/collections#method-pluck
I have two models, User and Post
User Model:
public function posts()
{
return $this->hasMany('App\Post');
}
Post Model:
public function user()
{
return $this->belongsTo('App\User');
}
In my controller I have a public function which has:
$users = User::orderBy('is_ban', 'desc')->paginate(10);
$posts = Post::orderBy('created_at', 'desc')->paginate(10);
Which is working as expected.
I also have one column in users table `is_ban' It's of boolean type.
I am looking for a query which will return the following:
Only get post which has been made by the user which has is_ban=false
perhaps i haven't understood you, but i hope it will help. You can add it to your Post model
public function getBannedUsersPosts()
{
return self::whereIn('user_id', User::where('is_ban', 0)->pluck('id'))->get();
}
I would like to return the model and part of its relationship
EX::
User model
public function comments()
{
return $this->hasMany('comments');
}
Comments model
public function user()
{
return $this->belongsTo('user');
}
Can I return all comments and the user's name associated with the comment?
The desired effect is
$comment = Comments::find($id);
$comment->user;
return $comment;
This will return the one comment and the associated user full model. I just need the name of the user. And this does not works if I call Comments::all()
Thank you in advance.
You're looking for Eloquent's Eager Loading
Assuming your Comments model has a method user():
public function user()
{
return $this->belongsTo('User');
}
You should be able to do this in your controller:
$comments = Comments::with('user')->where('post_id', $post_id);
// Return JSON, as is Laravel's convention when returning
// Eloquent model directly
return $comments;
You can do the opposite as well:
Assuming your User model has a method 'comments()', like so:
public function comments()
{
return $this->hasMany('Comment');
}
Inside of your controller, you should be able to do the following, assuming your have the $id of the user available:
$user = User::with('comments')->find($id);
// Return JSON, as is Laravel's convention when returning
// Eloquent model directly
return $user;