Laravel search DB with multiple tables - php

I have a table named records with a user_id column which links to a users table to set ownership.
I can correctly filter the records by title with a search string:
$records->where('title', 'LIKE', '%'.$search.'%');
But I'd like to return also the results containing the users.firstname and users.lastname, this is my (awful) join attempt:
$records->join('users', 'users.id', '=', 'records.user_id')
->where('users.firstname', 'LIKE', '%'.$search.'%')
->orWhere('users.lastname', 'LIKE', '%'.$search.'%')
->orWhere('title', 'LIKE', '%'.$search.'%');
// SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous

While I wait for a better answer I found a solution which works but it's not optimal since it involves one extra query to gather the author user_id and use it subsequently to query the records:
// Get the author ID
$author = DB::table('users')
->select(DB::raw('CONCAT_WS(" ",`firstname`,`lastname`) as `fullname`,id'))
->having('fullname', 'LIKE', '%'.$search.'%')
->first();
// $author output:
stdClass Object
(
[fullname] => John Doe
[id] => 35
)
// Query the records using the gathered ID
$records->where('user_id', $author->id)
->orWhere('title', 'LIKE', '%'.$search.'%');
Problems with this solution: Apart from the extra query, if somebody searches for John Doe or Some Title the results are correct. But if searching for John Doe Some Title, nothing is shown because the author and the title can't be found.

You need to set that also use the search parameter in your inner query:
$records->join('users', function($join) use ($search)
{
$join->on('users.id', '=', 'records.user_id')
->where('users.firstname', 'LIKE', '%'.$search.'%')
->orWhere('users.lastname', 'LIKE', '%'.$search.'%');
});

If I understand you want to return result from Records by filtering with $search and also want to show users info for this records.
You can use Eloquent.
Your model must be:
In User model:
public function records()
{
return $this->hasMany(Record::class);
}
In Record model:
public function user()
{
return $this->belongsTo(User::class);
}
And in Controller:
Record::where('title', 'LIKE', '%'.$search.'%')
->with('user')
->first();

Related

where clause in laravel for search

I am trying to select rows from table students using laravel query for searching but on searching it's returning all rows from table.
$data = DB::table('students')
->select(['name', 'username'])->where('institute', $inst)
->where('username', 'LIKE', '%'.$search.'%')
->orWhere('name', 'LIKE', '%'.$search.'%')
->orWhere('email', 'LIKE', '%'.$search.'%')
->orWhere('contact', 'LIKE', '%'.$search.'%')
->orderBy('id', 'DESC')
->paginate(10);
This is the thing, at least for what I can see, you have two kind of filters:
Students that are in a given institute
Students that have a similar username, name, email or contact than the given search term
If so, the problem in your query are the orWhere() clauses. Let's simplify your query to illustrate the issue:
$data = DB::table('students')
->where('institute', $inst)
->orWhere('name', 'LIKE', '%'.$search.'%')
->get();
In the above code, the statement will get all the students that have the institute equals to $inst OR have a name similar to %search%. So, the results could include students that are not in the given institute. You see the issue now?
In order to first filter by institute AND get records that have a similar similar username, name, email or contact, you could wrap the second conditions in a closure. Try this:
$data = DB::table('students')
->select(['name', 'username'])
->where('institute', $inst)
->where(function ($query) use ($search) { // <<<
$query->where('username', 'LIKE', '%'.$search.'%')
->orWhere('name', 'LIKE', '%'.$search.'%')
->orWhere('email', 'LIKE', '%'.$search.'%')
->orWhere('contact', 'LIKE', '%'.$search.'%');
})
->orderBy('id', 'DESC')
->paginate(10);

Fetch data from same field name in two different tables and detect which filed name we mean

I have assigned search method for my application and i have made relationship between two tables "users " table and "posts" table both of them have same field name "created_at" and when i want to fetch data that when this post has been created it will bring the date in users table created_at field not in posts table created_at field.
All i want is how to tell the system make difference between which table field name i mean .
This date comes from created_at field in users table
I wand to come date in this created_at field in posts table
ListingController.php
public function search(Request $request){
$posts = Post::with(['comments','category','creator'])
->join('users', 'posts.created_by', '=', 'users.id')
->where('slug', 'LIKE', '%'.$request->search. '%')
->orWhere('users.name', 'LIKE', '%'.$request->search. '%')
->where('status',1)->orderBy('posts.id','DESC')->paginate(5);
return view('front.listing',compact('posts'));
}
listing.blade.php
<div class="article_date">
by: {{ $post->creator->name }} , {{$post->created_at->diffForHumans()}}
</div>
You are calling your relationship improperly. You should not use a join there. Use constrained eager loading instead
There will be no conflict in the created_at date since there will be no join.
While still keeping your search query inside the closure of the relationship.
$posts = Post::with(['comments', 'category'])
->with(['creator' => function ($query) use ($request) {
$query->where('name', 'LIKE', '%' . $request->search . '%');
}])
->where('slug', 'LIKE', '%' . $request->search . '%')
->where('status', 1)
->orderBy('id', 'DESC')
->paginate(5);

How to search two tables for the given input in laravel

In my application, there are article and news tables. I know I can search for matching title in news table or article,
just by doing something like:
$query = $request['search'];
$searchResult= DB::table('article')->where('title', 'LIKE', '%$query%')
->orderBy('created_at', 'desc')->paginate(10);
or
$searchResult= DB::table('news')->where('title', 'LIKE', '%$query%')
->orderBy('created_at', 'desc')->paginate(10);
but what I want to do is to search both of them and return some information about them alongside what the reuslt type is, in terms of news and article. And than orther them by created_at as if they were in the same table.
Laravel 5.4
You can do that if getting 10 news and 10 articles per page is what you want. But in this case, you'll need to manually create paginator.
Load the data:
$articles = DB::table('article')
->where('title', 'like', '%$query%')
->latest()
->skip(0)
->take(10)
->get();
$news = DB::table('news')
->where('title', 'like', '%$query%')
->latest()
->skip(0)
->take(10)
->get();
Then merge the results:
$merged = $articles->merge($news);
Then order by date if you need to:
$merged = $merge->sortByDesc('created_at');

Search Data using Models in Laravel 5.4.36

I have created a search filter. Basically I'm getting records from single table so it works fine. But when i try to get data from another table, it is not correct. This is my drivers_table (driver_id is PK)
I'm using this query..
$drivers = Drivers::where('city', 'like', "$keywords[0]%")
->Where('first_name', 'like', "$keywords[1]%")
->get();
I have two dropdowns, Lets suppose I have 50 drivers, When i select City "DOHA" from first dropdown, Using ajax it gets me records of 20 drivers out of 50, and then i select first_name "ASFAND" from 2nd dropdown, it gets me records of people whose first name is Asfand from that list of 20 drivers. There was 5 people whose name was Asfand and also they were from DOHA City ( because i have selected both DOHA as city from first dropdown and first_name as Asfand from second drop down.
Everything works perfect. But now my question is I have a 3rd dropdown from which i will select Bank name, but bank name is not in the Drivers table, There is another table.
Banks (id, driver_id, bank_name)..
How can i get records now?
$drivers = DB::table('drivers')
->join('bank','bank.driver_id','=','drivers.driver_id')
->where('city', 'like', "$keywords[0]%")
->Where('first_name', 'like', "$keywords[1]%")
->orWhere('bank.bank_name', 'like', "$keywords[3]%")
->get();
Now if i select doha from first dropdown it doesnot show me any record.. if i select bank name from 3rd dropdown then it shows me record.. I want dropdowns to be independent..
If i don't select anything from 3rd dropdown, it should still show what i selected from first two dropdowns.
You can use joins only when it is required.
$drivers = DB::table('drivers')
->where('city', 'like', "$keywords[0]%")
->where('first_name', 'like', "$keywords[1]%")
->when(!empty($keywords[3]), function ($query) use ($keywords) {
$query->join('bank','bank.driver_id','=','drivers.driver_id')
$query->where('bank.bank_name', 'like', $keywords[3].'%');
})
Try like this,
$drivers = DB::table('drivers')
->join('bank','bank.driver_id','=','drivers.driver_id')
->where(function($query) use ($keywords) {
$query->where('drivers.city', 'like', "$keywords[0]%")
->orWhere('drivers.first_name', 'like', "$keywords[1]%")
->orWhere('bank.bank_name', 'like', "$keywords[3]%");
})
->toSql();
echo "<pre>";
print_r($drivers);
die();
Check with this it prints your query, try it in sql, if it working in that with your criteria then its perfect.
Try this -
$query = Drivers::query();
$query->leftjoin('bank','bank.driver_id','=','drivers.driver_id');
$query->where(function ($query) use($keywords){
$query->where('city', 'LIKE', "$keywords[0]%")
->orwhere('first_name', 'LIKE', "$keywords[1]%")
->orwhere('bank.bank_name', 'LIKE', "%$keywords[3]%");
});
$query->get();

Laravel 4 - get json list one table with relations

I have a table customers and a table orders.
And I want to make an ajax call to get a list of all customers with name x and their orders.
I got the ajax function and my function to retrieve the customer looks like this:
$customers = Customer::where('first_name', 'LIKE', '%'.$name.'%')
->orWhere('last_name', 'LIKE', '%'.$name.'%')
->where('user_id', Auth::user()->id)
->get()
->toJson();
return $customers;
With this I can only get all customers, can I modify this to get also their orders?
I think I could do it with join or is there any magic function?
Thanks
You can use relationship: follow the link and create one to many relationship and use the relationship in your query.
http://laravel.com/docs/eloquent#relationships
$customers = Customer::with('orders')
->where('first_name', 'LIKE', '%'.$name.'%')
->orWhere('last_name', 'LIKE', '%'.$name.'%')
->where('user_id', Auth::user()->id)
->get();
return $customers->toJson();

Categories