Laravel Query Builder relationship plus no relationship - laravel

I currently have this which works for querying a relationship:
$users = User::query();
$post_id = $request->input('post_id');
$users->whereHas('posts', function ($query) use ($post_id) {
$query->where('id', $post_id);
});
return $users->get();
But in the results of this query I would also like to include Users that do not have any posts connected to them. So the result becomes: users without posts + users with a specific post (code above). Is this possible?

Use doesntHave():
$users->whereHas('posts', function ($query) use ($post_id) {
$query->where('id', $post_id);
})->orDoesntHave('posts');

Related

how to use whereHas in laravel

I am new to laravel,
I need to create a query for the db,
$query = Deal::query();
I want to use the wherehas operator.
this is my code that is worked.
else if ($group_by == 'precedence') {
if($get_deals_for == 'noprecedence'){
$get_deals_for = 0;
}
$precedenceStatus = $get_deals_for;
$query-> where('precedence', '=', $precedenceStatus);
// \Log::info('The request precedence: '.$precedenceStatus);
}
I want to add this code also to the query
if($person) {
$query->whereHas('personnel', function ($subQuery) use ($person) {
$subQuery->where('id', '=', $person);
});
}
So I need to change the first code?
how I can convert the first code to wherehas?
the first code is from table called deal, the second section is from realtionship called personnel.
the second section worked in other places in the code, I just need to fix the first section and not understand what to write in the use
I try this and get error on the last }
else if ($group_by == 'precedence') {
if($get_deals_for == 'noprecedence'){
$get_deals_for = 0;
}
$precedenceStatus = $get_deals_for;
$query-> where('precedence', '=', $precedenceStatus)
-> when ($person, function($query) use($person) {
$query->whereHas('personnel', function ($query) use ($person) {
$query->where('id', '=', $person);
});
})
}
There is a method you can use called when(, so that you can have cleaner code. The first parameter if true will execute your conditional statement.
https://laravel.com/docs/9.x/queries#conditional-clauses
$result = $query
->where('precedence', '=', $precedenceStatus)
->when($person, function ($query) use ($person) {
$query->whereHas('personnel', fn ($q) => $q->where('id', '=', $person));
})
->get();
You should also be able to clean up your precedence code prior to that using when( to make the entire thing a bit cleaner.
Querying to DB is so easy in laravel you just need to what you want what query you want execute after that you just have to replace it with laravel helpers.Or you can write the raw query if you cant understand which function to use.
using,DB::raw('write your sql query').
Now Most of the time whereHad is used to filter the data of the particular model.
Prefer this link,[Laravel official doc for queries][1] like if you have 1 to m relation ship so u can retrive many object from one part or one part from many object.like i want to filter many comments done by a user,then i will right like this.
$comments = Comment::whereHas('user', function (Builder $query) {
$query->where('content', 'like', 'title%');
})->get();
$comments = Here will be the model which you want to retrive::whereHas('relationship name', function (Builder $query) {
$query->where('content', 'like', 'title%');
})->get();
you can also write whereHas inside whereHas.
[1]: https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence

How to get all the user data from another table and include them on user list in laravel?

I am using 2 tables upon displaying my users in my users>index.blade
these 2
USER table
and COLLECTOR_MEMBERS table
The result is this
Now my problem is I want to connect to the other table called
COMMISSIONS table
to achieve this result
MODELS
COMMISSIONS Model
USER
COLLECTOR MEMBER
USER Controller index function
public function index(Request $request)
{
$users = User::all();
$admins = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'admin');
})->get();
$collectorList = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector');
})->with('collectorList')->get();
$borrowers = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'borrower');
})->get();
$userProfile = Auth::user()->id;
if (Auth::User()->hasRole(['borrower','collector'])){
return redirect('dashboard/profile/'.$userProfile);
}
return view('dashboard.users.index', compact('users','profile'))
->with('admins',$admins)
->with('borrowers',$borrowers)
->with('collectorList',$collectorList);
// ->with('collectorBorrowers',$collectorBorrowers);
}
How wan I display the commission_amount column from commissions table? to make my list like this
You could use sum aggregate function, your code should look like this.
$collectorList = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector');
})->with(['collectorCommission' => function($query) {
$query->sum('commission_amount');
}])->get();
Assuming that you have this relationship in your user model
public function collectorCommission() [
return $this->hasMany('App\Commissions', 'user_id');
}
You cant use belongsToMany relationship since this relationship
requires you an intermediary table in your second argument.
You should use hasMany relationship considering that one user has many commissions.

Relational Query In laravel

My Code
$videos = ExamVideo::with([
'user' => function ($query) use ($request) {
$query->where('user_name', 'like', '%'.$request->search.'%');
}
])->where('is_marked','=', 0)->get();
return $videos;
I want to get only those videos where is_marked is zero & it's relation user_name match my search result.
But I get all the videos which marked is zero.
The with method is only for eager loading and not used to filter your records.
You can accomplish what you want with the whereHas method which will perform a query on the relation:
$videos = ExamVideo::whereHas('user', function ($query) use ($request) {
$query->where('user_name', 'like', "%{$request->search}%");
})->where('is_marked', false)->get();
For more information about whereHas: https://laravel.com/docs/6.x/eloquent-relationships#querying-relationship-existence

Laravel eloquent paginate in relation is not displayed in collection

I want to page the relation articles. The correct number is displayed but not in the collection, for example "first page" or "to last".
$articles = Categories::where('slug', $categorie)->with(['articles' => function ($query) use ($default_count, $default_sort) {
$query->orderBy('price', $default_sort)
->with('contents')
->paginate(2);
}])->first();
What am I missing here?
Try flipping it around so that Article is the top level:
$articles = Article::with('contents')
->whereHas('category', function ($query) use ($categorie) {
$query->where('slug', $categorie);
})
->orderBy('price', $default_sort)
->paginate(2);
This assumes that you have the category relationship set up on Article as well.
i think you want result some like that
Article::whereHas('category', function ($query) use ($categories) {
$query->where('slug', $categories);
})
->with('contents')
->orderBy('price', $default_sort)
->paginate(2);

How to query a table using result of many-to-many relation with Eloquent ORM?

here is link to my database schema:
How can I get all topics from the blogs to which the user is subscribed using his id? I use Eloquent ORM.
I have added the following lines to my User model:
public function blogs()
{
return $this->belongsToMany('Blog', 'blog_subscriptions');
}
And then requested in the controller
User::find(1)->blogs; // User id is hardcoded
With that I got all blogs to which the user is subscribed.
And now I am stuck on how to get the topics of those blogs.
Assuming relations:
// User
belongsToMany('Blog', 'user_subscriptions')
// Blog
belongsToMany('User', 'user_subscriptions')
hasMany('Topic')
// Topic
belongsTo('Blog')
1 My way, that will work with any relation, no matter how deeply nested:
User::with(['blogs.topics' => function ($q) use (&$topics) {
$topics = $q->get()->unique();
}])->find($userId);
2 Eloquent standard methods:
$topics = Topic::whereHas('blog', function ($q) use ($userId) {
$q->whereHas('users', function ($q) use ($userId) {
$q->where('users.id', $userId);
});
})->get();
// or
$user = User::find($userId);
foreach ($user->blogs as $blog)
{
$blog->topics; // collection of topics for every single blog
}
3 Joins:
$topics = Topic::join('blogs', 'topics.blog_id', '=', 'blogs.id')
->join('user_subscriptions as us', function ($j) use ($userId) {
$j->on('us.blog_id', '=', 'blogs.id')
->where('us.user_id', '=', $userId);
})->get(['topics.*']);
Mind that last solution will rely on your pivot data consistency. That said, if you can't be sure, that there are no redundant entries in user_subscriptions (eg. blog or user has been deleted but the pivot entry remains), then you need to further join users as well.
I am new to laravel and I don't have the possibility of test this, but I had a similar need and solved it with something like this:
DB::Query('topics')->join('blogs', 'blogs.id', '=', 'topics.blog_id')
->join('blog_subscriptions', 'blogs.id', '=', 'blog_subscriptions.blog_id')
->select('name.id','table.email')
->where('blog_subscriptions.user_id', '=', $user_id);

Resources