Having trouble passing variable through Controller, into Eloquent Query - laravel

I'm trying to make an ajax request along with a variable in the url of the request.
The request is supposed to retrieve results for Recipes, which has a pivot table for Flavors.
The query should retrieve all Recipes with specified flavor. I am not able to pass the $flavorID variable into the query though. Getting an undefined error.
Route::get('/api/recipes/flavor/{flavorID}', function($flavorID){
return App\Recipe::whereHas('flavors', function ($query) {
$query->where('flavor_id', $flavorID);
})->paginate(20);
});

$flavorID does not exist in the scope of the function being passed to whereHas. Use the use keyword to include the variable in the scope of the function.
Route::get('/api/recipes/flavor/{flavorID}', function($flavorID){
return App\Recipe::whereHas('flavors', function ($query) use ($flavorID) {
$query->where('flavor_id', $flavorID);
})->paginate(20);
});
See https://www.php.net/manual/en/functions.anonymous.php

When you have a sub-function, you need to pass variables into scope:
// http://example.com/api/recipies/flavor/vanilla
Route::get('/api/recipes/flavor/{flavorID}', function($flavorID){
return App\Recipe::whereHas('flavors', function ($query) use($flavorID) {
$query->where('flavor_id', $flavorID);
})->paginate(20);;
});
Adding use($flavorId) allows $flavorID to be used within function($query). If you omit it, then you get an undefined error as you're experiencing.

Related

getting query parameters from URL in laravel 7.1

Just as a learning exercise, I'm creating a REST API in Laravel 7.1. I'm having trouble figuring out how to parse the query string parameters in route methods. I've read over the documentation here, and it shows how to add parameters into the path:
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
However I don't see where you can get query parameters from the request URL. In my toy code, I want to add a route to add a new car to inventory:
Route::post('/inventory/add/{make}/{model}/{year}', function ($make, $model, $year) {
return \App\Inventory::create($model, $color, $trim, $accessories);
});
I want to specify parameters such as color, trim, and accessories through the query string, like so:
http://example.com/inventory/add/ford/focus/2020?color=red&trim=sport&accessories=chrome-wheels
How do I get the query parameters out of the Route::post method?
Edit I suppose this architecture may not be the optimal way of adding this extra information, but since I am trying to learn laravel, I am using it as an example. I am interested in learning how to get the query parameters moreso than how to improve the architecture of this learning example.
In Route::post you don't need set the parameters in route. Just use:
Route::post("your-route", "YourControllerController#doSomeThing");
So, in app/Http/Controllers/YourControllerController.php file:
class YourControllerController extends Controller {
public function doSomeThing(Request $request)
{
echo $request->input('param1');
echo $request->input('param2');
echo $request->input('param3');
}
You just need to inject the request instance into your handler (whatever a closure or controller method) and then ask for your parameters.
$color = $request->query('color', 'default-color');
//And so on...
https://laravel.com/docs/7.x/requests#retrieving-input

How to use custom keys in laravel routes without scoping?

When using custom keys Laravel forces us with scoping, for example, I have a route to getting a country and a post
api/countries/{country:slug}/posts/{post:slug}
but I can't get that using slug key because it doesn't have a relation with country, and in this case, I want to handle scope myself and I don't need implicitly scope binding, but I get an error (Call to undefined method App\Country::posts() ).
so because of that I cant using this Laravel feature. is there a way to turn the implicitly scope binding off?
If the posts are not related to the countries, it may not make sense to nest them in the URI?
But, nonetheless, to answer your question, you need to do one of two things:
Instead of setting {country:slug}, just use {country} and then override getKeyRouteName() function on your Country and Post models.
Alternatively, especially if you want to use the ID elsewhere, use explicit model binding.
To use a slug without custom keys in the routes file
class Post
{
[...]
public function getRouteKeyName()
{
return 'slug';
}
}
To use explicit route model binding
Add the following to the boot() method of your RouteServiceProvider:
public function boot()
{
parent::boot();
Route::bind('post', function ($value) {
return App\Post::where('slug', $value)->firstOrFail();
});
}

laravel 5.5 returning null for query params

I have a url: /feedback?page=1 and in my route (not a controller, just a route method) I have the following method inside a route group (the $userId var is from the group prefix):
Route::prefix('accounts/{userId}/feedback')->group(function() {
Route::get('/', function(Request $request, $userId) {
die(var_Dump($request->query('page')));
});
...
}
This returns null. I have tried input('page') to no success either. What am I blatently doing wrong?
I've also tried dd($_GET) which strangely returns nothing.
With dd($_GET) not working it led me to investigate whether the server was passing the query string... I looked into the nginx config and I wasn't passing $query_string to the index file. So, that's that.
Have to include use Illuminate\Http\Request; in the beginning.
You can use dd($request->query('page')) instead of die(var_dump())

Is there any way to pass variable in rememberForever callback?

I have following code,
\Cache::rememberForever('Roles', function() {
return RoleModel
::where('ParentRoleID' >= $CurrenctUserRoleID)
->get();
});
Issue is: I am getting Error
Undefined variable: CurrenctUserRoleID
Question: Is there any way to pass variable in callback?
You may try this (Notice the use of use keyword):
$CurrenctUserRoleID = 1; // Some id
\Cache::rememberForever('Roles', function() use($CurrenctUserRoleID) {
return RoleModel
::where('ParentRoleID' >= $CurrenctUserRoleID)
->get();
});
Check the PHP manual: Inheriting variables from the parent scope.
PHP.net - anonymous functions - Example #3
You aren't passing anything with the callback as you are not the caller of that callback. You are telling PHP to use a variable from the parent scope.
function (...) use (...) { ... }

Laravel 5 - Unable to access the ID variable within the route

My current setup:
Controller:
public function showGeneralPage($id, ShowClinicFormRequest $request)
{
return View::make('clinic.general', ['clinic' => Clinic::where('id', $id)
->first()]);
}
ShowClinicFormRequest:
public function authorize()
{
$clinicId = $this->route('clinic');
return Clinic::where('id', $clinicId)
->where('user_id', Auth::id())
->exists();
}
Route:
Route::get('clinic/{id}/general', 'ClinicController#showGeneralPage
When trying to click through to the page - General, it presents a forbidden error.
To be honest, I'm not overly fussed on even having to show the ID based on the clinic, within the URL, but I can't see any other way around it? Any help would be hugely appreciated. Many thanks.
You may try this (I've found three problems tho):
$id = $this->route()->parameter('id'); // $this->route('id') works as well
Also you need to pass the id when generating the URI, for example:
{{ url("clinic/{$id}/general") }} // $id may have some value, i.e: 10
Also, you need to change the order of parameters here:
public function showGeneralPage($id, ShowClinicFormRequest $request)
Should be:
public function showGeneralPage(ShowClinicFormRequest $request, $id)
Note: When using Method Injection place your method parameters after the type hinted dependency injection parameters.
There are two problems here. First, you have to pass the id along when generating the URL. Assuming a variable $id:
url('clinic/'.$id.'/general')
Second, you are trying to retrieve the parameter clinic, however it is actually called id.
Change it to:
$clinicId = $this->route('id');

Resources