Laravel inner join saying variable undefined - php

I am doing a search to filter through users that are displayed on my screen. The display of the users is working without the search. However when I type in the search a name, and go to display it, I get an undefined variable for search.
$Search = $request->search_code; //print_r($Search);die(); // this works
// this next line was used for testing and it works as well
//$findTrainers = DB::table('users')->where('users.name', 'like', "%$Search%")->get();
// This is what we want to work, but the search variable is now undefined
$findTrainers = DB::table('users')
->join('bios', function ($findTrainers) {
$findTrainers->on('users.id', '=', 'bios.user_id')
->where('users.name', 'like', "%$Search%");
})
->get();

This is due to how closures and scoping work. Closures don't know about variables defined outside of their scope, so you must tell a closure to use that variable when you want to access it within the scope of the closure, like this:
$findTrainers = DB::table('users')
->join('bios', function ($findTrainers) use ($Search){
$findTrainers->on('users.id', '=', 'bios.user_id')
->where('users.name', 'like', "%$Search%");
})
->get();

Related

Object of class Illuminate\Database\Query\Builder could not be converted to string in Laravel

I'm trying to add orwhere using the below syntax for searching :
->where(function($query) {
$query->where(DB::raw("g.title"), 'LIKE', "%{$query}%");
$query->orWhere(DB::raw("s.step"), 'LIKE', "%{$query}%");
})
but I'm receiving the below error
Object of class Illuminate\Database\Query\Builder could not be converted to string
It is working fine if I used the normal syntax as below :
->where(DB::raw("g.title"), 'LIKE', "%{$query}%")
->orwhere(DB::raw("s.step"), 'LIKE', "%{$query}%")
But I will add another where condition, so I have to use the first syntax.
You are defining $query twice. Both in your where() Closure and as a value. Also when you use closures and what to access values from outside the scope you have to use the use() statement. This code is not included but i assume it looks something similar to this and will work like that.
// replace this with whatever $query is in your code, from outside the closure scope
$search = $request->get('query');
Model::query()
->where(function($query) use ($search) {
$query->where(DB::raw("g.title"), 'LIKE', "%{$search}%");
$query->orWhere(DB::raw("s.step"), 'LIKE', "%{$search}%");
})
->get();

How to access varible inside orWhere() in laravel query builder|Laravel

I am trying to build little complex query where everything wan OK until I tried to use a advanced where condition.
In the code below I am getting an error saying
ErrorException: Undefined variable: user in file D:...**\app\Http\Controllers\ApiAuthController.php on line 285
and the line 285 is $query->where("tbl_transactions.from_user_id", "=", $user->id) inside the orWhere()
public function loadTransactions()
{
$token = JWTAuth::getToken();
$user = JWTAuth::toUser($token);
return DB::table('tbl_transactions')
->join('tbl_users as fromu', 'fromu.id', '=', 'tbl_transactions.from_user_id')
->join('tbl_users as tou', 'tou.id', '=', 'tbl_transactions.to_user_id')
->select('tbl_transactions.id', 'tbl_transactions.from_user_id', 'tbl_transactions.to_user_id', 'tbl_transactions.amount', 'tbl_transactions.created_at', 'tbl_transactions.status', 'fromu.userid', 'tou.userid', 'tou.phone as tophone', 'fromu.phone as fromphone')
->orWhere(function ($query) {
$query->where("tbl_transactions.from_user_id", "=", $user->id)// here the problem is (undefined **$user**)
->where('tbl_transactions.to_user_id', '=', $user->id);
})
->orderBy('tbl_transactions.id', 'desc')
->take(50)
->get();
}
I am new to laravel.Anyone here could help me would be great.
You need to use the use clause to make the variable accessible in the closure scope. So, change this:
->orWhere(function ($query) {
To this:
->orWhere(function ($query) use($user) {
Im too lazy to link the other 100s of posts that are duplcates of this.
PHP manual - anonymous functions Example #3

Laravel - Query Model if values contain a certain string (taken from search input)

I am implementing a search using Laravel and Ajax. So I have a Product which belongs to a Tag and a Subcategory. On the other hand the Subcategory belongs to a Category. I want to check all of their properties (field values) and check if they contain the given string. With some searching I found out that I have to use LIKE. Here is what I tried:
$products = Product::where('name_en', 'LIKE', $search)->get();
However this will get the products if the search string matches exactly the value. I want to match if it contains it. How can I proceed with the belongsTo relationships? How can I check the propreties of Tag and Subcategory as well? How to chain everything together so I achieve the desired result? Thanks in advance.
you are doing one thing wrong, your query returns you exact matches because you given the exact string. But your query should be like this.
$products = Product::where('name_en', 'LIKE', '%'.$search.'%')->get();
Above query will gives your products which contains the searched string.
And if you want to search in relational tables then you can user laravel method join(). But there are one more method whereHas but I always avoiding this method, because it creates very complex query. which is very heavy. So you can use join() method which will add inner join with relational table.
Here is the example of join:
$products = Product::join('tags', function($builder) {
$builder->on('tags.id', '=', 'products.tag_id');
// here you can add more conditions on tags table.
})
join('sub_categories', function($builder) {
$builder->on('sub_categories.id', '=', 'products.tag_id');
// here you can add more conditions on subcategories table.
})
->where('name_en', 'LIKE', '%'.$search.'%')
->get();
This is the basic example, you can use this according to your requirement.
To add to Lakhwinder Singh’s answer, it might be worth wrapping it up in a scope that you can apply to your model:
class Product extends Model
{
public function scopeSearch($query, $keywords)
{
return $query->where('name_en', 'LIKE', '%'.$keywords.'%');
}
}
You can then use this scope like this:
$products = Product::search($keywords)->get();
Which means you don’t have to keep manually adding “LIKE” conditions throughout your application.
As an aside, Laravel’s introducing Scout, a driver-based full text search extension for Eloquent, in version 5.3.
What you want is to write an advanced query to search product based on related models too, so as previous suggestion by others, you have to write join statements.
Check my example code below, which is written to search members, the search string also will bring members if the string matches, members skills or positions, so this will surely help you.
$users = User::select('app_users.*')
->distinct()
->join('app_members', 'app_users.id', '=', 'app_members.app_users_id')
->leftJoin('app_members_jobtitles', 'app_members.id', '=', 'app_members_jobtitles.app_members_id')
->leftJoin('app_jobtitles', 'app_members_jobtitles.app_jobtitles_id', '=', 'app_jobtitles.id')
->leftJoin('app_members_tags', 'app_members.id', '=', 'app_members_tags.app_members_id')
->leftJoin('app_technologies', 'app_members_tags.app_technologies_id', '=', 'app_technologies.id')
->whereNull('app_users.activation')
->where('app_users.block','=',0)
->where(function ($query)use ($search) {
$query->orWhere('app_users.first_name', 'like', '%'.$search.'%')
->orWhere('app_users.last_name', 'like', '%'.$search.'%')
->orWhere('app_members.company', 'like', '%'.$search.'%')
->orWhere('app_members.job_title', 'like', '%'.$search.'%')
->orWhere('app_jobtitles.title', 'like', '%'.$search.'%')
->orWhere('app_technologies.title', 'like', '%'.$search.'%')
->orWhere('app_members.summary', 'like', '%'.$search.'%');
})
->get();
Note the following join in the above code, which is in your case category and sub category
->leftJoin('app_members_jobtitles', 'app_members.id', '=', 'app_members_jobtitles.app_members_id')
->leftJoin('app_jobtitles', 'app_members_jobtitles.app_jobtitles_id', '=', 'app_jobtitles.id')

Undefined variable inside laravel left join

in my case, i want to display users and orders completed by each user, orders have status
i get $status from input form
here is my code
$orders = DB::table('user_profiles')
->leftJoin('orders', function($join){
$join->on('user_profiles.id','=','orders.id_user')
->where('orders.status','=',$status);
})
->selectRaw('user_profiles.*, count(orders.id_user) as order_try_count')
->groupBy('user_profiles.id')
->orderBy('order_try_count',$order)
->paginate(15);
but i get undefined variable status, what should i do to solve this problem ?, thank you
Yoo need to pass variables into closure using use construction like so:
->leftJoin('orders', function($join) use ($status) {
instead of
->leftJoin('orders', function($join) {
Reference: anonymous functions
You have to use use() method to user variable in closure
Try
->leftJoin('orders', function($join) use($status){
$join->on('user_profiles.id','=','orders.id_user')
->where('orders.status','=',$status);
})

Laravel Advanced Wheres how to pass variable into function?

Example in doc:
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
But what if I need to use external variable like that:
->where('city_id', '=', $this->city->id)
->where(function($query)
{
$query->where('name', 'LIKE', '%'.$searchQuery.'%')
->orWhere('address', 'LIKE', '%'.$searchQuery.'%')
})
For now I created new property and accessed it through $this->, but is there any more convenient way?
You can pass the necessary variables from the parent scope into the closure with the use keyword.
For example:
DB::table('users')->where(function ($query) use ($activated) {
$query->where('activated', '=', $activated);
})->get();
More on that here.
EDIT (2019 update):
PHP 7.4 (will be released at November 28, 2019) introduces a shorter variation of the anonymous functions called arrow functions which makes this a bit less verbose.
An example using PHP 7.4 which is functionally nearly equivalent (see the 3rd bullet point below):
DB::table('users')->where(fn($query) => $query->where('activated', '=', $activated))->get();
Differences compared to the regular syntax:
fn keyword instead of function.
No need to explicitly list all variables which should be captured from the parent scope - this is now done automatically by-value. See the lack of use keyword in the latter example.
Arrow functions always return a value. This also means that it's impossible to use void return type when declaring them.
The return keyword must be omitted.
Arrow functions must have a single expression which is the return statement. Multi-line functions aren't supported at the moment. You can still chain methods though.
#kajetons' answer is fully functional.
You can also pass multiple variables by passing them like: use($var1, $var2)
DB::table('users')->where(function ($query) use ($activated,$var2) {
$query->where('activated', '=', $activated);
$query->where('var2', '>', $var2);
})->get();
If you are using Laravel eloquent you may try this as well.
$result = self::select('*')
->with('user')
->where('subscriptionPlan', function($query) use($activated){
$query->where('activated', '=', $roleId);
})
->get();
You can pass variables using this...
$status =1;
$info = JOBS::where(function($query) use ($status){
$query->where('status',$status);
})->get();
print_r($info);

Categories