Laravel 7 resource model binding, no information in the edit page - laravel

In Laravel 7 I did the following:
php artisan make:controller ClientGroupController --resource --model=ClientGroup
I modified the edit function in ClientGroupController to look as follows:
public function edit(ClientGroup $clientGroup)
{
return view('extranet.groups.create_modal_form', compact('clientGroup'));
}
I also added this route resource: Route::resource('groups', 'ClientGroupController');
A dd($clientGroup) in the view (when visiting the page http://127.0.0.1:8000/groups/2/edit) yields none of the data for the current record (a blank ClientGroup object).
Did I miss a step? Why does $clientGroup->id return null in my view (id is the primary key of the client_group table).

public function edit($id)
{
$clientGroup = ClientGroup::find($id);
return view('extranet.groups.create_modal_form', compact('clientGroup'));
}

I had a similar problem with resource routes defined like this:
Route::resource('others', OtherServiceController::class);
But my model name was OtherService
This was my edit and update function
public function edit(OtherService $otherService)
{
return view('others.master-edit', compact('otherService'));
}
public function update(OtherServiceRequest $request, OtherService $otherService)
{
$otherService->update($request->validated());
return redirect()->route('others.index')->withToastSuccess('Success Update Data');
}
But this code threw errors about a missing required parameter, because resource name and model name are not the same. So, my solution was to change the resource routes to match the model.
Route::resource('otherService', OtherServiceController::class);
Maybe you can read this question, marked answer tells about overriding

Related

Can we exclude a custom service provider when running php artisan migrate in laravel?

I have a custom service provider in which I am accessing a model in boot(). But when I run php artisan migrate, it shows the below error:
[Illuminate\Database\QueryException] SQLSTATE[42S02]: Base table or view not found: 1146 Table '********' doesn't exist
I found that if we add if (!app()->runningInConsole()) { inside boot(), it works successfully.
This is the code we have used in the service provider:
public function boot()
{
$this->bindCurrentPartToNav();
}
private function bindCurrentPartToNav(): void
{
$currentPartName = \App\Http\Helpers\Part::getPartName();
view()->composer(
'includes.partials.part',
function ($view) use ($currentPartName) {
$view->with('currentPartName', $currentPartName);
}
);
}
Helper file:
public static function getPartName(): ?string
{
return PartModel::PartKey()->active()->pluck('name')->first();
}
Model:
public function scopePartKey($query): Builder
{
return $query->where('identifier', config('env.PART_KEY'));
}
Is there any way to remove that service provider from php artisan migrate so that we can remove runningInConsole() check in each refresh?
Thanks for your help in advance.
As any environment configuration, in your case a general configuration, you should assign a default value fall back.
public static function getSectionName(): ?string
{
try {
return SectionModel::sectionKey()->active()->pluck('name')->first();
} catch (\Exception $e) {
return null;
}
}
This will simulate the case where the section model with that specific identification_key is missing in the database.
This will also prevent any issues with the initial migration.
But in the end, you tied a model with a view rendering code. You should find another solution to dissociate them. For example, you can move the boot() code out of the model and link it to a middleware.
You can also use Singleton pattern (since it's like a general unique config across the application)

laravel resource url depend on model?

i am run this command for model, migration, resource controller. php artisan make:model QuestionAnswer -mc -r ..
Resource Route
Route::resource('faq','QuestionAnswerController');
My Edit Function
public function edit(QuestionAnswer $questionAnswer)
{
// return $questionAnswer;
return view('backend.faq.edit',get_defined_vars());
}
Edit Route
{{route('admin.faq.edit',$questionAnswer->id)}}
Edit function return $questionAnswer return null
Below Picture
When i Change resource route like model name
Route::resource('question-answer','QuestionAnswerController');
edit function return $questionAnswer return object mean expected output ..
Picture
Question
laravel resource url depend on model or something ?
if i am wrong somewhere for Route::resource('faq','QuestionAnswerController'); please comment i will remove my question..
Bacause your route parameter is question_answer, so change the controller to :
public function edit(QuestionAnswer $question_answer)
{
dd($question_answer);
}
Alternatively, you can specifically tell the resource what the route parameter should be named :
Route::resource('faq','QuestionAnswerController')
->parameters(['faq' => 'questionAnswer']);
Now you can access $questionAnswer as parameter :
public function edit(QuestionAnswer $questionAnswer)
{
dd($questionAnswer);
}
The official documentation of Naming Resource Route Parameters will be found here
Laravel resource generate prams base on url example
Route::resource('faq','QuestionAnswerController');
// this will generate url like
Route::get('faq','QuestionAnswerController#index')->name('faq,index');
Route::post('faq','QuestionAnswerController#store')->name('faq,store');
Route::get('faq/{faq}','QuestionAnswerController#show')->name('faq,show');
Route::put('faq/{faq}','QuestionAnswerController#update')->name('faq,update');
Route::delete('faq/{faq}','QuestionAnswerController#destroy')->name('faq,destroy');
so here in controller you need to accept that faq like this
public function edit(QuestionAnswer $faq) // here $faq should match with route prams
{
return $faq;
}
or you can change route url faq to questionAnswer then your old code will work
ref link https://laravel.com/docs/8.x/controllers#actions-handled-by-resource-controller

The update nor the destroy methods won't work in laravel eloquent model?

I have a strange situation where eloquent model won't let me update nor destroy while index and create is working fine!
I'm using Vue.js and Laravel API Resource for form control, and while it worked with me before, it won't work here:
Here's my Vue.js Code:
updateFinish(finish) {
axios.patch(`/api/finishes/${finish.id}`, finish).then(response => {
this.fetchFinishes();
}).catch(error => {
// Get laravel validation error
this.errors = error.response.data.errors;
});
},
laravel update code (not working)
public function update(FinishType $finishType)
{
// Don't know why not working
$finishType->update($this->validateRequest());
return new FinishTypeResource($finishType);
}
the response is null:
{"id":null,"name":null}
While this code works:
public function update($id)
{
$finishType = FinishType::find($id);
$validates = $this->validateRequest();
$finishType->name = $validates['name'];
$finishType->save();
return new FinishTypeResource($finishType);
}
public function validateRequest()
{
return request()->validate([
'name' => 'required | unique:finish_types',
]);
}
Note the Model name is FinishType and database table name is finish_types, I even tried to define the table name in the model like so protected $table = 'finish_types' – still not working and I already have defined the $fillable array!!!
Your route model binding is not working correctly, for the implicit binding to work your injected variable should match the route parameter name.
Assuming that your parameter name could be finish (reading the url from your javascript) you have to write the update function using $finish as injected variable, like this:
public function update(FinishType $finish)
{
$finish->update($this->validateRequest());
return new FinishTypeResource($finish);
}
Do the same for destroy():
public function destroy(FinishType $finish)
{
// your destroy code here
}
In any case you can run php artisan route:list to find your parameter name (the part of the URI in braces) and give the same name to the injected variable.
If the two do not match, parameter and injected variable name, laravel injects a void, not loaded, FinishType model so it does not make sense doing an update or a delete on it.
I can't post comments so I'm going to post what I assume is the answer.
Laravel does route model binding automagically when the route url name corresponds to the name of the table I think... or model.
So users/{id} would auto bind the User object when you type it as a param in the controller. Example (User $user)
However, since your URL seems to be "different" from the name of your Model/Table, go to the RouteServiceProvider, and manually do the binding.
So in your case you'd do something like this in the boot function of the RouteServiceProvider class:
public function boot()
{
parent::boot();
Route::model('finishes', FinishType::class);
}
Don't forget your imports :)
You can read more about Explicit Model Binding here: https://laravel.com/docs/5.8/routing#explicit-binding

laravel route issue .the page you are looking for could not be found

I want to show data from the database when I press the button in one view it displays me the specific data by the id in the other view this is my first view.
In my controller:
public function show($id) {
$symptoms=symptoms::all();
foreach ($symptoms as $symptom) $symptom=symptoms::find($id);
return view('front.second',compact('symptom'));
}
My problem is when displays the second view it can't find the page and the route just display the id not the method/id :(
Try this:
public function show(symptoms $symptom)
{
return view('front.second', compact('symptom'));
}
Or:
public function show($id)
{
$symptom = symptoms::find($id);
return view('front.second', compact('symptom'));
}
And read Laravel's Controllers Documentation carefully.
As you shared image, is clearly shows that you are using below route
{{route('show',['id'=>111])}}
Check your route by php artisan route:list and use right one, I guess you should use like
{{route('user.show',['id'=>111])}}
If you Controller name is UserController in resource

Laravel Backpack - getting current record from crud controller

In my crud controller I am trying to get the name of the person who is currently being edited.
so
http://192.168.10.10/admin/people/93/edit
In the people crud controller
public function setup() {
dd(\App\Models\People::get()->first()->name)
}
This returns the first person not the person currently being edited.
How do I return the current person (with an id of 93 in this example)
Ok, So since you use backpack look into CrudController to see how the method looks:
public function edit($id)
{
$this->crud->hasAccessOrFail('update');
$this->data['entry'] = $this->crud->getEntry($id);
$this->data['crud'] = $this->crud;
$this->data['fields'] = $this->crud->getUpdateFields($id);
$this->data['id'] = $id;
return view('crud::edit', $this->data);
}
So now you can overwrite the edit function and change whatever you want. You can even create a custom edit page if you so wish.
Setup on the other hand is usually used to add things like
$this->crud->addClause(...);
Or you can even get the entire constructor and put it in the setup method because setup call looks like this:
public function __construct()
{
// call the setup function inside this closure to also have the request there
// this way, developers can use things stored in session (auth variables, etc)
$this->middleware(function ($request, $next) {
$this->setup();
return $next($request);
});
}
So you could do something like \Auth::user()->id;
Also it's normal to work like this. If you only use pure laravel you will only have access to the current id in the routes that you set accordingly.
Rahman said about find($id) method. If you want to abort 404 exception just use method findOrFail($id). In my opinion it's better way, because find($id)->name can throw
"Trying to get property of non-object error ..."
findOrFail($id) first fetch user with specified ID. If doesn't exists just throw 404, not 500.
The best answer is:
public function edit($id)
{
return \App\Models\People::findOrFail($id);
}
Good luck.
you need person against id, try below
public function setup($id) {
dd(\App\Models\People::find($id)->name);
}

Resources