Eloquent has() method counts soft deleted rows - laravel-5

using
$users = User::has('comments','>=',3);
in Laravel 5.6 returns users with more than 3 comments but counts soft deleted comments, while I want the list of users who have more than 3 active comments.

I couldn't find the reason but creating a second relation solved my problem:
public function active_comments(){
return $this->hasMany(Comment::class)->where('deleted_at',null);
}
and then
$users = User::has('active_comments','>=',3);

Related

Laravel 7 API Resource showing only data that contains relationship

This my code stored in my API Controller:
return ApartmentResource::collection(Apartment::with(['sponsors'])->paginate(5));
It shows all Apartments, someone have the sponsor array empty, someone not.
How i can show only the Apartments that actually have sponsors?
You can use the has() method
https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence
return ApartmentResource::collection(Apartment::has('sponsors')->with(['sponsors'])->paginate(5));
with() simply eager loads the sponsors: https://laravel.com/docs/9.x/eloquent-relationships#eager-loading
use array_filter()
example:
$result = array_filter($array);
array_filter() remove empty array elements from array.

How return all rows for groupBy

I use the query to get the models that the user has, but only 1 model is returned for each user. How to get all? If I set $count=3 I should receive 3 or more models in group, but only first row is returned
$items->where(/*.....*/)
->groupBy('user_id')
->havingRaw("COUNT(*) >= {$count}")->get()
UPDATE
I solved it. I created a separate function for preparing the query and used it 2 times.
I think this may be an incorrect solution, but it works
$items = Items::query();
$this->prepareQuery($request, $items)
$items->whereHas('user', function ($q) use ($count, $request){
$q->whereHas('items', function ($query) use ($request){
$this->prepareQuery($request, $query);
}, '>=', $count);
})
->paginate(4);
This may work.Sometimes take can help.
$items->where(/*.....*/)
->groupBy('user_id')
->take({{$count}});
If you have relationships set up you can quite simply call:
$model->models()
$model being the model you're wanting the list for.
models() being the name of the relationship between the two items.
For example, a post may have many comments. You can call $post->comments() to get a list of the posts comments.
You may also query this from the database directly with some eloquent magic.
Post::with('comments')->where(/*....*/)->get();
EDIT:
You can check to see if a model has X number of related models like so.
Post::has('comments', '>=', 3)->where(/*...*/)->get();

Laravel where statement

I am new in Laravel. I want to create a search filter using eloquent model.
I want to check some columns are equal to some enteries and return the results, but the problem is that if any of the enteries is empty it returns nothing.
How to make it to search if other enteries matche and return values even one of the entery is empty.
$result = person::Where('age','>=',$age)
->Where('hairColor','=',$hairColor)
->Where('height','>=',$height)
->get();
Just use orWhere
$result = person::Where('age','>=',$age)
->orWhere('hairColor','=',$hairColor)
->orWhere('height','>=',$height)
->get();
Also, check this documentation
Laravel where clauses

Laravel 5 many to many attach two columns not working

in my Laravel 5 application i have many to many relationship between two models.I'm using a pivot table to keep track of them. In my both models i have defined belongsToMany method with relevant pivot table name as parameter.Then i'm going to add values to the pivot table in controller. It works fine for only one column. For the other one it's not inserting any values. In the Controller i'm calling like this,
$this->mymodel->addToPivotTable($values);
Should i pass two parameters there?
I could able to solve this. I needed to call the method after saving my data set to the table.It's like this,
public function add(Request $request){
$post = $request->all();
$arr = array(1,4,5);
$result = $this->mymodel->create($post);
$result->classifications()->attach($arr);
}

Laravel Many to Many - 3 models

Some help with many to many relationships in Laravel:
Using the example for roles and users - basically:
a table for all the roles
a table for the users
and table with user_id and role_id.
I want to add to the third table, eg Year. basically the pivot table will have user_id, role_id and year_id.
I want to be able to make a query to pull for example all users assigned a specific role in a specific year. Eg All users with role_id = 2, and year_id = 1.
Any help will be appreciated
Before answering, I would like to suggest you not to put year on database like this.
All your tables should have created_at and updated_at which should be enough for that.
To filter users like you want. You could do this:
// This queries all users that were assigned to 'admin' role within 2013.
User::join('role_users', 'role_users.user_id', '=', 'users.id')
->join('roles', 'roles.id', '=', 'role_users.role_id')
->where('roles.name', '=', 'admin')
->where(DB::raw('YEAR(role_users.created_at)', '=', '2013')
->get();
This example may not be the precise query you are looking for, but should be enough for you to come up with it.
The best way to achieve a three way relation with Eloquent is to create a model for the table representing this relation. Pivot tables is meant to be used for two way relations.
You could have then a table called roles_users_year which could have data related to this 3 way relation like a timestamp or whatever...
A very late answer to a very old question, but Laravel has supported additional intermediate (pivot) table columns of at least Laravel 5.1 judging from the documentation, which hasn't changed at least through Laravel 6.x.
You can describe these extra columns when defining your many-to-many relationship:
return $this->belongsToMany(Role::class)->withPivot('column1', 'column2');
or in your case, the below would also do the job:
return $this->belongsToMany(Role::class)->withTimestamps();
which you can then access via the pivot attribute on your model:
$user = User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->created_at;
}
Note that the pivot attribute is on the distant relationship model (a single Role) and not on the relationship itself.
To get all the Roles assigned to Users in any given year, you might create a special relationship:
// User.php
public function rolesInYear($year) {
return $this->belongsToMany(Role::class)
->wherePivot('created_at', '>=', Carbon::create($year))
->wherePivot('created_at', '<', Carbon::create($year + 1));
}

Resources