Multiple where condition does not work o n the Laravel eloquent - laravel

I am new to Laravel. I am writing an Eloquent query but it does not work.
the code is
$stories = Stories::with(['user', 'comment'])
->where('blocked', 1)
->where('title', 'like', '%' . $request->title . '%')
->orWhere('story', 'like', '%' . $request->story . '%')
->orWhere('section', 'like', '%' . $request->section . '%')
->orWhere('tags', 'like', '%' . $request->tags . '%')
->orderBy('id', 'DESC')
->get();
but it returns with 'blocked', 0
How can I get the result with 'blocked', 1 as well as the Search value?

You have an order of operations issue. Consider using this version:
$stories = Stories::with(['user', 'comment'])
$query->where('blocked', 1)
->where(function($query) {
$query->where('title', 'like', '%' . $request->title . '%')
->orWhere('story', 'like', '%' . $request->story . '%')
->orWhere('section', 'like', '%' . $request->section . '%')
->orWhere('tags', 'like', '%' . $request->tags . '%')
})
->orderBy('id', 'desc')
->get();
Here is the raw query you currently running:
SELECT *
FROM stories
WHERE (blocked = 1 AND
title LIKE ?) OR
story LIKE ? OR
section LIKE ? OR
tags LIKE ?
ORDER BY id DESC;
Note carefully that I have included parentheses, as the query will actually be evaluted. Here is the version you really want, corresponding to the above Eloquent code:
SELECT *
FROM stories
WHERE blocked = 1 AND
(title LIKE ? OR
story LIKE ? OR
section LIKE ? OR
tags LIKE ?)
ORDER BY id DESC;

Since you need blocked with other fields where you should use advanced query
https://laravel.com/docs/8.x/queries#subquery-where-clauses
$stories = Stories::with(['user', 'comment'])
->where('blocked', 1)
->where(function($q) use ($request) {
$q->where('title', 'like', '%' . $request->title . '%')
->orWhere('story', 'like', '%' . $request->story . '%')
->orWhere('section', 'like', '%' . $request->section . '%')
->orWhere('tags', 'like', '%' . $request->tags . '%');
})->orderBy('id', 'DESC')->get();

Related

Unknown column total when using where

I have made this query:
$query = UserHistoryAccess::with('user')
->select('user_history_accesses.*', DB::raw('count(user_history_accesses.id) as total'))
->join('users', 'user_history_accesses.user_id', 'users.id')
->groupBy('user_history_accesses.user_id')
->where('total', 'like', '%' . $term . '%')
;
Even I have followed this solution but I got this error :
Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'total' in 'where clause' (SQL: select count(*) as aggregate from user_history_accesses inner join users on user_history_accesses.user_id = users.id where total like %388%) in file C:\xampp\htdocs\HabilitisBack\vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 671
you can not use result colum in the where, you should recalculate it in the where to get the desired result, but try using 'having':
->having('total', 'like', '%' . $term . '%');

Is there any way to get model object instead of stdClass object while using Laravel DB:Query Builder?

In below code i tried to get nearby users and distances. Everything is working well. But below query returns results as a stdClass Object But I want User Model Object. Is it possible?
$collection = DB::table('users')
->join('locations as l', 'users.location_id', '=', 'l.id')
->select('users.*', DB::raw('(6371 * acos(cos(radians(' . $coordinates['latitude'] . ')) * cos(radians(`lat`)) * cos(radians(`lng`) - radians(' . $coordinates['longitude'] . ')) + sin(radians(' . $coordinates['latitude'] . ')) * sin(radians(`lat`)))) as distances'))
->having('distances', '<', 32.688888)
->orderBy('distances', 'ASC')
->get();
Output:
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => stdClass Object
(
)
)
)
I want
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => App\Models\User Object
(
)
)
)
This is because you're using the query builder instead of the model.
You should be able to achieve what you're after with the following:
$collection = User::join('locations as l', 'users.location_id', '=', 'l.id')
->select('users.*', DB::raw('(6371 * acos(cos(radians(' . $coordinates['latitude'] . ')) * cos(radians(`lat`)) * cos(radians(`lng`) - radians(' . $coordinates['longitude'] . ')) + sin(radians(' . $coordinates['latitude'] . ')) * sin(radians(`lat`)))) as distances'))
->having('distances', '<', 32.688888)
->orderBy('distances', 'ASC')
->get();

In Laravel only one of two joins work when the second parameter is a function with LIKE

I have one search term $term.
I have 3 tables.
1st is vehicles
and has id (int, autoincr., unique), vehicle_id (int) - which can be identical, vehicle_type (int) - can be 1 or 2 - 1 denotes car and 2 is for motorcycle. Example, how it could look like:
----------------------------------
| id | vehicle_id | vehicle_type |
|--------------------------------|
| 1 | 546 | 1 |
----------------------------------
| 2 | 257 | 1 |
----------------------------------
| 3 | 546 | 2 |
----------------------------------
| 4 | 368 | 1 |
----------------------------------
2nd is cars
and has id (int, autoincr., unique), title - (varchar), Example:
-------------------
| id | title |
|------------------
|544 | Abbycar |
-------------------
|545 | Batmobil |
-------------------
|546 | WackyWheel |
-------------------
|547 | Ferrari |
-------------------
3nd is motorcycles
and has id (int, autoincr., unique), title - (varchar), Example:
-------------------
| id | title |
|------------------
|544 | Abbycycle |
-------------------
|545 | Batcycle |
-------------------
|546 | WackyBike |
-------------------
|547 | Motorrari |
-------------------
Now, I want to use the 1st table's vehicle_id (vehicle.vehicle_id) and join it with the 2nd table's id (cars.id) but only under the condition that the vehicle_type is 1 (car). And at the same time the car's title should contain the $term using LIKE.
And at the same time I want to join 1st table's vehicle_id (vehicle.vehicle_id) with the 3rd table's id (motorcycles.id) but only under the condition that the vehicle_type is 2 (motorcycle). And at the same time the motorcycle's title should contain the $term using LIKE.
So far, I have this code:
$result = DB::table('vehicles')->join('cars', function($join) use($term)
{
$join->on('vehicles.vehicle_id', '=', 'cars.id')
->where('vehicles.vehicle_type', '=', '1')
->where('cars.title', 'LIKE', '%' . $term . '%');
})
->join('motorcycles', function($join2) use($term)
{
$join2->on('vehicles.vehicle_id', '=', 'motorcycles.id')
->where('vehicles.vehicle_type', '=', '2')
->where('motorcycles.title', 'LIKE', '%' . $term . '%');
})
->get();
The problem is that when I have a car and a motorcycle that have the same name and teh $term contains part of it, only the car is catched. If I comment the cars join part the motorcyle is shown, but I want both. How to do that?
Why is the second join being ignored?
Because this works:
$result = DB::table('vehicles')->join('cars', function($join) use($term)
{
$join->on('vehicles.vehicle_id', '=', 'cars.id')
->where('vehicles.vehicle_type', '=', '1')
->where('cars.title', 'LIKE', '%' . $term . '%');
})
->get();
And this works too:
$result = DB::table('vehicles')->join('motorcycles', function($join2) use($term)
{
$join2->on('vehicles.vehicle_id', '=', 'motorcycles.id')
->where('vehicles.vehicle_type', '=', '2')
->where('motorcycles.title', 'LIKE', '%' . $term . '%');
})
->get();
Each of those queries gives me a different results as expected, however, 2 joins in a row gives me nothing.
EDIT:
result of this:
$result = DB::table('vehicles')
->join('cars', 'vehicles.vehicle_id', '=', 'cars.id')
->join('motorcycles', 'vehicles.vehicle_id', '=', 'motorcycles.id')
->where('cars.title', 'LIKE', '%' . $term . '%')
->orWhere('motorcycles.title', 'LIKE', '%' . $term . '%')
->get();
is this:
[query] =>
select vehicles.vehicle_type as vehicle_type, vehicles.vehicle_id as vehicle_id
from `vehicles` inner join `cars` on `vehicles`.`vehicle_id` = `cars`.`id` and `vehicles`.`vehicle_type` = ?
inner join `motorcycles` on `vehicles`.`vehicle_id` = `motorcycles`.`id` and `vehicles`.`vehicle_type` = ? where `cars`.`title` LIKE ? or `motorcycles`.`title` LIKE ?
[bindings] => Array
(
[0] => 1
[1] => 2
[2] => %test%
[3] => %test%
)
I have not tested this but here is a possible solution:
$result = DB::table('vehicles')
->join('cars', 'vehicles.vehicle_id', '=', 'cars.id')
->join('motorcycles', 'vehicles.vehicle_id', '=', 'motorcycles.id')
->where('cars.title', 'LIKE', '%' . $term . '%')
->orWhere('motorcycles.title', 'LIKE', '%' . $term . '%')
->get();
This should result in a sql statement as follows:
select * from `vehicles`
inner join `cars` on `vehicles`.`vehicle_id` = `cars`.`id`
inner join `motorcycles` on `vehicles`.`vehicle_id` = `motorcycles`.`id`
where `cars`.`title` LIKE %term%
or `motorcycles`.`title` LIKE %term%
Try this:
$result = DB::table('vehicles')
->leftJoin('cars', function($join) {
$join->on('vehicles.vehicle_id', '=', 'cars.id')
->where('vehicles.vehicle_type', '=', 1);
})->leftJoin('motorcycles', function($join) {
$join->on('vehicles.vehicle_id', '=', 'motorcycles.id')
->where('vehicles.vehicle_type', '=', 2);
})
->where('cars.title', 'LIKE', '%' . $term . '%')
->orWhere('motorcycles.title', 'LIKE', '%' . $term . '%')
->get();

Using 'like' on 2 SQL columns combined

I currently have 2 columns in my table going by the name of uploadDate and uploadTime. I have a clause like this:
->orWhere('uploadDate', 'like', '%' . $request->search . '%')
->orWhere('uploadTime', 'like', '%' . $request->search . '%');
The problem is that if $request->search = yyyy-mm-dd, hh:mm:ss, my web app is not able to get any results since uploadDate and uploadTime are seperate columns on the DB. Does anyone have a way of creating a orWhere statement that concatinates both uploadDate and uploadTime?
I know this can be easily achieved by just creating a single column in the DB that merges both columns but I'm just looking for an easier way out at this point, hahaha.
You shouldn't use like or orWhere() here if you want to find records by exact date and time.
->where('uploadDate', str_before($request->search, ','))
->where('uploadTime', str_after($request->search, ', '))
If you have other where() or orWhere() clauses in the query, you can do this:
->where([
'uploadDate', '=', str_before($request->search, ','),
'uploadTime', '=', str_after($request->search, ', ')
])

convert raw mySQL statement to laravel 4 eloquent with pagination

I'm trying to express MySQL statment in Eloquent with pagination
code:
$query = "(SELECT city_name FROM Cities WHERE city_name LIKE '%" .
$keyword . "%')
UNION
(SELECT area_name FROM Areas WHERE area_name LIKE '%" .
$keyword . "%')
UNION
(SELECT sub_location_name FROM Sub_locations WHERE sub_location_name LIKE '%" .
$keyword . "%' )";
Try This :
$cities = DB::table('Cities')->select('city_name')->where('city_name', $keyword);
$area=DB::table('Areas')->select('area_name')->where('area_name', $keyword);
$result=DB::table('Sub_locations')
->select('sub_location_name')
->where('sub_location_name', $keyword)
->union($cities)
->union($area)
->paginate(15);

Resources