Laravel OrWhere having two conditions is not so obvious - laravel

Why in Eloquent a simple query as this one is not working?
$matches = DB::table("matches")
->where(["team_a"=> $request->tid, "match_tipo"=>3])
->orWhere(["team_a"=> $request->tid, "match_tipo"=>3])
->first();
According to with other examples here on Stackoverflow, I should use a query in Where like:
$matches = DB::table("matches")
->where(["match_tipo"=>3])
->where(function($query, $request) {
$query->where('team_h',$request->tid)
->orWhere('team_a',$request->tid);
})
->first();
But I should pass a second parameter ($request).
How is the simplest way to do this query?

You can make this as like this.
->where(["match_tipo"=>3]) this will be ->where("match_tipo",3) and use($tid) after query.
$tid = $request->tid;
$matches = DB::table("matches")
->where("match_tipo",3)
->where(function($query) use($tid) {
$query->where('team_h',$tid)
->orWhere('team_a',$tid);
})
->get();

while using the Callback or Closure as the where function Parameter you will only the one argument which is Current Object
Methods Can used to Pass the $request
Method One
$matches = DB::table("matches")
->where(["match_tipo"=>3])
->where(function($query) use ($request) {
$query->where('team_h',$request->tid)
->orWhere('team_a',$request->tid);
})
->first();
Method Two
$matches = DB::table("matches")
->where('match_tipo','=',3)
->when($request->tid,function($query) use ($request) {
return $query->where('team_h',$request->tid)
->orWhere('team_a',$request->tid);
})
->first();

Try this query :
$matches = DB::table("matches")
->where('match_tipo',3)
->whereRaw('team_a = "'.$request->tid.'" OR team_h = "'.$request->tid.'"')
->first();

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

Laravel apply pagination based on condition in query

I am using laravel eloquent for db operation. I create a done function in that I want to apply my pagination if the variable has value if the variable value is not found then it should use laravel get() method. Here is my code
$query = DB::table('mytable')
->when($searchBy != null, function ($query) use ($searchBy) {
return $query->where('mytable.id', '=', $searchBy)
->orWhere('orders.id', '=', $searchBy)
})
->orderBy('mytable.id', 'desc')
->paginate($recordsPerPage, ['*'], 'page', $pageNub);
I want to add pagination if $recordsPerPage variable is > 0, otherwise it should be use get() method
You would assign the builder to a variable and use some type of conditional here:
$query = DB::table('mytable')
->when($searchBy, function ($query, $searchBy) {
return $query->where('mytable.id', '=', $searchBy)
->orWhere('orders.id', '=', $searchBy)
})->orderBy('mytable.id', 'desc');
$result = ($recordsPerPage > 0) ?
$query->paginate(...) :
$query->get();

Query relationship inside the relationship in Laravel Eloquent

I am trying to get the news of a writer according to date passed. I have written function so far:
public static function getNewsByAuthorByDate($id, $year, $limit = 1){
return User::where('id', $id)->has('news')
->with(['news' => function($q) use(&$limit, &$year) {
$q->where('created_at', 'like', '%' . $year . '%')->latest()->limit($limit);
}])
->first();
}
But the news[] is null. Is it possible to get writer news according to date or do I have to try another way?
you can use whereYear
public static function getNewsByAuthorByDate($id, $year, $limit = 1){
return User::where('id', $id)->has('news')
->with(['news' => function($q) use(&$limit, &$year) {
$q->whereYear('created_at',$year)->latest()->limit($limit);
}])
->first();
}
and to use limit with eager loading you should use the package eloquent-eager-limit
According to the documentation:
The limit and take query builder methods may not be used when constraining eager loads.
Also, You don't need to use has method, the news would be empty if the user has no news:
return User::with(['news' => function($q) use($year) {
$q->whereYear('created_at', $year)->latest();
}])
->find($id);

Eloquent where condition AND ( condition OR condition OR condition )

Can somebody tell me what am I doing wrong?
I want to get all projects with status 0 and if any of data matches in eloquent.
My code is like this
public function search(Request $request){
if($request->has('q')){
$search_query = $request->input('q');
$projects = Project::where(['status' => '0'])->get();
$projects = $projects->where(function($query) use ($search_query) {
$query->where('title','LIKE','%'.$search_query.'%')
->orWhere('shortDescription','LIKE','%'.$search_query.'%')
->orWhere('longDescription','LIKE','%'.$search_query.'%')
->orWhere('tags','LIKE','%'.$search_query.'%')
->orWhere('projectLink','LIKE','%'.$search_query.'%');
});
$projects->get();
dd($projects);
}
}
And I am getting this error
ErrorException
explode() expects parameter 2 to be string, object given
I solved the problem but changed the code a little bit... If you like, take it! I tested and it's working.
if($request->has('q')){
// Your $request->q Value
$term = $request->q;
$projects = DB::table('tbl_projects')->where('status', '=', 0)
->where(function ($query) use ($term) {
$query->where('title', 'LIKE', '%'.$term.'%')
->orWhere('shortDescription', 'LIKE', '%'.$term.'%')
->orWhere('longDescription', 'LIKE', '%'.$term.'%')
->orWhere('tags', 'LIKE', '%'.$term.'%')
->orWhere('projectLink', 'LIKE', '%'.$term.'%');
})
->get();
//dd($projects);
}
Raw query is:
select * from `tbl_projects` where `status` = 0 and (`title` LIKE %bla bla% or `shortDescription` LIKE %bla bla% or `longDescription` LIKE %bla bla% or `tags` LIKE %bla bla% or `projectLink` LIKE %bla bla%))
Regards!
Your error is
$projects = Project::where(['status' => '0'])->get();
(['status' => '0']) Where clause params required is different. You must use ('status', '0') or ('status', '=', '0')
When you use ->get(), you have a Collection or EloquentCollection object. You need a QueryBuilder
Try to implement a better programation logic.
A better implementation is
public function search(Request $request){
if($request->has('q')){
// Add array with field coincidences target. Is better if this array is a const static field in the Project model
$searchFields = ['title', 'shortDescription', 'longDescription', 'tags', 'projectLink' ];
// Now you can add 100 fields for search coincidences easily
$search_query = $request->input('q');
$projects = Project::where('status', '0');
foreach($searchFields as $searchField){
if ($searchField == 'title'){
$projects = $projects->where($searchField,'LIKE',"%$search_query%");
continue;
}
$projects = $projects->orWhere($searchField,'LIKE',"%$search_query%");
}
$projects = $projects->get();
dd($projects);
}
}

How to add and exclude where() clause in laravel query builder

How to add and exclude where() clause in laravel query builder so that in one case it will be added in other one no
$orders = DB::table('orders')->select(
'orders.id as id',
'orders.created_at as created',
'u.email as email',
'ud.id as data_id',
'ud.firstName as firstName',
'ud.lastName as lastName',
'ud.phone as phone',
's.name as service',
's.id as service_id',
'pt.id as payment_type_id',
'pt.name as payment_name')
->join('users as u', 'orders.user_id', '=', 'u.id')
->join('user_data as ud', 'u.id', '=' ,'ud.user_id')
->join('payment_types as pt', 'orders.payment_type_id', '=', 'pt.id')
->join('services as s', 'orders.service_id', '=', 's.id')
->where('u.id', $user->id)->orderBy($sortBy, $type)->get();
I want to do this
$order = DB::table()....
if(true){
$order->where('id', '=', 1);
}
$order->orderBy('fieldname', 'asc')->get();
But the example above return no results
For conditional clauses you can make use of when().
$order = DB::table()
->yourQuery(...)
->when($var, function ($query, $var) { // <----
return $query->where('id', '=', 1); // <----
} // <----
->orderBy('fieldname', 'asc')
->get();
You can read more about this in the docs:
Conditional Queries
Sometimes you may want clauses to apply to a query only when something
else is true. For instance you may only want to apply a where
statement if a given input value is present on the incoming request.
You may accomplish this using the when method:
$role = $request->input('role');
$users = DB::table('users')
->when($role, function ($query, $role) {
return $query->where('role_id', $role);
})
->get();
The when method only executes the given Closure when the first
parameter is true. If the first parameter is false, the Closure will
not be executed.
...

Resources