I am learning Laravel and there is one thing I cannot solve.
What do I have:
Table of Users, Posts, Comments and corresponding Models
User.php:
public function comments() { return $this->hasMany(Comment::class); }
public function publishComment(Comment $comment)
{
$this->comments()->save($comment);
}
Post.php:
public function comments() { return $this->hasMany(Comment::class); }
Comment.php:
public function post() { return $this->belongsTo(Post::class); }
public function user() { return $this->belongsTo(User::class); }
What do I want?
Since I have Blog, one logged user can create many posts (this works).
But same logged user can create many comments to one post. (User has many comments, post has many comments).
Tables:
User: | id | name | email | password
Comment: | id | user_id | post_id | body
Post: | id | user_id | title | body
What have I tried?
I created controller
CommentsController:
class CommentsController extends Controller
{
public function store(Post $post)
{
$this->validate(request(), ['body' => 'required|min:2']);
auth()->user()->publishComment(
new Comment(request('body'));
);
return back();
}
And in my blade file I simply want $comment->user->name (get name of user who does the comment belongs to)
Error I get:
Trying to get property of non-object
<?php echo e($comment->user->name); ?>
Any help would be appreciated.
You need a Polymorphic Relations Relationship.
Table Structure
posts
id - integer
title - string
body - text
user_id - integer
users
id - integer
name - string
email - string
password - string
comments
id - integer
body - text
commentable_id - integer
commentable_type - string
Into commentable_id you save the User id or the Post id.
Into commentable_type you save the User Model or Post Model.
And also you can have another table using comments table.
Models
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* Get all of the owning commentable models.
*/
public function commentable()
{
return $this->morphTo();
}
}
class Post extends Model
{
/**
* Get all of the post's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
class User extends Model
{
/**
* Get all of the users's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
See the docs to get more details.
In this video you have a good explanation https://youtu.be/lePjXdMC6aM
You can simply do this in your view.blade.php:
// Here I am assuming you have a $post variable that contains your blog post.
<ul>
#foreach ($post->comments as $comment)
<li>{{ $comment->user->name }}</li>
#endforeach
</ul>
This will loop over all the comments that you have for your blog post and display the owner's name, hopefully this helps.
Try this if you need just the name of the person who created comment.
{{ $post->user->name }}
Or
user->name); ?>
Related
I have an Author model and Blog model.
I also set up a table with the author_id and blog_id. The table is called "author_blog".
Below is how I am defining my relationships:
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog', 'author_id');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author', 'blog_id');
}
In my view I am trying to do $blog->author->first_name. The first name is a column on the Authors table.
I keep getting
trying to get property on non-object.
Any ideas?
UPDATE:
I have removed the intermediate table and instead put an "author_id" on my blogs table and shortened it as such.
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author');
}
In my BlogController, when I define the view, I grab a collection of blogs via $blogs = Blog::all();
In my view I just loop through the blogs to show each individually like...
#foreach ($blogs as $blog)
<div>{{ $blog->author->first_name }}</div>
#endforeach
For one to many relationship you don't need another table to handle your foreign key.
Just add author_id foreign key with your blogs table. then define your relations
like below,
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog', 'author_id');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author', 'author_id');
}
view:
before that make sure your query return a valid collection.
#foreach ($blogs as $blog)
<div>#if( $blog->author) {{ $blog->author->first_name }} #endif </div>
#endforeach
For further more details : https://laravel.com/docs/5.8/eloquent-relationships#one-to-many
with belongsToMany relation you can define your middle table(author_blog)
In Author model:
public function blogs()
{
return $this->belongsToMany(Blog::class,'author_blog','author_id','blog_id');
}
author_blog => middle table
author_id => foreignPivotKey
blog_id => relatedPivotKey
Here are my tables
Posts
id | name | created_At
Comments
id | comment | post_id | created_at
Post Model
function comments(){
return $this->hasMany('App\Models\Comment','id','post_id');
}
PostsController
function index()
{
Post::with('comments')::get();
}
Now how can i get list of all posts along with comments?
I am trying to match post_id in the child table.
In Your Post Model:
public function comments()
{
return $this->hasMany('App\Model\Comment');
}
In Your Post Controller :
use Illuminate\Http\Request;
function index(Request $request)
{
$posts=Post::with('comments')->get();
// in json
return response()->json($posts);
// in your view
//return view('viewname')->with('posts',$posts);
}
I have a users table. The user has possibility to upload a post. The post is saved well to the database. The users can follow each other - so on a pivot table each follower_id has followees_id.
I need to get the posts of the current user followee's . I am kinda messed with getting it from a pivot table.
Here's my code so far:
controller:
protected function get_followee_posts($followee_posts) ////$followee_posts passed from the route.
{
$user = $this->user;
$user->followee()->attach($followee_posts);
$followee_posts = User::find($followee_posts);
}
view:
<div class="following_posts">
<p> Posts from people you're following: <p>
#foreach ($user->follower_id->followee_id->posts as $post)
<form action="/html/tags/html_form_tag_action.cfm" method="post">
<textarea name="comments" id="comments" style="width:96%;height:90px;background-color:white;color:black;border:none;padding:2%;font:22px/30px sans-serif;">
{!! $posts->full_post !!} </textarea>
</form>
#endforeach
route:
Route::get('hub/{followee_posts}','HubController#get_followee_posts')->name('followee_posts');
I am getting an error with the current code saying:
ErrorException in 7340f90cc5faf1a298fcc646b7248b22 line 105:
Trying to get property of non-object
Any help would be lovely. Thank you.
Your not too specific about your schema, but this is how I would go about it.
User Model
class User extends Model
{
protected $table = 'users';
public function posts()
{
return $this->hasMany('Post');
}
public function followers()
{
return $this->hasMany('Follower');
}
}
Follower Model
class Follower extends Model
{
protected $table = 'followers';
public function user()
{
return $this->belongs_to('User');
}
public function posts()
{
return $this->hasMany('Post', 'user_id', 'follower_id');
}
}
Post Model
class Post extends Model
{
protected $table = 'posts';
public function user()
{
return $this->belongs_to('User');
}
}
The followers table would look something like this:
user_id
follower_id
You could then use eloquent method chains to get the posts of a users followers:
// Get Users object with followers and followers posts
// We use with() to eager load relationships
$user = User::with('followers.posts')->find(2);
// Return associative array of post objects
$postsArray = $user->followers->lists('posts');
// Combine posts into a single collection
$posts = (new \Illuminate\Support\Collection($postsArray))->collapse()->toArray();
print_r($posts);
Sorry for the noob question, but I am not able to make eager loading work, and instead getting: Trying to get property of non-object in my view (index.blade.php below).
Users table
id | first_name | other_columns
Credits table
id | recipient | other_columns
recipient is id from the Users table.
Credit.php
class Credit extends Model {
public function recipient() {
return $this->belongsTo('App\User', 'recipient');
}
}
User.php
class User extends Model {
public function credits() {
return $this->hasMany('App\Credit', 'recipient');
}
}
CreditController.php
class CreditController extends Controller {
public function index() {
$credits = Credit::with('recipient')->get();
return view('pages.credits.index')->withCredits($credits);
}
}
index.blade.php
#foreach($credits as $credit)
{{ $credit->recipient->first_name }}
#endforeach
What am I missing?
I solved this by changing in my Credit Model:
public function recipient() {}
into
public function user() {}
I'm having some really weird issues here with laravel one-to-many relation. I have a one-to-many relation between User and Book. When trying to display the related object from view, the result is either none or the related object depending on how I access it.
User model
//User table: id, username, ...
class User extends ConfideUser implements UserInterface, RemindableInterface {
public function books(){
return $this->hasMany("Book","user");
}
}
Book model
//Book table: id, user, title...
class Book extends Ardent{
public function myUser(){
return $this->belongsTo("User","user"); //I name user_id field as "user"
}
}
view:
#if( ! empty($book->myUser)) //It is always empty
#else
{{$book->myUser}} //It displays the user object
#endif
{{$book->myUser->id}} //ErrorException: Trying to get property of non-object
{{$book->myUser["id"]}} //This works
You didn't tell about ConfideUser class but basically should extend Eloquent
class User extends Eloquent implements UserInterface, RemindableInterface {
public function books(){
return $this->hasMany("Book","user"); // <-- assumed user is custom key
}
}
Same in Book model, ( you didnt tel where Ardent come from and how it's been implemented)
class Book extends Eloquent{
public function user(){
return $this->belongsTo("User", "user");
}
}
You can check relationship and get result using (get users who has book(s))
$books = Book::has('user')->get();
If you query like this
$books = Book::all();
return View::make('books')->with('books', $books);
In your view you can use
#foreach ($books as $book)
{{ $book->user->id }}
#endforeach