Laravel 8 form to update database - php

I am creating a simple blog site with CRUD functionality in Laravel 8. I have done this before using the deprecated Laravel forms, but am now trying to do it using HTML forms.
However, I am having some problem with the update part of the website. I have a controller called BlogsController with this function to be called to update the blog in the database which should be called when the user submits the form to update.
BlogsController update function
public function update(Request $request, $id)
{
$this->validate($request, [
'title' => 'required',
'body' => 'required',
'category' => 'required',
'description' => 'required',
'read_time' => 'required'
]);
$blog = Blog::find($id);
$blog->title = $request->input('title');
$blog->body = $request->input('body');
$blog->category = $request->input('category');
$blog->description = $request->input('description');
$blog->read_time = $request->input('read_time');
$blog->user_id = auth()->user()->id;
$blog->save();
return redirect('/dashboard')->with('success', 'Blog Updated');
}
What action does the form need to direct to? Top of update form
<form method="POST" action="update">
Route in web.php
Route::resource('blog', 'App\Http\Controllers\BlogsController');
Implementation in Laravel forms
{!! Form::open(['action' => ['App\Http\Controllers\BlogsController#update', $blog->id], 'method' => 'POST']) !!}

You can get a list of all your application routes and names by running
$ php artisan route:list
For your blog update route you should use
<form method="POST" action="{{ route('blog.update', ['blog' => $blog]) }}">
#method('PATCH')
</form>
in your template.
Make sure you have you have your csrf token set correctly at your form by using the #csrf, see Laravel docs.

One thing that's cool with Laravel is Route model binding. So what's that mean? We can do something like this in your update method
// BlogController.php
public function update(Request $request, Blog $blog) {
$request->validate([
'title' => 'required',
'body' => 'required',
'category' => 'required',
'description' => 'required',
'read_time' => 'required'
]);
$blog->title = $request->title;
$blog->body = $request->body;
$blog->category = $request->category;
$blog->description = $request->description;
$blog->read_time = $request->read_time;
if ($blog->save()) {
return redirect('/dashboard')->with('success', 'Blog Updated');
} else {
// handle error.
}
}
In your template, you'll want to make sure you're using a PATCH method:
<form method="POST" action="{{ route('blog.update', ['blog' => $blog]) }}">
#csrf
#method('PATCH')
...
</form>

I assume you are using Resource route for your CRUD functionality. In that case, Update method in resource controller called via PUT method and not POST. So, in your form, just add this to change the Form submission method to PUT:
<input name="_method" type="hidden" value="PUT">
Also, in your form declaration, you have to add the destination route like this:
<form method="POST" action="{{ route('blog.update', $blog->id) }}">

You also have the option of using the action to get a URL to the registered route:
action('App\Http\Controllers\BlogsController#update', ['blog' => $blog])

Check all route list:
$ php artisan route:list
your route should be like:
<form method="POST" action="{{ route('blog.update', ['blog' => $blog]) }}">
{{csrf_field()}}
{{ method_field('PATCH') }}
</form>

Related

How to call controller update method from blade laravel?

form method="put" action="{{URL::action('siteController#update')}}" accept-charset="UTF-8"></form>
Route::post('site/update/{id}', 'siteController#update');
public function update(Request $request, $id)
{
//
$this->validate($request,[
'Name' => 'required',
'Description' => 'required',
'Status' => 'required'
]);
$Data = site::find($id);
$Data->Name = $request->Name;
$Data->Description = $request->Description;
$Data->Status = $request->Status;
if($Data->save())
{
return $this->index();
}else{
return redirect()->back()->withErrors($errors,$this->errorBag());
}
}
By adding a name to your route such as
Route::post('site/update/{id}', 'siteController#update')->name('site-update');
It allows you to generate its URL without knowing it at all
<form method="post" action="{{ route('site-update', compact('id')) }}">
#csrf
add your form field here and use button type submit
</form>
Even if you decide to change the URL, the route helper does not care as long as the name stays the same (it's just an alias)
Try This,
<form method="post" action="{{ url('site/update/', ['id' => $id]) }}">
#csrf
add your form field here and use button type submit
</form>

Laravel form route not defined

I am trying to send a route the old way, without using Blade's {{}} tags. I am encountering a problem, because the framework throws my route as not defined. Can someone help me?
This is my form tag:
<form method="POST" action="{{ route('companyStore') }}">
My route
Route::post('companyStore', 'CompanyController#store');
My controller (the function name might help you undertand)
public function store(Request $request){
$company_name = $request->input('companyname');
$company_sector = $request->input('companyname');
$company_address = $request->input('companyaddress');
$company_phone = $request->input('companyphone');
$company_website = $request->input('companywebsite');
$company_representative = Auth::user()->id;
Company::create([
'name' => $company_name,
'sector' => $company_sector,
'address' => $company_address,
'phone' => $company_phone,
'website' => $company_website,
'representative_id' => $company_representative
]);
$company = Company::where('representative_id', $company_representative)->first();
User::where('id', $company_representative)->update(array('company_id' => $company->id));
return redirect('/admin/home');
}
The error is always:
Route [companyStore] not defined. (View:
When you use the route helper, it expects a named route. So define your route as this:
Route::post('companyStore', 'CompanyController#store')->name('companyStore');
or use:
<form method="POST" action="{{ url('/companyStore') }}">
or use:
<form method="POST" {{ action('CompanyController#store') }}>
You can define a route.
Route::post('companyStore', 'CompanyController#store')->name('companyStore');
and use this one:
<form method="POST" action="{{ route('companyStore') }}">
I don't know why #nakov has propsed {{ url('/companyStore') }}
Just Change
FORM
Route::post('companyStore', 'CompanyController#store');
TO
Route::post('companyStore', 'CompanyController#store')->name('companyStore');
Will just work

How to pass 2 parameters in a route, but make one hidden in Laravel?

I want to make an edit_Item functionality, but I'm having a little bit of trouble with routing when submiting the edited form. I get this error:
InvalidArgumentException in UrlGenerator.php line 314:
Route [userItems] not defined.
First of all, in my Edit page, I have a form which passes 2 arguments from the Items table (item_id and user_id) to the controller and it looks like this:
{!! Form::model($items, ['action' => ['ItemController#update', $items->id, $items->user_id], 'method' => 'PUT']) !!}
//Form inputs
{{ Form::close() }}
My Update controller looks like this:
public function update($id, $user_id){
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
'title' => 'required',
'description' => 'required|description',
);
// store
$items = Item::find($id);
$items->title = Input::get('title');
$items->description = Input::get('description');
$items->save();
// redirect
Session::flash('message', 'Successfully updated item!');
return Redirect::route('userItems');
}
And my Route with the Update method looks like this:
Route::put('/userItems/{id}/{user_id}', 'ItemController#update');
Now, when I submit I'm currently getting routed to:
http://localhost:8000/userItems/26/3
And I need to get routed to:
http://localhost:8000/userItems/3
Any ideas on how to make the item_id(26) disappear from the route?
You could use an hidden input
Define a hidden field (not visible to a user).
Your form
{!! Form::model($items, ['action' => ['ItemController#update', $items->user_id], 'method' => 'PUT']) !!}
<input type="hidden" name="item_id" value="{{$items->id}}">
//Form inputs
{{ Form::close() }}
Your route
Route::put('/userItems/{user_id}', 'ItemController#update');
Your controller
public function update($user_id){
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
'title' => 'required',
'description' => 'required|description',
);
// store
$item_id = Request::input('item_id');
$items = Item::find($item_id);
$items->title = Input::get('title');
$items->description = Input::get('description');
$items->save();
// redirect
Session::flash('message', 'Successfully updated item!');
return Redirect::route('userItems');
}

Laravel Form Model Binding not submitting

I'm having some trouble using form model binding with L4. My form is being populated, and the routes are correct but it's not submitting correctly.
Controller:
public function edit($id)
{
$transaction = Transaction::where('id', '=', $id)->get();
return View::make('transaction')->with('transactions', $transaction);
}
public function update($id)
{
$transaction = Transaction::find($id);
$input = Input::all();
$transaction->status = $input['status'];
$transaction->description = $input['description'];
$transaction->save();
}
View:
#foreach($transactions as $transaction)
{{ Form::model($transaction, array('route' => array('transactions.update', $transaction->id))); }}
{{ Form::text('description'); }}
{{ Form::select('status', array('R' => 'Recieved', 'S' => 'Shipped', 'P' => 'Pending'), 'R'); }}
{{ Form::submit('Submit'); }}
{{ Form::close(); }}
#endforeach
I'm assuming that your transactions.* routes are being generated via Route::resource().
Per the documentation, Laravel generates the following routes for a resource:
Verb Path Action Route Name
GET /resource index resource.index
GET /resource/create create resource.create
POST /resource store resource.store
GET /resource/{resource} show resource.show
GET /resource/{resource}/edit edit resource.edit
PUT/PATCH /resource/{resource} update resource.update
DELETE /resource/{resource} destroy resource.destroy
You'll see that resource.update is expecting a PUT/PATCH request, but Laravel forms default to POST.
To fix this, add 'method' => 'PUT' to the array of form options, like so:
{{ Form::model($transaction, array(
'method' => 'PUT',
'route' => array('transactions.update', $transaction->id)
)); }}
This will add a hidden input, <input type="hidden" name="_method" value="PUT" />, to your form which tells Laravel to spoof the request as a PUT.

Generating URL::route with parameter in Laravel 4

I am having trouble getting getting my parameter of 'item id' to tack onto the end of my route being generated for my form action url.
I have a page setup to 'update' an existing item. The routes looks something like this:
Route::get('/item/edit/{id}', array(
'as' => 'item-edit',
'uses' => 'ItemController#getEditItem',
));
Route::post('/item/edit/{id}', array(
'as' => 'item-edit-post',
'uses' => 'ItemController#postEditItem',
));
and my ItemController contains these methods:
public function getEditItem($id) {
$states = State::where('user_id', '=', Auth::user()->id)->get();
$types = Type::where('user_id', '=', Auth::user()->id)->get();
$item = Item::where('user_id', '=', Auth::user()->id)
->where('id', '=', $id)
->first();
return View::make('items.edit')
->with('item', $item)
->with('states', $states)
->with('types', $types);
}
public function postEditItem($id) {
// Validate input for Item changes
$validator = Validator::make(Input::all(),
array(
'label' => 'required|min:3|max:128|unique:items,label,null,id,user_id,' . Auth::user()->id,
'type_id' => 'required|integer',
'state_id' => 'required|integer',
)
);
if( $validator->fails() ) {
return Redirect::route('item-edit')
->withErrors($validator)
->withInput();
} else {
$item = Item::find($id);
$item->label = Input::get('label');
$item->type_id = Input::get('type_id');
$item->state_id = Input::get('state_id');
$item->save();
return Redirect::route('item-create')
->with('global', 'Your new item has been edited successfully!');
}
}
The last piece of the puzzle is my items.edit view:
#extends('layout.main')
#section('content')
<form action="{{ URL::route('item-edit-post', $item->id) }}" method="post" class="form-horizontal form-bordered" autocomplete="off">
<!-- some inputs and such -->
</form>
#stop
The action URL being generated here is wrong:
<form method="POST" action="http://manageitems.com/item/edit/%7Bid%7D" accept-charset="UTF-8" hello="hello" class="form-horizontal form-bordered">
For some reason it is escaping my {id} in the route and not adding on the actual item ID on the end of the route. I have tried a few different ways of doing this and read through the route parameter docs, but I haven't made any progress. I also tried using Laravel's for builder like so:
{{ Form::open(array('action' => 'ItemController#postEditItem', $item->id, 'class'=>'form-horizontal form-bordered')) }}
but this did the same thing. I am new to Laravel so this may be a simple problem that I am overlooking, any help is much appreciated.
Use an array in the second parameter.
URL::route('item-edit-post', ['id' => $item->id])
Or the route helper (what I would go with, fits more in view files).
route('item-edit-post', ['id' => $item->id])
It seems that $item->id returns null.
And this is how you do it, when you specify action or route in the Form::open:
Form::open(['route' => ['some.route', $param]]);
Form::open(['action' => ['controller#action', $param]]);

Categories