Laravel: Find all posts made by a user using name field - laravel

I want to fetch all posts made by a user by matching the name of the user from the route url using Eloquent
My User.php has relationship as follows
public function posts() {
return $this->hasMany('App\Post');
}
My Post.php model has following relationship:
public function user() {
return $this->belongsTo('App\User');
}
my route is like following:
Route::get('/users/{name}', 'UsersController#show');
I know if I want to fetch all posts by a user I need to do something like this
public function show($name) {
$user = User::find(1);
$posts = $users->posts()->get();
return view('users.show', compact('posts'));
}
but I want to find the user based on the name field in the database and not the id
I cant use ->posts() if I use where like Users::where('name', $name)->posts()->get(); , It throws error.
How do I fetch all posts of a user by matching his name in database with eloquent

You can use whereHas():
$posts = Post::whereHas('user', function($q) use($name) {
$q->where('name', $name);
})->get();
Or you can do this:
User::where('name', $name)->first()->posts()->get();
Or:
$user = User::where('name', $name)->first();
$posts = Post::where('user_id', $user->id)->get();
All these options will create two queries.

Related

Merging two queries into one using Eloquent

I have this two queries to display information in 3 tables Users, Comments, and Posts. so I made this function:
public function show($id)
{
$posts = Post::with(['comments'])->findOrFail($id);
$user = User::find($posts->user_id);
echo "<h1>".$posts->title.'</h1>';
echo "<h2>".$user->name.'</h2>';
foreach ($posts->comments as $comment) {
echo $comment->body.'<br>';
}
}
on this function I using two variable $posts and $user, can I merge this two variable using eloquests command like Post::with(['user','comments'])'? so I can use just $posts variable and use it like $posts->users->name to access user name.
i was trying using this way:
$posts = Post::with(['comments','users'])->findOrFail($id);
but when i echo the post it showing that the user was null:
{"id":1,"user_id":1,"title":"Oleh id 1","body":"ini adalah content","created_at":"2017-10-18 03:25:54","updated_at":"2017-10-18 03:25:54","comments":[{"id":1,"post_id":1,"body":"Keren banget deh artikelnya, TOP","created_at":"2017-10-18 03:43:50","updated_at":"2017-10-18 03:43:50"},{"id":2,"post_id":1,"body":"Keren banget deh artikelnya, TOP","created_at":"2017-10-18 03:43:53","updated_at":"2017-10-18 03:43:53"},{"id":3,"post_id":1,"body":"Keren banget deh artikelnya, TOP","created_at":"2017-10-18 03:43:54","updated_at":"2017-10-18 03:43:54"}],"users":null}
Here's my model if you need it. My post model:
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function comments()
{
return $this->hasMany('App\Comment');
}
public function users(){
return $this->belongsTo('App\User');
}
}
my Comment model
class Comment extends Model
{
/**
* Get the post that owns the comment.
*/
public function post()
{
return $this->belongsTo('App\Post');
}
}
You’ll have an easier time sticking to Laravel’s conventions for naming relationships.
A Post has many Comments, which belong to a User. Given this set up:
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
You can then query a post’s comments and users like this:
$comments = $post->comments()->with('user')->get();
You could also eager-load the user relation on comments if you always wanted the user returned with a comment:
class Comment extends Model
{
protected $with = ['user'];
public function user()
{
return $this->belongsTo(User::class);
}
}
Then your query would be simplified:
$comments = $post->comments;
Hope this helps you!!
What I am guessing is you want the list of all posts with the users. If relation is defined, try with the join
$posts = DB::table('posts')
->join('users', 'users.id', '=', 'posts.user_id')
->select('posts.*', 'users.name as user_name')
->where('posts.comments', '<>', NULL)
->get();
#NOTE: If you are using soft deletes you might wanna add where('posts.deleted_at', null)
After couple of days searching finally i got the answer, i can get merge the query like this:
$posts = Post::with(['comments','users'])->findOrFail($id);
but in the Post Model the function not "Users" but "User".

Eloquent: hasNot with parameter

I have the following eloquent models:
User | id
Post | id
Comment | id | post_id | user_id
Using eloquent, how can I fetch all Posts which a specific User hasn't commented yet?
I tried so far:
In Model Post:
public function noCommentOf(User $user) {
$this->hasNot('App\Comment')->commentOf($user);
}
In Model Comment:
public function commentOf($query, User $user) {
return $query->where('user_id', '=', $user->id);
}
The way I would do this is by querying the Post model with a whereDoesnthave relationship. In your controller:
public function getPostsWithoutCommenter(){
$userId = 1; // Could be `$user`, `use($user)` and `$user->id`.
$posts = \App\Post::whereDoesntHave("comments", function($subQuery) use($userId){
$subQuery->where("user_id", "=", $userId);
})->get();
}
This would assume that comments is defined on the Post model as:
public function comments(){
return $this->hasMany(Comment::class);
}
Basically, if the comments relationship with the check for that $userId returns a Collection, it would be ignored from the result set.
Post model
public function comments()
{
return $this->hasMany(Comment::class)
}
Then get posts
$posts = Post:: whereDoesntHave('comments', function ($query) use ($userId) {
$query->where('user_id', $userId);
});
To get posts with no comments
$posts = Post::has('comments', '=', 0)->get();
I think:
$user->post()->leftJoin('comments', 'posts.id', '=', 'comments.post_id')->whereNull('comments.id');

What kind of relationship should be?

I have two models: Users and Categories.
I need to get all categories on which user subscribed.
Do, database structure is:
User Category UserCategory
___ _________ __________
id id | name category_id user_id
Category model is:
public function user()
{
return $this->belongsToMany('App\User', 'user_id', 'id');
}
User model is:
public function categories()
{
return $this->belongsToMany('App\Category');
}
I tried to get all categories on which user subscribed through third table:
$categories = Category::with("user")->where("id", Auth::user()->id)->get();
It does not work for me
To get all categories which belong to the user, use the whereHas() method:
$categories = Category::whereHas('users', function($q) use($userId) {
$q->where('id', $userId);
})->get();
Also, make sure table name is categories_users and define users relationship like this:
public function users()
{
return $this->belongsToMany('App\User');
}

Laravel return specific model attribute

Let's say I have User Model. Each User has Pet model.
both have relationship setup correctly.
When I get the user data along with his pets, I do this:
return $this->with('pets');
but what if I want to return the pet name only with the user data?
I've been trying that:
return $this->with('pets.name');
Didn't work for me.
Model
Class User extends Model ()
{
...
public function pets()
{
return $this->hasOne('App\Model\Pet');
}
}
Controller or Repository or any other object
function getUserDetails (Request $request)
{
$userId = $request->get('id');
$findUserById = User::find($userId);
$fullName = $findUserById->pets->fullname;
}
You can do this way :
$users_with_pet_name = DB::table('users')
->join('pets', 'users.id', '=', 'pets.user_id')
->select('users.*', 'pets.name')
->get();
Check out joins section: https://laravel.com/docs/5.1/queries#joins

Combine two request into one using laravel

I have two table email (email_id, email) and users (user_id) with a pivot table user_email (id, user_id, email_id) and i would like to check the existence of my email "toto#toto.com" for my user_id "2".
$emailID = Email::where('email', 'toto#toto.com')->pluck('id');
$exists = User::find('2')->emails->contains($emailID);
The result is ok, but i would like to know if it's possible to combine this into one query using Eloquent.
If have these models :
class Email extends Model {
public function users() {
return $this->belongsToMany('App\User', 'user_email');
}
}
class User extends Model {
public function emails() {
return $this->belongsToMany('App\Email', 'user_email');
}
}
You can make query with relationships too:
$email_address = 'toto#toto.com';
$user_id = 2;
$email = Email::whereHas('users', function($q) use ($user_id) {
$q->where('users.id', $user_id);
})->where('email', $email_address)->first();
if($email->exists) {
//... it exists
}
Yes, you can do it like this.
public function getUserById($id) {
$user = User::with('emails')->where('id', 2)->first();
return view('your-view')->with('user', $user);
}
Then on your blade template.
#foreach ($user->emails as $email)
{{ $email->email }}<br/>
#endforeach
Check out the Eager Loading documentation for more information.

Resources