Laravel Query Relationship Constraints - Inject Variable - laravel

this should be an easy question. I am trying to query my Post model to find all posts that have a certain topic. Below is the controller method.
// Get collection of posts with this topic
// Get specific topic for this page
$postTopic = Topic::where('topic_name', $topic)->first();
$posts = Post::whereHas('topic', function (Builder $query) {
$query->where('topic_id', $postTopic->id);
})->get()->sortByDesc('created_at');
I am struggling with how to define the $postTopic variable. Thank you!

Your initial approach is close, but the tricky thing about anonymous functions is "scope", where variables, unless explicitly passed into the scope, are not available. For example:
$postTopic = Topic::where('topic_name', $topic)->first();
$posts = Post::whereHas('topic', function (Builder $query) {
$query->where('topic_id', $postTopic->id);
})->get()->sortByDesc('created_at');
While this code looks correct, since you're not passing $postTopic into function (Builder $query), you'll receive the error:
Undefined variable `$postTopic` ...
To resolve this, you need to use a use() clause:
$postTopic = Topic::where('topic_name', $topic)->first();
$posts = Post::whereHas('topic', function (Builder $query) use ($postTopic) {
$query->where('topic_id', $postTopic->id);
})->get()->sortByDesc('created_at');
Any number of variables can be passed and referenced in scope using use(), and you should no longer get the undefined variable error.

Related

How To Pass Parameters In String Array Of Functions In With() Laravel

I Try To Pass Parameter To With() Function For Model:
Model::with(['functionA($parameters)', 'functionB'])
I think you are looking for this type.
Model::with(['functionA' => function($query) use ($parameters) {
$query->where('some_column', $parameters);
}, 'functionB'])->get();
Unfortunately, you can't use 'with' for normal function, it's used for eloquent's relationships.
for your case you can proceed like this:
$model = new Model(); // or $model = Model::where(anyConditionYouWant)->first();
$model->functionA($parameters);
you can use your functions any time you want without declare them in 'with' sentence

Laravel eloquent call realtionship based on a boolean parameter

I'm trying to make a method to retrieve model with a relationship I'd like to be able to fetch the relation based on a boolean parameter
for example, I can do it using the if condition like the following
if($load == true){
$users = User::with('login')->all()->paginate();
}else{
$users = User::all()->paginate();
}
I'm wondering if there's a way to do it without the if condition on the fly
You can use the when() method on the query builder. Note that you don't need to use the all() method when you want to use a paginator.
User::query()
->when($load, fn($query) => $query->with('login'))
->paginate();
you can use when method:
$users = User::when($load, function ($query) {
return $query->with('login');
})->paginate(10);
The when method only executes the given closure when the first argument is true. If the first argument is false, the closure will not be executed

Why do I get an Undefined Variable: request in laravel

I got an error with my query, it seems that my Request $request variable can't be used inside the function($quer){$query->} below is my sample code.
Table1::addSelect(['PaymentStatus' => Table2::selectRaw('COUNT(*)')
->whereColumn('AccountNumber','Table1.AccountNumber')
->whereColumn('ServicePeriodEnd','Table1.ServicePeriodEnd')
])->whereNotExists(function($query){
$query->select(DB::raw('*'))
->from('Table2')
->whereRaw('Table1.AccountNumber = Table2.AccountNumber')
->whereRaw('Table1.ServicePeriodEnd = Table2.ServicePeriodEnd')
->where('AccountNumber', $request->AccountNum); // this part gives an Undefined Variable: request
})->where('AccountNumber', $request->AccountNum)
->orderBy('ServicePeriodEnd','desc')
->get();
The $request variable can not be read from the function due to it's not been declared to be used in the function. Replace this line:
])->whereNotExists(function($query){
With this line
])->whereNotExists(function($query) use ($request) {
This is relatively new syntax btw. Example can be found at https://www.php.net/manual/en/functions.anonymous.php
Use request use ($request) in the callback function query
->whereNotExists(function($query) use ($request) {
Table1::addSelect(['PaymentStatus' => Table2::selectRaw('COUNT(*)')
->whereColumn('AccountNumber','Table1.AccountNumber')
->whereColumn('ServicePeriodEnd','Table1.ServicePeriodEnd')
])->whereNotExists(function($query) use ($request) {
$query->select(DB::raw('*'))
->from('Table2')
->whereRaw('Table1.AccountNumber = Table2.AccountNumber')
->whereRaw('Table1.ServicePeriodEnd = Table2.ServicePeriodEnd')
->where('AccountNumber', $request->AccountNum); // this part gives an Undefined Variable: request
})->where('AccountNumber', $request->AccountNum)
->orderBy('ServicePeriodEnd','desc')
->get();

How could I get only specified columns instead of the full object? Laravel Eloquent

this is my first time asking something here and I hope I do it alright.
Im new to Laravel and I just know the basics of Eloquent, what I am trying to do is a game recommendator, so, in order to do so, the user sets a genre and I want to return all the games with this genre.
I am using whereHas as I am using a many to many relationship, this is my code:
public function searchByPreferences(){
$genre_id = request('genre');
$games = Game::whereHas('genres', function (Builder $query) use($genre_id) {
$query->where('genre_id',$genre_id);
})->get();
dd($games);
}
So, this returns the games with all their data, and what I want is to only get an array of their IDs so I can make the petition of the game by id later. Thank you in andvance!
You should use pluck() function to get list of ids as below :
public function searchByPreferences(){
$genre_id = request('genre');
$games = Game::whereHas('genres', function (Builder $query) use($genre_id) {
$query->where('genre_id',$genre_id);
})->pluck('id')->all();
dd($games);
}
I just found the solution and it's pretty easy.
You can specify the column giving the get() a parameter like this:
public function searchByPreferences(){
$genre_id = request('genre');
$games = Game::whereHas('genres', function (Builder $query) use($genre_id) {
$query->where('genre_id',$genre_id);
})->get('id');
dd($games);
}

Laravel Query Builder Advance Where

Laravel Advance Query Builder not seeing parent method variable
public function read($status=null,$skip=0,$take=10,$orderby=array())
{
$table = DB::table('users')
->skip($skip)
->take($take)
->where(function($query) {
if($status)
$query->where('status','!=',$status);
});
}
This returns an error which $status variable undefined inside the advance where query. Is there anything to extend?
If you want to use variables in your closure, you must include them.
Change
->where(function($query) {
to
->where(function($query) use ($status) {

Resources