How to get the Model id in custom Request class - laravel

I have made a custom Request for validation and i don't know how to get the Model id on update.
I'm using route model binding and form model binding but this models id is not shown when i hit this Request for validation and i make
dd($this);
all fields are shown except the model id.

use route() method on request to retrive the route parameter
dd($this->route('param_name'));
if your route is like /users/{user_id} then $this->route('user_id'); will give you the parameter user_id value in request if you have bind custom parameter name in route model binding use that parametername in route() method
for ex. Route::model('user', App\User::class); then use $this->route('user'); to retrive the user model directly.
PS. $this means you should be in your Request class where you define rules() and messages() method.

For example your route is /insurance_contract_items/insurance_contract_item/
You can use $this->insurance_contract_item to get your model instance.
As you read on previous answer you can use also $this->route('insurance_contract_item').

Related

Laravel edit controller not having data

I am trying to make crud in laravel. While doing dd of data variable in edit function attributes array is getting null
Route
Route::resource('/gameSettings', GameSettingController::class);
Controller
public function edit(GameSetting $game_setting)
{
dd($game_settings);
return view('admin.game_setting.edit', compact('game_setting'));
}
Model
class GameSetting extends Model
{
use HasFactory;
protected $fillable = [
'coin_value',
'minimum_withdraw_amount'
];
}
Link
https://localhost:8000/admin/gameSettings/1/edit
dd($game_settings); giving null array attribute
I dont have enough rep to comment so I give an answer...
#lagbox is correct. Your route parameter should match exactly as the variable typehinted in the controller for your case change $game_setting to $gameSetting
if you want to use $game_setting change your route to
Route::resource('/gameSettings', GameSettingController::class, ['parameters' => ['gameSetting' => 'game_setting']]);
The variable that you have typehinted on the Controller method must match exactly the name of the route parameter you have defined. In this case the parameter would be named gameSetting most likely. If you don't match these then you have Dependency Injection happening which would give you a new, non-existing, instance of the model. If you match the name then you will get Route Model Binding and it will look up the model and give you that particular entity.
If you want to see what the route parameter is named, since you are using resource routing, you can run php artisan route:list from the command line and it will show you those 7 routes and how they are defined.

Laravel route difference between {id} vs {tag}

I am new in Laravel pardon me if question is silly. I have seen a doc where they used
For get request
Route::get("tags/{id}","TagsController#show");
For put request
Route::put("tags/{tag}","TagsController#update");
What is the difference and benefit between this ? I understood 1st one, confusion on put route.
There’s no real difference as it’s just a parameter name, but you’d need some way to differential parameters if you had more than one in a route, i.e. a nested resource controller:
Route::get('articles/{article}/comments/{comment}', 'ArticleCommentController#show');
Obviously you couldn’t use just {id} for both the article and comment parameters. For this reason, it’s best to use the “slug” version of a model for a parameter name, even if there’s just one in your route:
Route::get('articles/{article}', 'ArticleController#show');
You can also use route model binding. If you add a type-hint to your controller action for the parameter name, Laravel will attempt to look up an instance of the given class with the primary key in the URL.
Given the route in the second code example, if you had a controller that looked like this…
class ArticleController extends Controller
{
public function show(Article $article)
{
//
}
}
…and you requested /articles/123, then Laravel would attempt to look for an Article instance with the primary key of 123.
Route model binding is great as it removes a lot of find / findOrFail method calls in your controller. In most instances, you can reduce your controller actions to be one-liners:
class ArticleController extends Controller
{
public function show(Article $article)
{
return view('article.show', compact('article'));
}
}
Generally there's no practical difference unless you define a custom binding for a route parameter. Typically these bindings are defined in RouteServiceProvider as shown in the example in the docs
public function boot()
{
parent::boot();
Route::model('tag', App\Tag::class);
}
When you bind tag this way then your controller action can use the variable via model resultion:
public function update(Tag $tag) {
// $tag is resolved based on the identifier passed in the url
}
Usually models are automatically bound so doing it manually doesn't really need to be done however you can customise resolution logic if you do it manually
Normal way
Route::get("tags/{id}","TagsController#show");
function($id)
{
$tag = Tag::find($id);
dd($tag); // tag
}
With route model bindings
Route::put("tags/{tag}","TagsController#update");
function(Tag $tag) // Tag model binding
{
dd($tag); // tags
}
ref link https://laravel.com/docs/5.8/routing#implicit-binding
It's just a convention. You can call it all you want. Usually, and {id} refers to the id in your table. A tag, or similarly, a slug, is a string value. A tag could be 'entertainment' for video categories, while 'my-trip-to-spain' is a slug for the description of a video.
You have to chose the words what you are comfortable with. The value will be used to find in your database what record is needed to show the correct request in the view. Likewise you can use video/view/{id}/{slug} or any combination thereof.
Just make sure your URLs don't get too long. Because search engines won't show your website nicely in search results if you do. Find the balance between the unambiguous (for your database) and logic (for your visitors).
Check this out: Route model bindings
Use id, Laravel will get the id from route, and it will be the tag's id, it is integer.
function show($id) {
$tag = Tag::find($id);
}
Use tag, Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
In URL, your tag parameter is integer, however in your controller action $tag will be a model object:
function action(Tag $tag) {
$tag->name;
}
So you don't need to get the $tag by eloquent in your controller action. You just need to specify it is From model Tag $tag
It will do it automatically.

laravel 5.8 edit function with model instance

public function edit(EduLevel $eduLevel)
{
dd($eduLevel->name);
return view('adm.edulevel.edit',compact('eduLevel'));
}
Route::resource('edulevel','EduLevelController'); //web.php
with resource route
how to get eduLevel to view with model instance laravel. in previous i call with parme parameter id and use find() method to get data..
from this sample - https://itsolutionstuff.com/post/laravel-58-crud-create-read-update-delete-tutorial-for-beginnersexample.html
I don't understand the question but I will just guess that you have a route that accepts a parameter that you you expect it to be the model inside your function.
You need to create a route like this one:
Route::get('/edit/{eduLevel}', 'SomeController#edit');
Notice the same name for the variable, this is important otherwise you will get only the id, slug or whatever.
Make sure your path name also have the same name for route segment name.
so your route path should be like this.
Route::get('/edit/{variablename}', 'ControllerName#edit');
your controller function logic should be like this.
public function edit(EduLevel $variablename)
{
return view('adm.edulevel.edit',compact('variablename'));
}
So make sure your variable name in route and in controller function
should be same.
For more information, you can read Route Model Binding in laravel
I am having the same problem (almost).
I wanted to call a controller method in the view. So I should pass the model from controller to view.
How to pass model from controller to view?
I found this [Laravel 5 call a model function in a blade view but using ->withModel($model); to pass the model from controller to view and {{$model->someFunction()}} to call the method in the view is not working.
Any advice please?

Want to show name instead of id in the URL field in Laravel

I don't want to show /route_name/{id} in the URL field of my Laravel project. Instead of that I want to show /route_name/{name} but pass the id in the back-end to the controller.
Suppose I have a route named departments and pass an id 3 named knee_pain as a parameter. And it is like /departments/3
But I want to to show /departments/knee_pain in my url and as well as want to pass the id 3 in my controller without showing the id in the url.
How to do that ?
In your model you can use the getRouteKeyName method to bind to another attribute than the default id in your routes :
public function getRouteKeyName()
{
return 'slug'; // Default is 'id'.
}
Rather than using the name attribute, that you could use elsewhere in your application for displaying the name of the entry, I recommend using an attribute made url friendly. You could use Str::slug() for that.
public function setNameAttribute($value) {
$this->name = $value;
$this->slug = \Str::slug($value);
}
It will 'slugify' your string, for example : \Str::slug('Knee pain') => 'knee-pain'.
Note : in Laravel 5.5, use the str_slug() helper.
You should also make sure this string is unique in your database.
First you have to garantee that the name is unique, if don't you will have more than one Id in your controller. For that i recommend you to use Purifier to remove spaces and make it URL friendly:
Purifier
Second, probably the best way to have clean controllers is creating a middleware that understand what kind of name is (what table should middleware look for). You can validate that by route name and send the correct id to controller.
Middleware docs

Laravel - route model binding with request headers

I am wondering is it possible to do something similar to route model binding, but with request headers. I have a query that I check on my api endpoints, that looks like this:
User::where('telephone', $request->header('x-user'))->firstOrFail();
Is it possible to somehow avoid repeating this query in every method in controllers, but to apply it to routes, so that I could just get the user object just like in a route model binding with type hinting in a function, for every route that in an api routes folder:
public function userTransactions(User $user)
{
//
}
Create a middleware and assign it to the desired routes.
Option 1
In your middleware do:
$user = User::where('telephone', $request->header('x-user'))->firstOrFail();
request()->merge(['user_model' => $user]);
You can then request()->get('user_model') anywhere in your controller
Option 2
Start by creating a global scope class that conforms to your query. Here you'd get the header value and use that in the scope.
https://laravel.com/docs/5.5/eloquent#global-scopes
Next in the middleware, add the scope to the model using addGlobalScope
User::addGlobalScope(new HeaderScope())
Now all queries for User will have a where clause with your header value.
You can subsequently remove the scope or ignore global scopes if needed.

Resources