Laravel multiple column eloquent search query - mysql

i am very new in Laravel,currently working with Laravel4.I am trying to add a multiple column search functionality in my project.I can do single column eloquent search query,But honestly i have no idea how to do multiple column eloquent search query in laravel.I have two drop down menu
1.Locatiom
2.blood group.
i want to search an user having certain blood group against certain location.That is, user will select a location and blood group from those two drop down menu at a time and hit the search button.
In my database,i have two column, one contains the location and another contains the blood group of a certain user. Now,what should be the eloquent query for such a search?

Simply chain where for each field you need to search through:
// AND
$results = SomeModel::where('location', $location)->where('blood_group', $bloodGroup)->get();
// OR
$results = SomeModel::where('location', $location)->orWhere('blood_group', $bloodGroup)->get();
You can make it easier to work with thanks to the scopes:
// SomeModel class
public function scopeSearchLocation($query, $location)
{
if ($location) $query->where('location', $location);
}
public function scopeSearchBloodGroup($query, $bloodGroup)
{
if ($bloodGroup) $query->where('blood_group', $bloodGroup);
}
// then
SomeModel::searchBloodGroup($bloodGroup)->searchLocation($location)->get();
Just a sensible example, adjust it to your needs.

This is a great way but I think there is an error somewhere as laravel would not allow you to access a non-static function so instead of using
SomeModel::searchBloodGroup($bloodGroup)->searchLocation($location)->get();
you could simply use
SomeModel::BloodGroup($bloodGroup)->Location($location)->get();
take note of the searchBloodGroup has been changed to BloodGroup, that's how you will use it for all others also.

$errors = $connection->table('test_sessions_table')
->where('user_id', $user->id)
->where('status_question', 'false')->count('status_question');
in this method your code takes the following form
SQL code
select count(`status_question`) as aggregate from `test_sessions_table` where `user_id` = ? and `status_question` = ?
orWhere your code will look like this
$errors = $connection->table('test_sessions_table')
->where('user_id', $user->id)
->orWhere('status_question', 'false')->count('status_question');
SQL code
select count(`status_question`) as aggregate from `test_sessions_table` where `user_id` = ? or `status_question` = ?
Personally, I recommend using two ‘where’

Related

How to return the data of another model instance model by using joins in laravel?

I want to return the data of Charge instance instead of User , for that i am trying to use joins ,can you please help me to acheive this thing
$id=Charge::whereNotNull('created_by')->get('created_by')->toArray();
foreach($id as $name){
$id[] = $name['created_by'];
}
return $v=User::whereIn('id',$id)->where('username',$request->data)->get();
}
for this i am trying to use left join , relationship available between created_by and id (I am trying to convert above queries into single query)
$v=Charge::whereNotNull('created_by')->leftJoin('User',function($join){
$join->on('Charge.created_by','=','User.id');
})->get();

Filter With() in Query Scope

Controller
$r = \App\User::whereIn('id', $user_ids)->withPosts($category_id)->get();
User model
public function scopeWithPosts($query, $category_id)
{
return $query->with('posts')->where('category_id', $category_id);
}
I have been at this for too many hours now.
I am trying to use with() along with an query scope to add an extra filter to the relationship.
However it gives me the error " category_id not existing in users table"? What am I missing?
Laravel 6
The problem you are experiencing is that you are expecting the with('posts') function to return a query that is relative to the Posts ORM model. It won't, it will still return a reference to the original query. What you will find is that the with function returns $this, so you'll always get the original query.
What you are attempting is a SQL query to find the User, followed by another SQL query to get all the Post records of that user, with those posts filtered by category. So
SELECT * FROM Users WHERE id=?;
SELECT * FROM Posts WHERE user_id = ? AND category_id = ?
To do that in the Eloquent relationship, you need to subquery, like so:
return $query->with(['posts' => function ($q) use ($category_id) {
$q->where('category_id', $category_id);
}]);
Please comment if you need further info and I'll edit my answer.

Eloquent Query, possible Join

I have three models: driver, designation and dpsObject, with the following replationships:
driver->hasMany(dpsObject)
driver->belongsTo(Designation)
designation->hasMany(Driver)
dpsObject->belongsTo(Driver)
I'm trying to write a query to return a list of dpsObject records that correspond to the values of three user inputs, which are: a date range(From and To) holding the values of an EntryDate field in the dpsObject and a Designation input, holding the value of a Designation_name field in the Designation object.
Currently this is my Query:
$dps = dpsObject::where([['entryDate', '>=', $from],
['entryDate', '<=', $to]]);
$from and $to hold the request values gotten from the form user's submit.
I need to complete the query to capture the Designation name of a driver that that has dpsObject records. The challenge is that the designation_name field does not exist on the dpsObject model but only on the driver and designation models. This is how I want to maintain the database model. I think I need to be using a join or something similar, but I'm not sure how to go about it.
What is the best way to write such a query?
Kind regards
You can use nested whereHas():
$dpsObjects = dpsObject::whereBetween('entryDate', [$from, $to])
->whereHas('driver', function ($q) use($designationName) {
$q->whereHas('designation', function ($q) use($designationName) {
$q->where('designation_name', $designationName);
});
})
->get();
Here, designation and driver are belongsTo() relationships.

Laravel Fluent add select()s in separate places?

//Earlier in the code, in each Model:
query = ModelName::select('table_name.*')
//Later in the code in a function in a Trait class that is always called
if ($column == 'group_by')
{
$thing_query->groupBy($value);
$thing_query->select(DB::raw('COUNT('.$value.') as count'));
}
Is there a way to append or include a separate select function in the eloquent query builder?
The actual ->select() is set earlier and then this function is called. I'd like to add the count column conditionally in this later function that has the query passed into it.
For future reference, you can use the addSelect() function.
It would be good to have in the documentation, but you'll find it here in the API: http://laravel.com/api/4.2/Illuminate/Database/Query/Builder.html#method_addSelect
Yeah you just insert the block you wanna execute as a function....according to the documentation on Parameter Grouping , you can do like so...by passing the Where a function...
This code below probably wont do what you want, but, its something for you to build off of, and play around with.
DB::table('users')
->where('name', '=', 'John')
->orWhere(function($query)
{
$query->group_by($value);
->select(DB::raw('COUNT('.$value.') as count'));
})
->get();
Try this:
$thing_query->groupBy($value)->get(DB::raw('COUNT('.$value.') as count'));
Also,if you are just trying to get the count and not select multiple things you can use ->count() instead of ->get()

Laravel Fluent queries - How do I perform a 'SELECT AS' using Fluent?

I have a query to select all the rows from the hire table and display them in a random order.
DB::table('hire_bikes')->order_by(\DB::raw('RAND()'))->get();
I now want to be able to put
concat(SUBSTRING_INDEX(description, " ",25), "...") AS description
into the SELECT part of the query, so that I can select * from the table and a shortened description.
I know this is possible by running a raw query, but I was hoping to be able to do this using Fluent or at least partial Fluent (like above).
How can I do it?
You can actually use select AS without using DB::raw(). Just pass in an array into the select() method like so:
$event = Events::select(['name AS title', 'description AS content'])->first();
// Or just pass multiple parameters
$event = Events::select('name AS title', 'description AS Content');
$event->title;
$event->content;
I tested it.
Also, I'd suggest against using a DB:raw() query to perform a concatenation of your description field. If you're using an eloquent model, you can use accessors and mutators to perform this for you so if you ever need a limited description, you can simply output it in your view and not have to use the same query every time to get a limited description. For example:
class Book extends Eloquent
{
public function getLimitedDescriptionAttribute()
{
return str_limit($this->attributes['description'], $limit = 100, $end = '...');
}
}
In your view:
#foreach($books as $book)
{{ $book->limited_description }}
#endforeach
Example Output (not accurate to limit):
The description of this book is...
I'd also advise against using the DB facade because it always utilizes your default connection. If you're querying a secondary connection, it won't take this into account unless you actively specify it using:
DB::connection('secondary')->table('hire_bikes')->select(['name as title'])->get();
Just to note, if you use a select AS (name AS title) and you wish to update your the model, you will still have to set the proper attribute name that coincides with your database column.
For example, this will cause an exception because the title column does not exist in your database table:
$event = Events::select('name AS title')->first();
$event->title = 'New name';
$event->save(); // Generates exception, 'title' column does not exist.
You can do this by adding a DB::raw() to a select an array in your fluent query. I tested this locally and it works fine.
DB::table('hire_bikes')
->select(
array(
'title',
'url',
'image',
DB::raw('concat(SUBSTRING_INDEX(description, " ",25),"...") AS description'),
'category'
)
)
->order_by(\DB::raw('RAND()'))
->get();
select(array(DB::raw('latitude as lat'), DB::raw('longitude as lon')))