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();
Related
I have a table like this
Teacher Table
What I am trying to do is to get the row which contains the subjects 1(or any other number like 7,8 etc.)
This is what I have tried in my controller.
public function allTeachers($sub_id) //receiving $sub_id(to be searched)
{
$teachers_all=Teacher::where('subjects','like','%'.','.$sub_id.'%')->latest()->paginate(50);
dd($teachers_all);
}
The problem here is that, I am getting all the rows which contains subjects as '1',e.g. if it is '3,11,22' or '41,5' it gets selected.
But what I am trying to achieve is it should only return where subjects string contains '1' followed by any other number after ',' or '1,2,44,31,23' etc.
I am using laravel, I hope I made the question clear.
The solution to your question would be either to use find_in_set or concat to fill some missing commas and then search for the value:
Teacher::whereRaw('find_in_set("' . $sub_id . '", subjects) <> 0')
->latest()
->paginate(50);
or
Teacher::whereRaw('concat(",", colors, ",") like "%,' . $sub_id . ',%"')
->latest()
->paginate(50);
That being said, #bromeer's comments hold true in any case. MySQL isn't around comma-separated values in fields. Both examples shown above aren't an ideal solution. You should look into relationships a bit more.
I suggest using a many-to-many relationship in your case. For that, create a pivot table called teacher_subject and add the relation to your Teacher model:
public function subjects()
{
return $this->belongsToMany(Subject::class);
}
To find any teachers teaching a specific subject, use whereHas like this:
Teacher::whereHas('subjects', function (Builder $query) use ($sub_id) {
$query->where('id', $sub_id);
})->latest()->paginate(50);
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
I have some problems here.
I get a collection which like:
$VenderData=Vender::where('active', '=', '1')->get();
Inside the collection i have a column called 'type' and the data looks like 'A1,A2,A3,'
or
'A1,A3,'
I want to transfer those codes to real names from
another table 'vender_type'.
code name
A1 XX
A2 OO
A3 ZZ
then add a new column into the original collection $VenderData.
How can i do this?
You must split the type attribute (using array explode(string $delimiter , string $string)) , and get the name of each one from vender_type table, try this :
$VenderData = Vender::where('active', '=', '1')->get();
foreach($VenderData as $vend)
{
$vend->new_type = array();
$types = explode(",", $vend->type);
foreach($types as $type)
{
$t = vender_type::where('code', $type)->first();
if($t)
$vend->name_type[] = $t->name;
// or for example : $vend->name_type[$type] = $t->name;
}
}
I hope that will help you.
I think that you need better query than modifying each value after. This vender_type is probably some foreign key in you database so you can get that value in query builder. To find out about foreign keys and joins in laravel eloquent check this.
Basically you need something like this
$users = DB::table('table1')
->join('table2', 'table1.vender_type', '=', 'table2.vender_type')
->select('table1.code', 'table1.name', 'table2.vender_type')
->where('table1.active', '=', '1')
->get();
Just replace table1 and table2 with values of you table names in database and you're done.
Hope it helps
This is for Laravel 5.2. I have a method defined as follows in my Users model:
public function name()
{
return "$this->name_first $this->name_last";
}
I'm trying to figure out how to use that as part of a query, but it seems like it isn't possible for a somewhat obvious reason: the database doesn't know anything about the method and that makes perfect sense. However, the concept of what I'm trying to achieve makes sense in certain contexts, so I'm trying to see if there's a way to accomplish it naturally in Eloquent.
This doesn't work, but it represents what I'm trying to accomplish:
public function index(Request $request)
{
$query = new User();
if(Request::has('name')) {
$query = $query->where('name', 'LIKE', '%' . Request::input('name') . '%');
}
return $query->get();
}
In short, the database only knows about name_first and name_last, but I'd like to be able to search (and sort) on name without storing it. Maybe storing the concatenated name is no big deal and I should just do it, but I'm also trying to learn.
I agree with Bogdan, The issue of having spaces either in the first or the last name makes querying on the individual columns difficult, so this is probably the way to go. Code reuse can be increased by defining it as a custom scope:
https://laravel.com/docs/5.2/eloquent#local-scopes
// class User
public function scopeOfFullNameLike($query, $fullName)
{
return $query->whereRaw('CONCAT(name_first, " ", name_last) LIKE "%?%"', [$fullName]);
}
// ...
User::ofFullNameLike('john doe')->get();
That would mean you should be concatenating the column value at the database level. Which means you could use CONCAT and a whereRaw clause:
$query->whereRaw('CONCAT(name_first, " ", name_last) LIKE ?', ['%' . Request::input('name') . '%']);
Or as an alternative if you want the full name to be selected as part of the result, you could concatenate within the select and use having instead of where to be able to use a column alias:
$query->select('*', DB::raw('CONCAT(name_first, " ", name_last) as name'))
->having('name', 'LIKE', '%' . Request::input('name') . '%');
Not the most compact solutions, but things involving MySQL functions need some raw SQL to work with the Query Builder.
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.