Laravel: "Trying to get property 'comments' of non-object" - laravel

I setup an api resource collection for the post model, called PostCollection. I have a problem with my comments query for a post. Getting non-object for $comments. The comment table currently has no records.
$author = \App\Post::find(1);
$comments = \App\Post::find(1)->comments;
return [
'id' => $this->id,
'user_id' => $this->user_id,
'description' => $this->description,
'media' => $this->media,
'media_type' => $this->media_type,
'likes' => $this->likes,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'author_avatar' => $author->setting->user_profile_photo,
'author_profile_name' => $author->name,
'author_user_name' => $author->setting->user_name,
'visible' => true,
'comments' => $comments,
];
In the post model, I have:
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
In the comment model I have:
public function user()
{
return $this->belongsTo(User::class);
}
public function post()
{
return $this->belongsTo(Post::class);
}

You should this
public function comments()
{
return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
}
in your controller
$post = \App\Post::find(1);
$comments = $post->comments;

Related

Passing a new variable to Resource from Controller | Laravel

I have an API resources in my code,
what i wanted to do is to pass a new data to be return in Resource Collection
Controller:
public function index(Request $request)
{
// #TODO implement
$books = Book::with('authors')->paginate(5);
$pass = 1;
return BookResource::collection($books, $pass, 200);
}
my Resources:
public function toArray($request)
{
return [
// #TODO implement
'id' => $this->id,
'isbn' => $this->isbn,
'title' => $this->title,
'description' => $this->description,
'published_year' => $this->published_year,
'authors' => AuthorResource::collection($this->authors),
'review' => BookReviewResource::collection($this->reviews),
'pass' => $this->pass
];
}
I want the $pass, can be returned in Resources,
how do i achieve that?
Try adding metadata to the collection using additional:
return BookResource::collection($books)->additional([
‘pass’ => $pass,
]);
BookResource
class BookResource extends Resource {
protected $pass;
public function pass($value){
$this->pass = $value;
return $this;
}
public function toArray($request){
return [
'id' => $this->id,
'isbn' => $this->isbn,
'title' => $this->title,
'description' => $this->description,
'published_year' => $this->published_year,
'authors' => AuthorResource::collection($this->authors),
'review' => BookReviewResource::collection($this->reviews),
'pass' => $this->pass
];
}
public static function collection($resource){
return new BookResourceCollection($resource);
}
}
BookResourceCollection
class BookResourceCollection extends ResourceCollection {
protected $pass;
public function pass($value){
$this->pass = $value;
return $this;
}
public function toArray($request){
return $this->collection->map(function(BookResource $resource) use($request){
return $resource->pass($this->pass)->toArray($request);
})->all();
}
Pass params
BookResource::collection($books)->pass(1);
Or using this:
http://localhost:3000/api/books?pass=1
public function toArray($request) {
$pass = $request->pass;
return [
'id' => $this->id,
'isbn' => $this->isbn,
'title' => $this->title,
'description' => $this->description,
'published_year' => $this->published_year,
'authors' => AuthorResource::collection($this->authors),
'review' => BookReviewResource::collection($this->reviews),
'pass' => $pass
];
}

Undefined method 'posts' inside controller - Laravel

I am getting error for undefined method which is defined inside my User model.
My controller:
$inputs = request()->validate([
'title' => 'required|min:8|max:255',
'post_image' => 'file',
'body' => 'required'
]);
auth()->user()->posts()->create($inputs);
My Post model:
public function user() {
return $this->belongsTo('App\Models\User');
}
My User model:
public function posts() {
return $this->hasMany('App\Models\Post');
}
correct your relationship
public function posts() {
return $this->hasMany(Post::class);
}
First your posts relationship is wrong, it must be hasMany NOT belongsTo
public function posts() {
return $this->hasMany(User::class);
}
Then it should work.
You can also try to create the model in a different way:
$validated = request()->validate([
'title' => 'required|min:8|max:255',
'post_image' => 'file',
'body' => 'required'
]);
// Here you should check if $validated has all required fields
// because some could fail, in that case aren't in the array
Post::create([
'title' => $validated['title'],
'user_id' => auth()->id, // or auth()->user->id
'post_image' => $validated['post_image'],
'body' => $validated['body'],
]);
Laravel Validation Docs

Property [id] does not exist on the Eloquent builder instance

I am trying to get comment and it's replies in laravel api,I tried following way and faced to this error, how can I solve it?
this is my controller:
public function postSinglePage(Request $request)
{
$post_id=$request->get('post_id');
$post = Post::where('id',$post_id)->where('status', '=', 1)->get();
return response([
"posts" => GetPostsSinglePageData::collection($post),
]);
}
and this is my resource collection to get post and it's comments:
public function toArray($request)
{
return [
'post_id' => $this->id,
"name" => $this->post_title,
"excerpt" => $this->post_excerpt,
"thumbnail" => $this->getFirstMediaUrl("images"),
"logo" => $this->getFirstMediaUrl("images"),
'comment_count'=>getCommentCount($this->id),
'comments'=> new CommentCollection(Comment::select('*')->where('post_id',$this->id)),
"like" => DB::table("like_tb")->select('like_dislike')
->where("type_like",'=','post')
->where('related_id',$this->id)
->get(),
"share" => DB::table("share_tb")->select("share_number")
->where('type','=','post')
->where("related_id",$this->id)
->get(),
];
}
this is comment collection:
public function toArray($request)
{
return [
'commentId'=>$this->id,
'courseId'=>$this->post_id,
'commentDate'=>$this->date,
'commentText'=>$this->body,
'userId'=>$this->user_id,
'replays'=>ReplyCommentCollection::collection(\App\Models\Comment\ReplyComment::where('comment_id',$this->id)->get()),
'users'=>UserInfoCollection::collection(User::where('id',$this->user_id)->get()),
];
}
$this->id not work in inner other function you must write like this:
public function toArray($request)
{
$comments=Comment::select('*')->where('post_id',$this->id)->get();
$commentCollection= CommentCollection::collection($comments);
return [
'post_id' => $this->id,
"name" => $this->post_title,
"excerpt" => $this->post_excerpt,
"thumbnail" => $this->getFirstMediaUrl("images"),
"logo" => $this->getFirstMediaUrl("images"),
'comment_count'=>getCommentCount($this->id),
'comments'=> $commentCollection,
"like" => DB::table("like_tb")->select('like_dislike')
->where("type_like",'=','post')
->where('related_id',$this->id)
->get(),
"share" => DB::table("share_tb")->select("share_number")
->where('type','=','post')
->where("related_id",$this->id)
->get(),
];
}

How to handle nested relation in laravel resource - 2

So I've been trying to get a second level relation out of my "CategoryResource" but it's not working, here is some of my code :
First, My model :
public function children()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
public function sub_children()
{
return $this->hasMany(Category::class, 'parent_id');
}
and then the "CategoryResource" :
$data = [
'id' => $this->id,
'parent_id' => $this->parent_id,
'order' => $this->order,
'name' => $this->name,
'slug' => $this->slug,
'childs' => CategoryResource::collection($this->whenLoaded('children') && $this->whenLoaded('children')),
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
];
My Controller
return CategoryResource::collection(Category::where('parent_id',null)->with('children.sub_children')->get());
Is there anyway i can retrieve my nested relation through laravel resource ?
You could use with function in the relationship. It would be something like this:
public function children()
{
return $this->hasMany(Category::class, 'parent_id', 'id')
->with('children');
}
It is going to load the children and then "subChildren" as relations of the first object.
So, you are going to load it as:
$children = $originalObject->children;
foreach ($children as $c) {
$subChildren = $c->children;
}
Check if this works for your problem.

Laravel, Call to a member function sync() on null

I have a FatalThrowableError in my laravel projects - Call to a member function sync() on null. Debuger show mi, that is this line of code
Post::findOrFail($post_id)->tags()->sync([1, 2, 3], false);
Complete method this line look like:
public function store(Request $request)
{
// validate a post data
$this->validate($request, [
'title' => 'required|min:3|max:240',
'body' => 'required|min:50',
'category' => 'required|integer',
]);
// store post in the database
$post_id = Post::Create([
'title' => $request->title,
'body' => $request->body,
])->id;
Post::findOrFail($post_id)->tags()->sync([1, 2, 3], false);
// rediect to posts.show pages
return Redirect::route('posts.show', $post_id);
}
My Post model its looks like
class Post extends Model
{
protected $fillable = [ ... ];
public function category() {...}
public function tags()
{
$this->belongsToMany('App\Tag', 'post_tag', 'post_id', 'tag_id');
}
}
And my Tag model its look like
class Tag extends Model
{
protected $fillable = [ ... ];
public function posts()
{
return $this->belongsToMany('App\Post', 'post_tag', 'tag_id', 'post_id');
}
}
Thanks for yours anser!
The error states that you're calling sync() on a null object, which means the result of your tags() method is null.
If you take a look at your tags() method, you can see that you forgot to return the relationship, therefore it is returning null. Add the return keyword and you should be good.
public function tags()
{
return $this->belongsToMany('App\Tag', 'post_tag', 'post_id', 'tag_id');
}
Try this
// store post in the database
$post = new Post([
'title' => $request->title,
'body' => $request->body,
]);
$post->save();
$post->tags()->sync([1, 2, 3], false);

Resources