How to join 3 tables using laravel eloquent - laravel-5

How can I apply this query in laravel 5?
I have 3 table, Post, Profile, Comments
Post{id,title,body,user_id}
profile{user_id,last_name,first_name}
comments{comments,user_id,post_id}
I want to get this kind of structure:
post_id title post last_name first_name
and below are the comments
comments last_name fist_name

//post model
public function comments(){
return $this->hasMany('App\Comments', 'post_id', 'id');
}
//comments model
public function user(){
return $this->belongsTo('App\Profile', 'user_id');
}
//profile model
public function comments(){
return $this->hasMany('App\Comments');
}
and i call it in the controller using:
$posts = Posts::with('userProfile','comments', 'comments.user')->get();
Then it works:)
Thank you for some help and idea :)

If you need JUST those columns, you have to do something like this:
$users = DB::table('comments')
->join('profile', 'comments.user_id', '=', 'profile.user_id')
->select('comments.comments', 'profile.last_name', 'profile.first_name')
->get();
Anyway, I'd recommend using relations in your models if you are using the data in different places (or different structures).
P.S:
post_id post last_name first_name
There's no "post" field in any table, do you need the post title?

Related

Route model binding select specific columns with relation

Route:
Route::get('/posts/{post}', [PostController::class, 'show']);
Controller:
public function show(Post $post){
$postData = $post->load(['author' => function($query){
$query->select('post_id', 'name');
}])
->get(['title', 'desc', 'created_date'])
->toArray();
}
This returns all the posts in the database, While I only want to get the selected post passed to the show function.
So if I visit /posts/3, It should show data related to the post with id = 3, not all posts.
The result should be an array with only the selected post.
When you are inside the Controller you already have the Post you want. If you call get you are getting all posts with a new query.
To select specific columns from a relationship, you can do it like this:
public function show(Post $post)
{
$post->load('author:id,name,age'); // load columns id, name, age from author
}
Notice that including the id is required.
To specify columns for the Post, there's no way to do it per route, the only way is to override how Laravel resolves the implicit binding. For that, you can add this in your Post model class:
public function resolveRouteBinding($value, $field = null)
{
return $this->whereKey($value)->select(['id', 'body', 'author_id'])->firstOrFail();
}
Notice that including the author_id is required to load the Author afterwards inside the Controller method. Also keep in mind this will affect all routes where you implicitly load a Post.
Please don't use get() function on the model.
public function show(Post $post)
{
$post->load(['author' => function ($query) {
$query->select(['post_id', 'name']);
]);
dd($post->toArray());
}
Btw, the author shouldn't have a post_id, because author can have multiple posts. you should update the database structure or you are doing wrong in the controller. (my bad, Thanks #techno)

Laravel 5.2 Eloquent ORM to get data from 3 tables

I have the following tables. users, user_details and client_teams. Each user has one details and each user can have many teams. schema for users:
id, name, email,parent_user_id
user_details:
id, user_id, client_team_id
client_teams:
id, user_id, team_name,status
In user_model i have the following relations:
public function userDetails(){
return $this->belongsTo('App\Models\UserDetails','id','user_id');
}
public function clientTeamList(){
return $this->hasMany('App\Models\ClientTeams','user_id','id');
}
In user_details model i have the following relation:
public function clientMemberTeam(){
return $this->belongsTo('App\Models\ClientTeams','client_team_id');
}
I want to be show the list of users who have a specific team ID and created by a specific user. The query that i am using is this:
$userCollections=Users::where([
['users.status','!=','DELETE'],
['users.parent_user_id',$clientId],
['users.id','!=',$loginUser->id]
])
->with([
'userDetails'=>function($query) {
$query->where('client_team_id',1);
}
]);
This is giving me all records for this user, Whereas i want to match by client_team_id and user_id
You need to use whereHas and orWhereHas methods to put "where" conditions on your has queries.
Please look into https://laravel.com/docs/8.x/eloquent-relationships
$userCollections = Users::where([['users.status', '!=', 'DELETE'],
['users.parent_user_id', $clientId],['users.id', '!=', $loginUser->id]
])
->whereHas('userDetails' => function ($query) {
$query->where('client_team_id', 1);
})->get();

Laravel eloquent get data from two tables

Laravel Eloquent Query builder problem
Hello I have a problem when I am trying to get all the rows where slug = $slug.
I will explain in more details:
I have two tables, cards and card_categories.
cards has category_id.
card_categories has slug.
What I need is a query which returns all the cards which contents the slugs.
For example I made this:
$cards = Card::leftJoin('card_categories', 'cards.id', '=', 'card_categories.id')
->select('cards.*', 'card_categories.*')
->where('card_categories.slug', $slug)
->paginate(5);
But what happens is that just return 1 row per category.
I don't know what is wrong.
Many thanks.
I think I understand what you mean, from your explanation I would imagine your card model is as follows.
class Card extends Model {
protected $table = 'cards';
public function category()
{
return $this->belongsTo(Category::class)
}
}
In which case, you should just be able to do this:
$cards = Card::whereHas('category', function ($query) use ($slug) {
$query->where('slug', $slug);
})->paginate(5);
That will select all of the cards that has the category id of the given slug.

Laravel - Filter records by distinct relation

Right now I have the following models structure,
Country -> State -> City -> Student
And the Student model includes first_name and last_name.
So, I want countries to by filtered by giving student's first name. Like if I give John then I want list of countries which has students whose first name is John.
I was trying something like this,
I added a method called Students() in Country model and returning Student instances from that method. But now I stuck to find out how to filter countries.
Thanks in anticipation.
I came across a similar question recently and I came with the following solution myself. Probably, there are easier ways, but this will get you going for now, I guess.
First we query all the users with first_name == John, as you described, and we limit the query to output only the ID's.
$users = User::where('first_name', 'John')->get()->pluck('id');
We then cross-compare this with the result of Students() from the country model. As I don't know what you're querying for to get the country that you want, I'll just take the Netherlands as an example — that's where I'm from.
$users = Country::where('name', 'the Netherlands')->students()->whereIn('id', $users)->get();
For this to work, you must make sure that within the Students()-function in your model, the get() is left out.
Final 'result':
$users = User::where('first_name', 'John')->get()->pluck('id');
$users = Country::where('name', 'the Netherlands')->students()->whereIn('id', $users)->get();
in the Student Model create this:
public function city()
{
return $this->belongsTo(City::class,'city_id', 'id');
}
and in the City Model create this:
public function state()
{
return $this->belongsTo(State::class,'state_id', 'id');
}
Finally in the State Model:
public function country()
{
return $this->belongsTo(Country::class,'country_id', 'id');
}
For example if you made things like that in controller:
$students = Student::where('name', 'John')->get();
in the view:
#foreach($students as $student)
$student->city->state->country->country_name;
#endforeach
You can access like that.
If you have setup the model and relationship properly then you need to call them using in with function
$students = Student::where('name','John')->with('city.state.country')->get();
Loop through the $students
#foreach($students as $student)
{{ $student->city->state->country }}
#endif

How to query from eloquent?

ERD :
enter image description here
Model
Student : id
Course : id
Student_Course (payment) : id, student_id, course_id
The relation between Student and Course is Many to Many, because of that I make another table Student_Course.
I have one question, that is Show total amount of students that enroll at least 1 course.
Please help me to find the result. I stuck on that.
can you please try following example:
Model/Student.php //write relationship in your model
public function courses()
{
return $this->belongsToMany(Course::class, 'payment');
}
and then try with following eloquent query
$students = Student::whereHas('courses')
->take(10)
->get();
Try this.
use Illuminate\Database\Eloquent\Model;
class Student extends Model {
public function student_courses() {
return $this->hasMany('App\StudentCourses');
}
}
$students = Student::whereHas('student_courses')->get();

Resources