I want to seed the related tables in Laravel. I had a problem in access to the out-of-scope variable inside the anonymous function which I had defined for whereHas methods to put "where" conditions on my has queries.
$id = $user->id; // out-of-scope variable
$posts = Post::whereHas('comments', function ($query) {
$query->where('user_id', $id);
})->get();
Technically I don't have access to $id inside the anonymous function.
This isn't a Laravel question, but a PHP one. Just add use ($variable) after the parameter list:
$posts = Post::whereHas('comments', function ($query) use ($id) {
$query->where('user_id', $id);
})->get();
Related
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.
Attached is a screenshot of the error I am facing. I have the log show the value of the $team variable. What am I doing wrong?
You don't have access to parents variables from a closure, you need to explicitly send variables to the closure with use keyword
function($query) use ($team)
Use forget to use $team variable inside your closure. It must be function($query) use ($team)
$data = User::whereHas('roles' => function($query) use ($team) {
$query->where('role_code', '=', $team)
})->get();
Consider this code:
$fn = FormNilai::whereHas('mataPelajaranLokalGuru',function($mlg) {
$mlg->where('guru_id','=',$this->uid);
})->get();
How is $mlg always treated as FormNilai instance? how is the scenario? I read a lot about dependency injection but still don't get the point.
Dependency Injection is a different part. As per your code example, You need to the tell the anonymous function to use that variable like...
$uid = $this->uid;
$fn = FormNilai::whereHas('mataPelajaranLokalGuru',function($mlg) use($uid)
{
$mlg->where('guru_id','=',$uid);
})->get();
As that variable uid is outside the scope of the anonymous function it needs to be passed in using the use keyword as shown in the above code.
You can get more idea on use with example here
The parameter $mlg isn't treated as FormNilai instance, it's just treated as an instance of Illuminate\Database\Eloquent\Builder.
You can see that how it works in the source codes.
Illuminate/Database/Eloquent/Builder.php#L934
Example:
Define an anonymous function accepts an regular argument:
$example = function ($arg) {
var_dump($arg);
};
$example("hello");
You can change the argument name to any string, just like $myArgument.
And the the output would not been changed whatever the argument name is.
Laterally i've realize that laravel support php anonymous style so we can implement such a javascript function usage but surely it hard for me to do for first time
For simple usage, they display an example like this
$users = User::with(array('posts' => function($query)
{
$query->where('title', 'like', '%first%');
}))->get();
What if the user wanted to make the third parameter is filled with variable. When i check it out with replacing those '%first%' word with any global variable, it ruins the structure, and it happend to me.
$title = 'heirlom of marineford';
$users = User::with(array('posts' => function($query)
{
$query->where('title', 'like', $title);
}))->get();
After searching to PHP documentation, i found that the technique to passing parameter to that anonymous function by extending function block with use() so the function would assume to use all variable that defined by the use() section
$title = 'heirlom of marineford';
$users = User::with(array('posts' => function($query) use($title)
{
$query->where('title', 'like', $title);
}))->get();
I hope that could help you
im trying to join two tables post and comment using ORM relations,
$posts = Post::with('comments')->get();
how can i use condition on comments when using with to join tables?
i can use whereHas like
$posts = Post::whereHas('comments', function ($query) {
if(isset($_GET['title']))
$query->where('title', $_GET['title']);
})->get();
but when i use whereHas i wouldn't get the post without any comment in the result
basically i want to use left join with condition on the right table
You can pass a closure to with() method like this:
$posts = Post::with(['comments' => function($q) {
$q->where('column', '=', 'value'); // Put conditions here
}])->get();
Hope this helps!
You need use Closures:
$title = $_GET['title'];
$posts = Post::whereHas('comments', function ($query) use ($title) {
if(!empty($title)) {
$query->where('title', $_GET['title']);
}
})->get();
Reference:
In PHP 5.3.0, what is the function "use" identifier?
How can use variable in laravel query builder. Here is my code.
$role = 1;
$user = DB::table('users')
->join('assigned_roles', function($join)
{
$join->on('users.id', '=', 'assigned_roles.user_id')
->where('assigned_roles.role_id', '=', $role );
})
->get();
But it return Undefined variable: role.
How can I solve this problem. Help me plz.
You need to import variables from the local scope to the anonymous function's scope:
function ($join) use ($role) {}
See the example in the docs.