PUT method throws BadMethodCallException - php

I'm learning Laravel from Lacast and i'm trying to create a CRUD application.I've implemented the index,show,create and store correctly,but with the edit form when i try to submit data it's throwing BadMethodCallException.
Here are my routes
Route::get('/projects','ProjectsController#index');
Route::get('/projects/{id}','ProjectsController#show')->where('id','[0-9]+');
Route::get('/create','ProjectsController#create');
Route::post('/projects','ProjectsController#store');
Route::get('/projects/{id}/edit','ProjectsController#edit')->where('id','[0-9]+');
Route::put('/projects/{id}','ProjectsController#update')->where('id','[0-9]+');
Route::delete('/projects/{id}','ProjectsController#destroy');
Here is the edit form:
#extends('template');
#section('content')
<h2>Create new project</h2>
<p>/projects/{{ $project->id }}</p>
<form method="POST" action="/projects/{{ $project->id }}">
{{ method_field('PUT') }}
{{ csrf_field() }}
<div>
<input value="{{ $project->title }}" type="text" name="title" id="title" placeholder="Project title">
</div>
<div>
<textarea name="description" placeholder="Enter the project description">{{ $project->description }}</textarea>
</div>
<div>
<button type="submit">Update project</button>
</div>
</form>
#endsection
The controller code:
public function edit($id){
$project= Project::find($id);
return view('projects.edit',compact('project'));
}
public function update($id){
$project= Project::find($id);
$project->title=request('title');
$project->description('description');
$project->save();
return redirect('/projects');
}
The edit form displays as expected with data coming from the database,after submit i get the following error page:
With the example of the instructor the code has worked perfectly,and before using the PUT either on my form and in my controller i used PATCH like the instructor but always the same result.
Here is the instructor video link: Faking PATCH and DELETE Requests

The error is pretty straightforward.
public function update($id){
$project= Project::find($id);
$project->title=request('title');
$project->description('description'); // You don't have a method description()
$project->save();
return redirect('/projects');
}
This is what you probably meant to do:
public function update($id)
{
$project= Project::find($id);
$project->title = request('title');
$project->description = request('description');
$project->save();
return redirect('/projects');
}

Related

How to use same Blade template for add and edit operation of one controller in Laravel?

I have a question, I used the same blade template to create and insert. In my controller I created a variable ModificationMode on edit function and on the template I used isset() method.
Controller
public function edit($id)
{
$ModificationMode = 0;
$DataPraticien = \App\Praticien::find($id);
return view('AjoutePraticien', compact('DataPraticien'))->with('ModificationMode', $ModificationMode);
}
View
#if(isset($ModificationMode))
<form method="post" action="{{route('prat.update', $DataPraticien ?? '')}}">
#csrf
#method('PATCH')
#else
<form action="{{route('prat.store')}}" method="post">
#endif
//stuff
//stuff
I make every variable as optional. Is that a good idea? Can this method bring me some issues? How about security?
Here i am just explaining you with small example that how you use same form for add and edit. When I need to to the same I do this :
// routes.php
Route::get('test', 'TestController#create');
Route::get('test/{id}', 'TestController#edit');
Controller.php
// TestController.php
public function create()
{
return view('form');
}
public function edit($id)
{
$resource = Resource::find($id);
return view('form', compact('resource'));
}
Blade file
// form.blade.php
<h2>{{ isset($resource) ? 'Edit a Record' : 'Create a new Record' }}</h2>
<form action="{{ isset($resource) ? '/test/' . $resource->id : '/test' }}" method="post">
<label>Title</label>
<input type="text" name="title" value="{{ old('title', isset($resource) ? $resource->title : '') }}" />
<label>Description</label>
<textarea name="description">{{ old('description', isset($resource) ? $resource->description : '') }}</textarea>
<button type="submit">{{ isset($resource) ? 'Update' : 'Create' }}</button>
</form>
I think you are correct. If my form is simple then I do similar. Just a $ModificationMode variable does not require for me. what I do...
#if(isset($DataPraticien))
<form method="post" action="{{route('prat.update', $DataPraticien ?? '')}}">
#method('PATCH')
#else
<form action="{{route('prat.store')}}" method="post">
#endif
#csrf

The PUT method is not supported for this route. Supported methods: GET, HEAD, POST, DELETE. (note I am using model biding)

I am using model biding, but I am basically trying to create a form that can edit and update comments. It runs perfectly and even prompts me to edit the form. However, every time I try to update it the POST method is not supported for the root. which is bogus as I did the spoofing correctly, someone help me please.
Here us my CommentsController methods
public function edit($id)
{
$comment = Commenting::find($id);
return view('comments.edit', compact('comment'));
}
public function update(Request $request, $id, $posts)
{
$comment = Commenting::find($id);
$comment->update($request->all());
$comment->posts_id = $posts;
return view('post.show', compact('comment'));
}
Here is the routing in my web.php
Route::get('/posts/comment/{comment}', 'CommentsController#edit')->name('comments.edit')->middleware('auth');
Route::put('/posts/comment/{comment}', 'CommentsController#update')->name('comments.update')->middleware('auth');
Here's what I call the link to edit the form in my show.blade
Edit
lastly this is my edit.blade file
#extends ('layouts.home')
#section ('content')
<div class="card">
<h1> Edit Comment </h1>
<div class="card-block">
<form method="POST" action="{{route('comments.update', ['comments' => $comment])}}">
#csrf
#method('PUT')
<div class="form-group">
<textarea name="body" placeholder="Enter you comment here..." class="form-control"> {{$comment->body}}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Update</button>
</div>
</form>
#include ('layouts.errors')
</div>
</div>
#endsection
Take a look your update method
public function update(Request $request, $id, $posts)
Try to delete the $posts variable on update function
Try
{{method_field('put')}}
or
<input type="hidden" name="_method" value="PUT">
add patch method in blade file:
#extends ('layouts.home')
#section ('content')
<div class="card">
<h1> Edit Comment </h1>
<div class="card-block">
<form method="POST" action="{{route('comments.update', ['comments' => $comment])}}">
{{ csrf_field() }}
<input type="hidden" name="_method" value="PATCH">
<div class="form-group">
<textarea name="body" placeholder="Enter you comment here..." class="form-control"> {{$comment->body}}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Update</button>
</div>
</form>
#include ('layouts.errors')
</div>
</div>
#endsection
write post method in route file :
Route::post('/posts/comment/{comment}', 'CommentsController#update')->name('comments.update')->middleware('auth');
Your route binding is named comment not comments. This will not generate a URL to your comments.update route:
route('comments.update', ['comments' => $comment])
This will generate a URL to /posts/comment?comments=3 not /posts/comment/3. You want to use the same name as the route parameter so it knows to replace that route parameter:
route('comments.update', ['comment' => $comment])
Which would generate a URL to /posts/comment/3.
Also your controller method
public function update(Request $request, $id, $posts)
has a $posts variable but there is no parameter for that defined for the route, so where does that come from?
If you actually want to use Model Binding, which it would appear you are not, you could use Implicit Bindings by type-hinting a $comment argument on that controller method:
public function update(Request $request, Comment $comment)
as the route pararemeter is named comment not id.
Laravel 5.8 - Routing - Route Model Binding - Implicit Binding

Laravel Search function

i have a question about the Laravel search function, i had follow the guildeline online and i still fail to search the category, can someone guide me and tell me where i did wrongly ? Much appreciated
My category Controller php code:
public function search(Request $request)
{
$search = $request->get('search');
$posts = DB::table('bit_app_policy_category')->where('id','like','%' .$search. '%')->paginate(5);
return view('category.index',['posts' => $posts]);
}
My index.blade code
<div align="left">
<div class="col-md-4">
<h1>Policy</h1>
</div>
<div class="col-md-4">
<form action="/search" method="get" role="search">
{{ csrf_field() }}
<div class="input-group">
<input type="text" class="form-control" name="_method" placeholder="Search ID / Code"> <span class="input-group-btn">
<button type="submit" class="btn btn-primary">Search</button></span>
</div>
</form>
</div>
</div>
web.php
Route::get('/search','categoryController#search');
What error i get is here
Error image
interface
Database
You are sending $posts variable to your view. But the error says you are referencing a $category variable.
return view('category.index',['posts' => $posts]);
Maybe you might want to update view to use $posts. If you could post your full code (category/index.blade.php) we might be able to help you better.
__
Here is how I would do:
$categories= DB::table('bit_app_policy_category')->where('id','like','%' .$search. '%')->paginate(5);
return view('category.index',['categories' => $categories]); //you can also use compact return view('category.index', compact('categories') );
And to display:
#foreach( $categories as $category )
<div>{{ $category->id }}</div>
#endforeach
Another tip: you can name your routes like so
Route::get('search','categoryController#search')->name('search');
Then you can reference this route (in form or anywhere else you want) like so:
<form action="{{ route('search') }}" ..>

how to print task name using taskId in Laravel 5.2

I am developing project management app using laravel 5.2 and in my application user can create project and one project have many tasks and one task have many sub tasks. this is my relationship with each models
project Model
public function tasks(){
return $this->hasMany('App\Task');
}
Task Model
public function subtasks(){
return $this->hasMany(Subtask::class);
}
Subtask Model
public function task(){
return $this->belongsTo(Task::class);
}
this is my subtask input form in subtasks/form.blade.php
Add Sub Task
<form class="form-vertical" role="form" method="post" action="{{ route('subtasks.form', ['projectId'=> $projectId, 'taskId'=>$taskId])}}">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<input type="text" name="task_name" class="form-control" id="name" value="{{ old('task_name') ?: '' }}">
#if ($errors->has('task_name'))
<span class="help-block">{{ $errors->first('task_name') }}</span>
#endif
</div>
<div class="form-group">
<button type="submit" class="btn btn-info">Create Task</button>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
route
Route::get('projects/{projectId}/task/{taskId}/subtask', function ($projectId, $taskId) {
return view('subtasks/form',['projectId'=>$projectId,'taskId'=>$taskId]);
});
in my form file I can print $projectId and $ taskId as well but now I need print project_name and task_name regarding to ids how can I do this?
updated question
please see my subtask store methods
public function store(Request $request,$projectId,$taskId)
{
$subtask = new Subtask;
$subtask->subtask_name = $request->input('task_name');
$subtask->task_id = $taskId;
$subtask->project_id = $projectId;
$subtask->save();
//
}
You can do like so (Q&D solution):
Route::get('projects/{projectId}/task/{taskId}/subtask', function ($projectId, $taskId) {
$project = \App\ProjectModel::find($projectId);
$task = \App\TaskModel::find(taskId);
return view('subtasks/form',['project'=>$project,'task'=>$task]);
});
Note: In your form action, you will need to update the following :
['projectId'=> $projectId, 'taskId'=>$taskId]
By :
['projectId'=> $project->id, 'taskId'=>$task->id]

how to print the database content on a desired page?

I am using laravel 5.2. I want to print the database content that is stored in my database dynamically on the desired page. I tried but an error appears everytime i.e;( undefined variable:). I just want to print whatever content I store in my database table dynamically.
My code is here:
My model name is:gallery
My routes:
Route::get('/gallery/list' ,[
'uses'=>'gallerycontroller#viewgallerylist',
'as'=>'viewgallery'
]);
Route::post('/gallery/save' ,[
'uses'=>'gallerycontroller#savegallery',
'as'=>'savegallery'
]);
My controller:
public function viewgallerylist()
{
$galleries = gallery::all();
return view('gallery')->with('galleries', $galleries);
}
public function savegallery(Request $request)
{
$gallery1=$request['gallery_name'];
$gallery=new gallery();
$gallery->name=$gallery1;
$gallery->save();
return redirect()->route('viewgallery');
}
My desired page:
<form method="post" action="{{ route('savegallery') }}">
<input class="form-control" type="text" name="gallery_name">
<button type="submit" class="btn btn-primary" id="upl">Create+</button>
<input type="hidden" value="{{ Session::token() }}" name="_token">
</form>
#foreach($galleries as $gallery)
<p>{{ $gallery->name }}</p>
#endforeach
Most model Classes will have a capital letter. Are you sure your Model isn't called Gallery instead of gallery?
which means that you need to call Gallery::all() in your controller and make sure use App\Gallery; is at the top of your page.
public function viewgallerylist()
{
$galleries = Gallery::all();
return view('gallery')->with('galleries', $galleries);
}
The problem might be with your model.... please provide a larger view
Route::get('/' ,[
'uses'=>'gallerycontroller#viewgallerylist',
'as'=>'viewgallery'
]);
Route::post('/' ,[
'uses'=>'gallerycontroller#savegallery',
'as'=>'savegallery'
]);

Categories