Controller method issue in Laravel Eloquent - php

This is my Controller method wherein I want to fetch posts by user id.
I also have relationship defined in User model
public function posts()
{
return $this->hasMany('Post','user_id','id');
}
UserController.php
use App\Post;
public function findPostsByUser($id){
$user = User::findOrFail($id);
$posts = $user->posts()->get();
return $posts;
}
But it is giving me 'Post' not found error. Can someone help on this.

In your Post model make sure you have the relation defined like this:
public function user()
{
return $this->belongsTo('App\User');
}
And change your User model to this:
public function posts()
{
return $this->hasMany('App\Post','user_id','id');
}

Change relation method to
use App\Post;
....
public function posts()
{
return $this->hasMany(Post::class,'user_id','id');
}
or
public function posts()
{
return $this->hasMany('App\Post','user_id','id');
}
If you wont to get only posts that case use this
public function findPostsByUser($id){
$posts = Post::where('user_id', $id)->get();
return $posts;
}
The second solution has 1 query, but first solution has 2 query in db.
Also you can do it this way
public function findPostsByUser($id){
$posts = Post::whereUserId($id)->get();
return $posts;
}

Related

Accessing a hasMany relation function via Collection

I am trying to get all of the users notifications, and depending on if the user is a buyer or seller (can be both). I have made two functions in my notifications table to filter each other out.
My goal is to ultimately run:
$notifications = Auth::user()->notifications()->getBuyerNotifications();
or
$notifications = Auth::user()->notifications()->getSellerNotifications();
I am running into an issue: Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany
User Model:
public function notifications() {
return $this->hasMany('App\Notification', 'user_id', 'id');
}
Notifications Model:
public function user() {
return $this->belongsTo('App\User', 'id', 'user_id');
}
public static function getBuyerNotifications() {
return self::whereNotNull('buyer_id')
->whereNull('deleted_at')
->get();
}
public static function getSellerNotifications() {
return $this->whereNotNull('seller_id')
->whereNull('deleted_at')
->get();
}
The command I want to run to get all of the users notifications if they're a buyer: $notifications = Auth::user()->notifications()->getBuyerNotifications();
Firstly, you don't need to use whereNull('deleted_at'), you can import the softDeletes Trait in your model:
use Illuminate\Database\Eloquent\SoftDeletes;
...
class Notification extends Model {
use SoftDeletes;
...
}
Laravel will automatically use whereNull('deleted_at') on Eloquent-Builder.
Secondly, you cannot use static method on Illuminate\Database\Eloquent\Relations\HasMany.
Use scope method instead:
public function scopeBuyerNotifications($query) {
return $query->whereNotNull('buyer_id');
}
public function scopeSellerNotifications($query) {
return $query->whereNotNull('seller_id');
}
So you can find the notification like this:
$notifications = Auth::user()->notifications()->sellerNotifications()->get();
$notifications = Auth::user()->notifications()->buyerNotifications()->get();
Auth::user() uses session data.
Try this:
optional(User::find(Auth::id())->notifications)->getBuyerNotifications;
or
$userId = 1; // Example id you can just pass the user Id.
User::find($userId)->notifications->getBuyerNotifications;
You can add two other methods in user model as follows
public function getBuyerNotifications() {
return $this->hasMany('App\Notification', 'buyer_id', 'id');
}
public function getSellerNotifications() {
return $this->hasMany('App\Notification', 'seller_id', 'id');
}
And you can call it directly from the user instance
$user->getBuyerNotifications();
$user->getSellerNotifications();

Laravel - my scope method does not appear to be working

I am using scope to filter conditions for specific users, I have assigned a course to a teacher and when this teacher signs into their account, I only want this teacher to view their course, although my scope method doesn't appear to be working correctly. I am not getting an error, so I am not sure where I have gone wrong. I have added some of my code below, i would be very grateful for any help. Thanks
CoursesController index method;
public function index()
{
$courses = Course::ofTeacher()->get();
return view('admin.courses.index')->with('course', $courses); //pass data down to view
}
Course.php;
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
class Course extends Model
{
protected $fillable = [
'id', 'title'
];
public function courses(){
return $this->belongsToMany('App\User');
}
public function teachers() {
return $this->belongsToMany(User::class, 'course_user')
}
public function scopeOfTeacher($query)
{
if (!Auth::user()->isAdmin()) {
return $query->whereHas('teachers', function($q) {
$q->where('user_id', Auth::user()->id);
});
}
return $query;
}
}
User.php;
public function isAdmin() {
return $this->role()->where('role_id', 1)->first();
}

How to fix the relationship problem of "Property [id] does not exist" problem

I have three model 1. Task.php 2. Project.php 3. User.php.
Task have a one to many relationship with user and project.php.
Task.php
public function project()
{
return $this->belongsTo(Project::class);
}
public function user()
{
return $this->belongsTo(User::class,'member_id');
}
User.php
public function tasks()
{
return $this->hasMany(Task::class);
}
Project.php
public function tasks()
{
return $this->hasMany(Task::class);
}
Nowi want to retrieve all the task that is associated with users where project id is one (Actually not one, id is passed through url).Here is my attempt
public function taskList($id)
{
$project=Project::with('tasks')->find($id);
$tasks=Task::has('user')->whereHas('project',function($project){
$project->where('id',$project->id);
})->get();
dd($tasks);
return view('leader.tasks',compact('project'));
}
In the above either i give the $id which is i get from the url either $project->id, it always through me the error.Please help me to solve this.
public function taskList($id)
{
$project=Project::with('tasks')->find($id);
$tasks=Task::has('user')->whereHas('project', function($query) use ($project) {
$query->where('id', $project->id);
})->get();
dd($tasks);
return view('leader.tasks',compact('project'));
}
You need to use with() method along with has()
public function taskList($id)
{
$project=Project::with('tasks')->find($id);
$tasks=Task::with('user')->has('user')->whereHas('project', function($query) use ($project) {
$query->where('id', $project->id);
})->get();
dd($tasks);
return view('leader.tasks',compact('project'));
}

How to filter entries via hasMany relationship in Laravel

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.

Query with two laravel models and return result

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();
}

Categories