Get NULL/empty columns in Laravel eloquent query - php

Currently I'm working on a ajax search filters on Laravel, but I cannot get the correct info, this is the scenario:
I have 2 tables:
Table1: SoftwareRequest
Table2: DenyCategory
with a select option I get the name as Value
and I added that select option like in top of the query on the controller function:
$deniedReason = $request->get('deniedReason');
if($deniedReason == "All"){
$deniedReason = "";
}
So that means that every time I select "All" it will be empty so I can get all data like empty (this is the problem).
This is my current query:
$request_data = SoftwareRequest::leftJoin('DenyCategory', 'SoftwareRequest.DenyCategoryId', '=', 'DenyCategory.Id')->where('DenyCategory.Name', 'like', '%' . $deniedReason . '%')->paginate(20);
So the thing is that if I select another option rather than "All", for example "Already Available", I do get the excepted data, meaning all objects from table 1 joined with table 2 that has that option, but the problem comes when I select "All" it doesn't bring all the data it should and that's because not all objects have DenyCategoryId in Table1 meaning that some of those are Null/empty so it only brings the ones 'LIKE' Null/empty as I specified on the previous code block.
$deniedReason = $request->get('deniedReason');
if($deniedReason == "All"){
$deniedReason = "";
}
How can I get all data empty or not empty when I select the option All and as well as to get the data when I select another option? I bet it would have something to do with the query not being 'Like' but that's out of my knowledge scope.

Why not make the where clause optional?
$queryBuilder = SoftwareRequest::leftJoin('DenyCategory', 'SoftwareRequest.DenyCategoryId', '=', 'DenyCategory.Id')
// Only apply where-clause when denied reason has been provided.
if ($request->get('deniedReason') !== 'All') {
$queryBuilder = $queryBuilder->where('DenyCategory.Name', 'like', '%' . $deniedReason . '%');
}
$request_data = $queryBuilder->paginate(20);
I think you can improve your code a bit better but I'll leave that up to you with some pointers:
Eloquent relationships
Class Constants

Related

Order by relevance based on multiple conditions using Laravel

I am having an issue while using order by based on multiple conditions.
User with most filled information should show up top and then the one's with less filled information.
$users = User::where('status',1)
->withCount('reviews')
->with('reviews','about')
->orderByRaw("CASE WHEN is_native != '0' AND photo != '' THEN 0 ELSE 1 END")// how i can match the about us relationship value here? means if user have added about intro then it should come first and reviews count?
->paginate(10);
Here is my About Relationship on User
public function about()
{
return $this->hasOne('App\UserAbout', 'user_id')->select('about');
}
NOTE: i am trying to do it with CASE, if there is any other good option you can please point out that.
Thank you
this means that you have to orderby about's count and then by review count, that will get the result you want:
$users = User::where('status',1)
->withCount(['reviews','about'])
->with('reviews','about')
->orderByRaw('about_count desc,reviews_count desc')
->paginate(10);
now user with 'about' will have about_count=1 others will have about_count =0
As #OMR suggested you can do that. But you don't need to use raw Query
$users = User::where('status',1)
->withCount(['reviews','about'])
->with('reviews','about')
->orderBy('about_count','desc')
->orderBy('reviews_count','desc')
->paginate(10);

Laravel 5.4 where clauses if $request->jobTitle !null?

I built small search form helps me search in jobsTable from db
jobs Table has jobTitle, jobCompany, jobGovernorate, jobLocation and created_at column
And posted data from search form:
{"jobTitle":"designer","jobCompany":null,"jobGovernorate":null,"jobLocation":null,"postingDate":"ad"}
I mean some input may be null, so how to write dynamic where clause for inputs have value, i want search engine able to search by JobTitle, JobCompany or All inputs if have value.
Hint: fields name and table columns name are same
if there's a way to retrieve jobs from my db like
DB::table('jobs')->where($request->all())
Sorry for poor english, I don't know how to explain my question
I prefer to define all search fields.
$searchFields = ['jobTitle','jobCompany','jobGovernorate','jobLocation','postingDate'];
$jobQuery = DB::table('jobs');
foreach ($searchFields as $field) {
if ($request->has($field)) {
$jobQuery->where($field, $request->input($field));
}
}
$results = $jobQuery->get();
you have to code the query, I mean, what are you looking for?
something like
DB::table('jobs')->where([
['jobTitle', 'like', $request->jobTitle . '%'],
['jobCompany', 'like', $request->jobCompany . '%']])->get();

laravel 5 search query issue

I need to search filtering different columns from DB table, those filtering columns are groupA, groupb and groupC, each column has one of following values high, low, moderate in db table
But front end user have anther value called "none", but that value is not contain in database.
This is my current query
public function show($groupA, $groupB, $groupC)
{
$FodMaps = FodMap::where('groupA', '=', $groupA)->where('groupB', '=', $groupB)->where('groupC', '=', $groupC)->get();
return $FodMaps;
}
What I want is if user search with value which does not contain in db (high/low/moderate) it should search the other columns except the one which have unmatching values
ex: http://url/api/fodmap/groupA=low/groupB=low/groupC=high
if user enter above way it should display the results according to the values
but if user inputs like following
http://url/api/fodmap/groupA=low/groupB=low/groupC=none
since "none" value in groupC column does not exit it should search only other two columns without considering the value of groupC
please advice
You can add query condition dynamically like this.
public function show($groupA, $groupB, $groupC)
{
$query = FodMap::query();
if ($groupA !== 'none') {
$query->where('groupA', '=', $groupA)
}
if ($groupB !== 'none') {
$query->where('groupB', '=', $groupB)
}
if ($groupC !== 'none') {
$query->where('groupC', '=', $groupC)
}
return $query->get();
}

Laravel select with multiple where in statement

I have tried various methods to resolve this issue, but none worked for me.
1st method:
$title = Character::find($selected_char->id)->title()->where('title', '=', 'Castle');
$title = $title->where('title', '=', 'City');
$title = $title->get();
2nd method:
$title = Character::find($selected_char->id)->title()->where('title', '=', 'Castle')->where('title', '=', 'City')->get();
3rd method:
$title = DB::select(DB::raw("select * from titles where titles.char_id = 5 and title = 'Castle' and title = 'City'"));
None of the above methods work. If I take only one where clause it works perfectly. Example:
$title = Character::find($selected_char->id)->title()->where('title', '=', 'City')->get();
$title = Character::find($selected_char->id)->title()->where('title', '=', 'Castle')->get();
I even tried to take another column than title, but it doesn't work with a second where function. I want to retreive the rows from titles table where the title is City AND Castle I have used multiple where clauses before in a single select statement and it worked. Not now. Any suggestions? Thanks in advance.
You said:
I want to retreive the rows from titles table where the title is City AND Castle
You may try this:
$rowCOllection = DB::table('titles')
->whereIn('title', array('City', 'Castle'))->get();
Using multiple where:
$rowCOllection = DB::table('titles')
->where('title', 'City')
->where('title', 'Castle')->get();
If you want to add another where clause for titles.char_id then you may use it like:
$rowCOllection = DB::table('titles')
->where('title', 'City')
->where('title', 'Castle')
->where('char_id', 5)->get();
You may chain as much where as you need before you call get() method. You can add the where('char_id', 5) after the whereIn like whereIn(...)->where('char_id', 5) and then call get().
If you have a Title model then you may do the same thing using:
Title::where(...)->where(...)->get();
Same as using DB, only replace the DB::table('titles') with Title, for example:
$rowCOllection = Title::where('title', 'City')
->where('title', 'Castle')
->where('char_id', 5)->get();
What about Character here ?
I don't really know how work your double ->where( in php, but in sql here is the mistake :
When you say where title = 'a' and title = 'b', it's like you say : ok give me something where 0=1 it returns nothing.
You can do :
select * from titles where titles.char_id = 5 and (title = 'Castle' or title = 'City')
Retrieve all data where title equals castle or city
Or
select * from titles where titles.char_id = 5 and title IN ('Castle','City')
Retrieve all data where title equals castle or city using IN
I'm pretty sure you will find a way to do that in PHP too.
Assuming you are using Laravel 4
And Character is your model extended from Eloquent
don't mix FIND and WHERE.
Find is for single usage find AND sorting afterward (so order by, and etc)
So if you want to chain up your query
Character::where()->where()->where()-get() (don't forget the get or else you wont get a result)
this way you respect eloquent's features.
Note your first method with ->title() is flawed because your calling a function that you custom created inside your model - thats why it wouldn't have worked.
Note: WereWolf Alpha's method will also work IF you don't want to use Eloquent because the code that he presented will work but thats Fluent notation...so take your pick.

How to assemble a query with various optional parameters in Laravel?

I have a research to do in a database. Not always I'll be using all of parameters. The user may want to research for a name, but not address or the other way around.
I've tried to use advanced wheres and even unions, but none seems to work. All of them give me a SQL error "General error: 1221 Incorrect usage of UNION and ORDER BY".
Here's a piece of code I've tried
$city_name = ($city_name != null) ? DB::table('cities')->where('name', 'LIKE', "%$city_name%") : DB::table('cities');
$state = ($state_id != '--') ? DB::table('cities')->where('state_id', '=', $state_id) : DB::table('cities');
$cities = DB::table('cities')->union($city_name)->union($state)->orderBy('name')->get();
But it gives me the above described error.
What I really want to do is to select, dinamically, what parameters I put in the query and even assemble it "on the fly". Does anyone knows how to do that?
If I couldn't make myself clear, please let me know in the comments...
I think you need somethink like this:
$query = DB::table('cities');
if ($city_name != null)
{
$query->where('name', 'LIKE', "%$city_name%");
}
if ($state_id != '--')
{
$query->where('state_id', '=', $state_id);
}
$cities = $query->orderBy('name')->get();

Categories