Passing conditional param to Eager Loading in larave ends with error - php

my code is as followed:
return User::whereHas('roles', function ($role, $query) {
return $role;
$query->whereId($role);
})->get();
what I am trying is to pass role id here to query builder.
it ends up with following error:
Symfony\Component\Debug\Exception\FatalThrowableError
Too few arguments to function App\Http\Controllers\UserController::App\Http\Controllers\{closure}(), 1 passed in /Users/x/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php on line 962 and exactly 2 expected

I think this is what you want:
A closure is a function that is evaluated in its own environment, which has one or more bound variables that can be accessed when the function is called.
The use() keyword let's you import variables from outside the function environment, inside the function.
return User::whereHas('roles', function ($query) use ($role) {
return $query->whereId($role);
})->get();

Related

passed variable in nested where query in laravel 9

I am trying to use variable to nested where() query in laravel 9 but i get an error that variable Undefined
my code:
public function edit($id)
{
$category = Category::findOrFail($id);
$parents = Category::
where('status' , 'active')
->where('id' , '<>' , $id)
->where(function($query){
return $query
->whereNull('parent_id')
->orWhere('parent_id', '<>', $id);
})->get();
}
the error:
Undefined variable $id
$parents = Category::
where('status' , 'active')
->where('id' , '<>' , $id)
->where(function($query) use ($id) { <-- problem is here
return $query
->whereNull('parent_id')
->orWhere('parent_id', '<>', $id);
})->get();
in this section of your code: ->where(function($query){ you need use keyword to pass value inside this inner function as below:
->where(function($query) use ($id) { .. };
the detail for this action is:
The closure is a function assigned to a variable, so you can pass it around
A closure is a separate namespace, normally, you can not access variables defined outside of this namespace. There comes the use keyword:
use allows you to access (use) the succeeding variables inside the closure.
use is early binding. That means the variable values are COPIED upon DEFINING the closure. So modifying $id inside the closure has no external effect, unless it is a pointer like an object is.
You can pass in variables as pointers like in case of &$id. This way, modifying the value of $total DOES HAVE an external effect, the original variable's value changes.
Variables defined inside the closure are not accessible from outside the closure either.
Closures and functions have the same speed. Yes, you can use them all over your scripts.
for more info read this.

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'role_not' ERROR

I am trying to display users other than super_admin so I used whereRoleNot Function in my controller to hide super_admin .
My User Model:
public function scopeWhereRole($query, $role_name){
return $query->whereHas('roles', function($q) use($role_name){
return $q->whereIn('name', (array)'$role_name');
});
} //end of scopeWhereRole
public function scopeWhereRoleNotIn($query, $role_name){
return $query->whereHas('roles', function($q) use($role_name){
return $q->whereNotIn('name', (array)'$role_name');
});
} //scopeWhereRoleNotIn end
And User controller index method:
public function index()
{
//
$users= User::whereRoleNot('super_admin')->paginate(3);
return view('dashboard.users.index', compact('users'));
} //end of index
The core issue is that you had a typo when using your scope, but due to the way you named your scope, it was still a valid where{column} clause.
Laravel has dynamic functions, like where{column}($search) that constructs a simple where clause for the {column} value and $search value provided. Take your example:
$users = User::whereRoleNot('super-admin');
whereRoleNot tries to create a where clause for the column, in your case, role_not (dynamically constructed from the string RoleNot), and your database table does not have this column.
Simply use a normal where clause:
$users = User::where('role', '!=', 'super_admin')->paginate(3);
Edit: If you want to use a scope, I'd suggest you change the name a bit:
public function scopeRoleIn($query, $role_name){
return $query->whereHas('roles', function($q) use($role_name){
return $q->whereIn('name', (array)$role_name); // Don't use `'` here
});
}
public function scopeRoleNotIn($query, $role_name){
return $query->whereHas('roles', function($q) use($role_name){
return $q->whereNotIn('name', (array)$role_name); // Don't use `'` here
});
}
Then, use your scope as follows:
// $users = User::roleIn('super-admin')->paginate(3); // Etc...
$users = User::roleNotIn('super-admin')->paginate(3);
You may use scopeWhere..., but that naming potentially conflicts with Laravel's dynamic where{column} clauses, so you should avoid it.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'role_not'
ERROR
It's because Laravel is expecting that you have a column 'role_not' in your User table considering that your local scope was named scopeWhereRoleNotIn, remove the prefix scope and it's final name will become WhereRoleNotIn yet you are calling the scope name as WhereRoleNot. Now you know why column 'role_not' is the error because Laravel is expecting that you were not already using local scope.
Now, to call this local scope, your query should look like this
public function index()
{
$users= User::whereRoleNotIn('super_admin')->paginate(3);
return view('dashboard.users.index', compact('users'));
}
Even if 'where' is a reserved keyword it will still works
It's jut a matter of you missed to call the exact name of your local scope that is why Laravel is treating it as an where clause for your query builder.
please read docs local scope

Error in Laravel 5.2 Eloquent - cannot be converted to String

I am very new to Laravel and am going through the tutorials and am stuck on something.
I have a complex query that I need to reuse with one parameter change in the where clause. I added this as a query scope in my Model and then call it from my corresponding Controller. When I try to return the data though I am getting this error:
Object of class Illuminate\Database\Eloquent\Builder could not be converted to string
Here is the query scope:
public function scopeCrosstab($wellID)
{
return static::select('sampleDate', \DB::raw("
max(if(chemID=1, pfcLevel, ' ')) as 'PFOA', max(if(chemID=1, noteAbr, ' ')) as 'PFOANote'
"))
->leftJoin('SampleNote', 'WellSample.noteID', '=', 'SampleNote.noteID')
->where('wellID', '=', $wellID)
->groupBy('sampleDate');
}
Here is the Controller code:
public function smith()
{
$wellSamples = WellSample::crosstab(2);
return $wellSamples->get();
//return view('pages.wellsample', compact('wellSamples'));
}
I have tried many different permutations of the code with quotes, with double quotes etc. If I hard code the value in the query scope it works, but I need to be able to make it dynamic.
Scope methods take at least one parameter, the first of which must be $query. You then build off of the query variable that is passed to your scope method. Like this:
public function scopeCrosstab($query, $wellID)
{
return $query->select('sampleDate', \DB::raw("
max(if(chemID=1, pfcLevel, ' ')) as 'PFOA', max(if(chemID=1, noteAbr, ' ')) as 'PFOANote'
"))
->leftJoin('SampleNote', 'WellSample.noteID', '=', 'SampleNote.noteID')
->where('wellID', '=', $wellID)
->groupBy('sampleDate');
}

Undefined Variable Multiple Query Scopes Laravel

This work perfect:
public function scopeHBO($query)
{
return $query ->where('network', '=', "hbo");
}
Call in Controller: It Works!
$events = Schedule::HBO()->orderBy('searchdate')->get();
When I add another Query Scope like so:
public function scopeHBO($query)
{
return $query
->where('network', '=', "hbo")
->where('searchdate', '>=', 'NOW()');
}
OR:
public function scopeDate($query)
{
return $query->where('searchdate', '>= ', 'NOW()');
}
Then call in the controller:
$events = Schedule::HBO()->Date()->orderBy('searchdate')->get();
I get an error: Undefined variable: event. I tried with with Raw MySql in the same model and it works. Whenever i add a query scope, does not matter what it is.. i get that same error Undefined variable: event.
NOW() is a function, so you need to use a raw query:
where('searchdate', '>=', DB::raw('NOW()'))
Then you can use the scopes. (Do note that I think scopeDate must be called as date(), not Date() - not 100 % sure on that though.)
This sounds less like a generic problem with Laravel, and more like a problem with you specific application.
My guess (which is a wild guess), is that adding that second where clause in your scope method
return $query
->where('network', '=', "hbo")
->where('searchdate', '>=', 'NOW()');
ended up creating a SQL query that returned 0 rows. Then, somewhere in your other code you're doing something like
foreach($events as $event)
{
//...
}
//referencing final $event outside of loop
if($event) { ... }
As I said, this is a wild guess, but the problem doesn't seem to be your query code, the problem seems to be the rest of your code that relies on the query returning a certain number of, or certain specific, rows/objects.

Query builder: passing argument to anonymous function

I got a problem in passing variable to query builder closure, here is my code:
function get_usersbyname($name){
dd($name);
$resultset = DB::table('users')->where(function($query){
$query->where('username', 'LIKE', $name);
});
....
}
if I run it, it returns an error "undefined name variable", but I already passed $name variable and checked its existence.
Also I cann't find any resouce explains how to pass variable to query builder anonymous function.
Could you help me with this problem?
You need to the tell the anonymous function to use that variable like...
Because that variable is outside the scope of the annonymous function it needs to be passed in using the use keyword as shown in the example below.
function get_usersbyname($name){
dd($name);
$resultset = DB::table('users')->where(function($query) use ($name) {
$query->where('username', 'LIKE', $name);
});
....
}

Categories