Laravel Select2 Search - php

I use the select2 jquery plugin but I can't search for the data that I want to output.
I've been trying to search the name of a book in my database which should be available and with the company branch, I am currently in. I'm dealing with 2 tables for this.
books
book_type_id [1, 2]
status ['Available', 'Available']
book_type
id [1, 2] name ['Book 1', 'Book 2']
and
public function get_available_book_type(Request $request){
$employee = employee::where('id', Auth::user()->emp_id)->first();
$bt = books::with('book_type')->where('branch_id', $employee->branch_id)
->where('status', 'Available')->where('id', 'LIKE', '%'.$request->name.'%')->groupBy('book_type_id')->get();
$book_type = $bt->where('book_type.name', 'like', '%'.$request->name.'%');
$array = [];
foreach ($book_type as $key => $value){
$array[] = [
'id' => $value['id'],
'text' => $value['book_type']['name']
];
}
return json_encode(['results' => $array]);
}
This results in a "no results found". However, when I use
$book_type = $bt->where('book_type.name', $request->name);
It returns a data so I believe my initial query is correct and not empty but this is not what I want because I use this for searching and I don't expect my user to type the whole word to output it to select2.
The $book_type like query works if I don't use relationship.

You can use whereHas method to filter through the relations:
$book_type = books::with('book_type')
->where('branch_id', $employee->branch_id)
->where('status', 'Available')
->where('id', 'LIKE', '%'.$request->name.'%')
->whereHas('book_type', function($query) use ($request) {
$query->where('book_type.name', 'LIKE', '%'.$request->name.'%');
}
->groupBy('book_type_id')->get();

Related

How to find data matching the search in any field of the column in laravel

i'm trying get data from a table which is called item and i want to bring the items that contains the search string that the user searches for example the user searches "active" so it will go the the table pick up any data that's field contain the word "active". i tried to do it with this piece of code but it does not work.
Route::get('/data', function () {
$items = Item::where('status', 'Like', 'active')->get();
dd($items); });
Any one has a solution?
You can use
$items = Item::where('status', 'like', '%active%')->get();
To search multiple columns you can do orwhere like below
$items = Item::where('status', 'like', '%active%')
->orWhere('column2', 'like', '%active%')
->orWhere('column3', 'like', '%active%')
->get();
or
$columns=['col1','col2','col3'];
$items = Item::query();
foreach($columns as $column){
$items->orWhere($column,'like','%active%')
}
$result=$items->get();
or
$columns=['col1','col2','col3'];
$items = Item::where(function($query)use($columns){
foreach($columns as $column){
$query->orWhere($column,'like','%active%')
}
})->get();

How can I search with multiple columns in Laravel

I am very new in Laravel, I try to search with one column and this is my code. But now I want to search with multiple columns - how can I do that?
My controller :
public function search_pers(Request $request)
{
$mle = $request->input('mle');
$listpers = Personne::where('mle', 'LIKE', '%'.$mle.'%')->get();
return view('frontend.etat_civil', ['personnes' => $listpers]);
}
You could use an array
Personne::where([
['col1', '=', 'value1'],
['col2', '<>', 'value2'],
[Your_col, OPERATOR, value],
...
])
or in your case
$str = "concat('%',".$mle .",'%')";
$listpers = Personne::where([
['mle', 'LIKE', $str],
['col1', '=', 'value1'],
['col2', '<>', 'value2'],
[Your_col, OPERATOR, value],
)->get();
As I understand what you need is an orWhere condition:
public function search_pers(Request $request)
{
$mle = $request->input('mle');
$listpers = Personne::where('mle', 'LIKE', '%'.$mle.'%')->orWhere('nom','like','%'.$mle.'%')->get();
return view('frontend.etat_civil', ['personnes' => $listpers]);
}
Another alternative and probably a better one is to use fulltext search.
MySQL Fulltext search

Laravel eloquent - Filtering subquery inside with statement

I have the following query:
$countries = Country::where('code', '=', $code)
->with(array('cities.details' => function ($query) use ($user) {
$query->where('cities.name', '=', 'This is a city name');
}))->first();
Lets see the example: I have three tables, Country, City and CityDetails. I want to get all countries, then get all cities (INCLUDING the details information) but I also want to filter cities by name and fetch details table which belongs to the city table.
If I want to use with to get the child and another table using with(cities.details), how can I filter using CITIES attributes?
The main question is: How can I fetch two tables in a with statement like secondTable.OtherTable and filter the query using secondTable attributes?
Just for make it clearer, if I use statement like this:
$countries = Country::where('code', '=', $code)
->with(array('cities.details' => function ($query) use ($user) {
$query->where('name', '=', 'This is a detail name');
}))->first();
I can access only details table attributes. The question is: How can I access the city table attribute to filter inside a with a statement?
Thanks in advance
I just found a solution. Basically, I should apply the filter for city table and then call wit function on the subquery. This code solved my problem:
$countries = Country::where('code', '=', $code)
->with(array('cities' => function ($query) use ($user) {
$query->where('name', '=', 'San Francisco')->with('details');
}))->first();
Note that I called with('details') on city only after filter in subquery.
The most straightforward one is using join query:
(new Country)
->join('cities', 'cities.id', '=', 'countries.city_id')
->join('city_details', 'cities.id', '=', 'city_details.city_id')
->where('cities.name', 'TheName')
->where('city_details.info', 'info')
->select('...');
But the result has only one level. So,
$query = (new Models\Country())
->with([
'cities' => function ($query) {
$query->where('name', 'xxx')->with([
'details' => function ($query) {
$query->where('info', 'info');
}
]);
}
]);
$result = $query->get()->filter(function ($item) {
return count($item['cities']);
});
The result gives countries with empty cities. So use Laravel collection to filter in the last.

Laravel, how to call or append(join) another model with condition in existing model condition

I am stuck with search functionality from two different tables (VenueHall and Venue). The data is coming in the search1 parameter. I am able to search the data from one table (VenueHall) but I am not able to map with another table (Venue) using the existing object from the first table ($VenueHall`).
$VenueHall = VenueHall::orderBy('created_at', 'DESC');
$VenueHall = $VenueHall->with('venue');
$VenueHall = $VenueHall->with('venueType');
$VenueHall = $VenueHall->with('venue.area');
if (Input::has('query') && $searchQuery = Input::get('query'))
{
$perecentilify = '%'. $searchQuery .'%';
$VenueHall = $VenueHall->where(function($query) use ($perecentilify, $searchQuery) {
$query->where('name', 'LIKE', $perecentilify)
->orWhere('code', 'LIKE', $perecentilify);
//->orWhere('from venue table');
});
}
$data = array(
'venueHall' => $VenueHall->paginate(2)
);
return View::make('venues/venues', array('data' => $data));
I am not able to map the //->orWhere('from venue table') clause which comes from the Venue table. Please help me out get the data from the two tables based on the search value in the search box.
Often I find joins to be the easiest solution in such cases:
$VenueHall = VenueHall
::join('Venue', 'Venue.id', '=', 'VenueHall.venue_id')
->where('VenueHall.name', 'LIKE', $perecentilify)
->orWhere('VenueHall.code', 'LIKE', $perecentilify)
->orWhere('Venue.name', 'LIKE', $perecentilify)
->orderBy('created_at', 'DESC')
->with(['venue', 'venueType', 'venue.area'])
->paginate(2)
;

Laravel 4, messy Eloquent join query

I'm working on somehow messy project where structure of db is:
Object
id, title, description, url ... [and some more columns]
ObjectMeta
object_id, variable, value
So let's give you:
Object: 1, 'Cool Book', 'This cool book is just for you!', ...
Object Meta:
1, 'author_name', 'John Doe'
1, 'released', 2014
1, 'price', 23.22
1, 'url', 'http://amazon.com/coolbook'
1, 'genre', 3
So I need to perform query which will:
Pull all Objects that has genre 3, then sort those Objects by their released date.
$objs = static::Active()
->where('object', '=', $object)
->where('category','=',$category)
->whereIn('site_id', array(self::$site_id, 0))
->leftJoin('object_meta', function($join)
{
$join->on('object.id','=', 'object_meta.content_id');
})
->where('object_meta.variable', 'genre')
->where('object_meta.value', 3);
->where('object_meta.variable', 'released');
->orderBy('object_meta.value', 'desc');
->groupBy('object.id')
->paginate(20);
This query has 0 results even if there are plenty of those books out there. I know that the second object_meta.variable where is guilty here. How can I write this query to make it work?
Really appreciating your help.
-- Edit
I've created workaround but it's really, really bad workaround (funny thing is that I swear the query above was working for month or so).
$objs = static::Active()
->where('object', '=', $object)
->where('category','=',$category)
->whereIn('site_id', array(self::$site_id, 0))
->leftJoin('object_meta', function($join)
{
$join->on('object.id','=', 'object_meta.content_id');
})
->where('object_meta.variable', 'genre')
->where('object_meta.value', 3);
->groupBy('object.id')
->get();
foreach($objs as $obj)
{
$obj->id = $obj->object_id;
$objs_meta = ObjectMeta::where('object_id',$obj->object_id)->get();
foreach($objs_meta as $obj_meta)
{
$variable = $obj_meta->var;
$obj->$variable = $obj_meta->value;
}
}
$objs = $objs->sortBy(function($role){
return $role->released;
});
$objs = Paginator::make($objs->toArray(), sizeof($objs), $limit);
You need inner join (join()) not leftJoin(), and you need it twice:
$objs = static::Active()
->where('object', '=', $object)
->where('category','=',$category)
->whereIn('site_id', array(self::$site_id, 0))
->join('object_meta as genre', function ($join) {
$join->on('object.id', '=', 'genre.content_id')
->where('genre.variable', '=', 'genre')
->where('genre.value', '=', 3);
})
->join('object_meta as released', function ($join) {
$join->on('object.id', '=', 'released.content_id')
->where('released.variable', '=', 'released');
})
->orderBy('released.value', 'desc');
->select('object.*', 'released.value as released')
->distinct()
// or group by, doesn't matter in your case
// ->groupBy('object.id')
->paginate(20);
Then your objects will have additional property released with appropriate value.
According to the comments:
If you want to dynamically add the joins, then I suggest scopes like below:
public function scopeGenre($query, $value)
{
$query->join('object_meta as genre', function ($join) use ($value) {
$join->on('object.id', '=', 'genre.content_id')
->where('genre.variable', '=', 'genre')
->where('genre.value', '=', $value);
});
}
then:
$query->where(..)->genre(3)->...

Categories