Join in laravel 5.5 [duplicate] - laravel

This question already has answers here:
Laravel eloquent counting a relation
(3 answers)
Closed 5 years ago.
I am trying to make a query where I get the number of comments on a News in a row in laravel.
News Table
News_Comments Table
Display count of comments in 'Kommentare'
This is the query in mysql.
SELECT news.Id,news.title,news.body,news.created_at, COUNT(news_comments.id) AS Kommentare
FROM news
LEFT JOIN news_comments ON news_comments.fk_news_id = news.id
GROUP BY news.id
Result of this query
How would I write that in laravel 5.5?
Thank you very much!

You have to set the relationship between News and NewsComments.
In News Model, supposing that news_comments is in NewsComment Model, in App folder. Set the relationship:
public function newsComments()
{
return $this->hasMany('App\NewsComment', 'fk_news_id');
}
And then, to get the count, you can use count() method:
$count = $news->newsComments()->count();
Or, directly using blade:
{{ $news->newsComments()->count() }}

Make a model for news table name News and another for comments table name Comment. And then in your News model, define a hasMany() relationship method like -
public function comments(){
return $this->hasMany(Comment::class);
}
And then in your controller, retrieve like this-
$newses = News::with('comments')->get();
This will load all news with corresponding all comments. If you want to load single news with all comments then -
$news = News::with('comments')->where('id',$news_id)->first();
To get the comment count, you can count() on relationship like -
$count = News::find($news_id)->comments()->count();

Related

How to make left join in many to many relationship laravel

I am new in laravel. I have 3 tables
users
ingredients
user_ingredients(pivot table)
Now i have established many-to-many relationship but I have a special requirement that I want to get matching records(which is done) with all the ingredients in ingredients table. I can do it using query_builder or raw but I want to do it in eloquent.
I have searched about 4 hours to find any solution in eloquent but did not found.
Here is my code
User Model
public function ingredients()
{
return $this->belongsToMany('App\Ingredient', 'user_ingredients');
}
Ingredient Model
public function user()
{
return $this->belongsToMany('App\User', 'user_ingredients');
}
Controller Code
$ingredients = $user->ingredients()->get();
Query Builder query
select ingredients.*,user_ingredients.liked from ingredients LEFT JOIN user_ingredients on ingredients.id = user_ingredients.ingredient_id and user_ingredients.user_id=129
I have checked has(),with() but nothing according to my requirement.
Please help me. Thanks
If I understand your question correctly, you are just trying to access all the ingredients on the user model? In that case, you should be able to just do $user->ingredients
You can access the relationship as a property on the user object. It's some behind the scenes Laravel magic that handles this.

How to load Laravel with nested models and limit the nested models?

Hello guys I am using Laravel 5.6 I have three tables in the database posts,comments and replies and three models Post , Comment , Reply
the relations are as follow one post has many comments and one comment has many replies. I created a route that when hit will return some data ;however, I want this data to be in a specific way read this example:
Lets say I have 6 posts in my database and each post has 6 comments also each comment has 6 replies I want to return only the first 3 posts along with the first 3 comments for each post also the first 3 replies for each comment
//this is a function inside a controller
//and for sure I have make sure to make use of the models namespaces
public function test(){
$posts = Post::with(['comments' => function($data){
return $data->take(3);
},
'comments.replies' => function($data){
return $data->take(3);
}])->paginate(3);
//returning the posts
return $posts
}
This way is working it returns the first 3 post and it returns the first 3 comments and first 3 replies only for the first post but for other posts I only get an empty key of comments so there is no replies as a result
hope you get my question please help
sorry for big question
Thanks in advance.
There is no native support for this in Laravel.
I created a package for it: https://github.com/staudenmeir/eloquent-eager-limit
Use the HasEagerLimit trait in both the parent and the related model.
class Post extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}
class Comment extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}
Then you can apply ->take(3) to your relationship.
The same goes for the replies.

Laravel 5.5 Paginate the Query - Eager Loading

I have a problem and can't figure out how to solve it. I've searched online but still couldn't get a firm answer. What I'm trying to do is to paginate Inquiries table - or the query below. Everything seems to work (at least I'm getting 20 inquiries per page, however I can't figure out how to display the links()?
I'm saving Inquiries in the $thecusts collection and passing it to the view.
Tables and relations : Employees - Dealers (manytomany)
Dealers-customers(1 to many)
Customers-inquiries (1 to many).
So I need to paginate x Inquiries for the employee that has many dealers.
Anyone can help ?
$justch = $me->employeehasdealers()->get(['dealers.dealer_id','dealer','abbreviation']); //list of dealers assigned to auth employee
$justch2=$justch->load(['DealerHasInquiries'=>function($query){
$query->with('inquiriescomments:comments_inquiries_id,inquiry_id,employee_id,comments','inquiryspdl','inquiriescustomers:customer_id,customer')->paginate(20);
}]);
$thecusts = new Collection();
foreach ($justch2 as $just) {
$thecusts = $thecusts->merge($just->DealerHasInquiries);
}
The problem is you're not passing back the paginator instance. You can manually create one in your controller based on $thecusts:
$perPage=20;
return view('my-view', ['paginator' => new Paginator($thecusts->toArray(), $perPage)]);
Then you can call the links method on the paginator instance in your view:
{{ $paginator->links() }}
Edit
You may be able to simply all this though in a single query like:
$thecusts = $me->employeehasdealers()->with(['DealerHasInquiries'=>function($query){
$query->with('inquiriescomments:comments_inquiries_id,inquiry_id,employee_id,comments','inquiryspdl','inquiriescustomers:customer_id,customer');
}])->paginate(20);
return view('my-view, compact('thecusts'));
however I can't figure out how to display the links()?
You can do this in your blade:
{{ $justch2->links() }}
The Answer has been posted by btl - (Much appreciate it!)
Here is my code with some additions:
Controller:
$perpage=19;
$justch = $me->employeehasdealers()->with(['DealerHasInquiries'=>function($query) use ($perpage){
$query->with('inquiriescomments:comments_inquiries_id,inquiry_id,employee_id,comments','inquiryspdl','inquiriescustomers:customer_id,customer')->simplePaginate($perpage);
}])->get(['dealers.dealer_id','dealer','abbreviation']);
foreach ($justch as $just) {
$thecusts = $thecusts->merge($just->DealerHasInquiries);
}
$paginator = new Paginator($thecusts->toArray(),$perpage, Paginator::resolveCurrentPage(),['path'=>Paginator::resolveCurrentPath()]);
$inquiries = $thecusts;
return view('/inquiries', ['paginator'=>$paginator,'inquiries' => $inquiries]);
Blade: {{$paginator->links()}}

How to use softdelete withTrashed in Laravel [duplicate]

This question already has an answer here:
How to use withTrashed when I'm querying using eager loading?
(1 answer)
Closed 5 years ago.
I'm building an application in laravel where I've two models company and contact with belongs to relationship as following:
class Contact extends Model
{
use SoftDeletes;
public function company()
{
return $this->belongsTo('App\Company');
}
}
I'm using softdeletes in company model too, Now suppose even if any company is deleted, I want the contact to be shown with there company details.
I'm trying to do something like this to retrieve the data:
$allData = Contact::with('company')->withTrashed()->get();
It is not working, it is only showing company details which are not deleted. Any ideas to overcome this problem?
Try this solution:
Contacts with trashed:
$allСontacts = Contact::withTrashed()->get();
Without:
$contacts = Contact::all();
Get companies:
$companies = $contacts->company()->withTrashed()->get();
$allCompanies = $allСontacts->company()->withTrashed()->get();

Eloquent relationship with 3 tables

I'm new to Stack Overflow and Laravel.
I try to develop a variable profilesystem in Laravel and I got 3 tables ('User', 'User_Fields', 'Fields').
The structure of the Fields table is following:
The structure of the user_fields table is following:
The User table is the standard table which came with Laravel 5
Now I want to get all fields from user_fields depending on which user is selected or logged in. If the user_field doesn't exists, the model should return null or create a new record for the user_field.
I tried a lot of "solutions" which came with eloquent like (hasManyThrough, belongsToMany) but I don't get the result I wanted.
Is there any solution with relationship methods?
Thanks for your help, and sorry for my bad english :/
You should be using the belongsToMany()->withPivot() to retrieve the intermediate table columns. Your user_fields is your pivot table so on your user model you should have:
class User extends Model
{
public function fields()
{
return $this->belongsToMany(Field::class, 'user_fields')->withPivot('value');
}
}
Then you can access your values for a user by:
$user = User::find($id);
foreach($user->fields as $field) {
$field->pivot->value;
}

Resources