Laravel Resource Controller update method not firing - php

I have a resource controller TruckController generated via php artisan make:controller TruckController --resource.
When I go go to localhost/trucks/1/edit, the edit form shows up successfully.
When I click submit, I am redirected to the resource show page (localhost/trucks/1); however, the truck information is not updated and no errors were thrown.
It seems the update function is not firing at all, which I think means there is something wrong with the action attribute in my form, but I am still unsure. There shouldn't be an issue with the routes because the routes should already be defined because it's a resource controller.
edit.blade.php
<form method="PUT" action="{{ action('TruckController#update', ['id' => $truck->id]) }}" class="validate form-horizontal form-groups-bordered" novalidate="novalidate">
#csrf
<input type="hidden" name="state" data-geo="administrative_area_level_1" value="{{ $truck->state }}">
<input type="hidden" name="city" data-geo="locality" value="{{ $truck->city }}">
<input type="hidden" name="zipcode" data-geo="postal_code" value="{{ $truck->zipcode }}">
[ ... ]
</form>
TruckController#update
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(TruckCreateRequest $request, Truck $truck)
{
$validated = $request->validated();
$truck->name = $request->name;
$truck->description = $request->description;
$truck->save();
}
TruckCreateRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TruckCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required',
'description' => 'required',
'city' => 'required',
'state' => 'required',
'zipcode' => 'required',
'address' => 'required'
];
}
}
And just in case this may be of more help ...
Web.php
<?php
Auth::routes();
// ajax
Route::post('ajax/notifications/clear', 'DashboardController#mark_notifications_read');
Route::get('/', 'DashboardController#index')->name('dash');
Route::resource('events', 'EventController');
Route::resource('venues', 'VenueController');
Route::resource('trucks', 'TruckController');
Route::resource('admin', 'AdminController');
App/Models/Truck.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Truck extends Model
{
//
}

From the Laravel Documentation:
Since HTML forms can't make PUT, PATCH, or DELETE requests, you will
need to add a hidden _method field to spoof these HTTP verbs.
Try to add a hidden method field to the form:
#method('PUT')
Read more here: https://laravel.com/docs/5.7/blade#method-field

You should try this:
<form method="POST" action="{{ action('TruckController#update', [$truck->id]) }}" class="validate form-horizontal form-groups-bordered" novalidate="novalidate">
#csrf
<input type="hidden" name="state" data-geo="administrative_area_level_1" value="{{ $truck->state }}">
<input type="hidden" name="city" data-geo="locality" value="{{ $truck->city }}">
<input type="hidden" name="zipcode" data-geo="postal_code" value="{{ $truck->zipcode }}">
[ ... ]
</form>

Related

Single Validation in Laravel

I am very new to Laravel, and our system uses multiple forms within a single page to insert the single bitcoin wallet into each input field, but as it stands the user is able to use it on all inputs and this is wrong as could i make only one valid? such as "username" "email" etc ..
html:
<form method="POST" action="/wallet3-edit/update">
<div class="form-group hidden">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="PATCH">
</div>
<div class="form-group {{ $errors->has('bitzpayer_id3') ? ' has-error' : '' }}">
<label for="bitzpayer_id3" class="control-label"><b>Wallet:</b></label>
<input type="text" name="bitzpayer_id3" placeholder="Please enter your Wallet here" class="form-control" value="{{ $user->bitzpayer_id3 }}"/>
<?php if ($errors->has('bitzpayer_id3')) :?>
<span class="help-block">
<strong>{{$errors->first('bitzpayer_id3')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group">
<button type="submit" class="btn btn-warning text-white"> Submit </button>
</div>
</form>
Controller:
<?php
namespace App\Http\Controllers;
use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class Wallet3Controller extends Controller
{
/**
* Update user profile & make backend push to DB
*
**/
public function index() {
/**
* fetching the user model
**/
$user = Auth::user();
//var_dump($user);
/**
* Passing the user data to profile view
*/
return view('/wallet3-edit', compact('user'));
}
public function update(Request $request) {
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Validate request/input
**/
$this->validate($request, [
'bitzpayer_id3' => 'max:255|unique:users,bitzpayer_id3,'.$user->id,
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('bitzpayer_id3');
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
}
Routes:
Route::get('wallet3-edit', 'Wallet3Controller#index');
Route::patch('wallet3-edit/{id}', 'Wallet3Controller#update');
if you want to validate not duplication in a single page:
because The page dosent send any request to server until the form completes,
you can check this within javascript/jquery like this:
$(".inputs").change(function(){
if($("#input1").val()==$("#input2").val()){
$("#input1").addClass("error");
}
});
but if your input are seprated in different pages and save in database you can validate with them with this kind of rules in Laravel controller or Laravel Request Class:
$validationRules = ["wallet" => "required|unique:wallets_table,btc"];
where "wallet" is the name of your input field. "wallets_table" is your database table and "btc" is table column.
but if you are not willing to save the wallet public keys in Database and the requests are from a single user, you can save the "Address"es in a Session Array and check them out when a user submit a request. but this solution works User Scope .
please give me more details if I misunderstood.

Why my post method doesn't work in Laravel?

I've created a form in Laravel to submit registration data to database. I've done this identically as other form in other view that works. Checked for typo's but still when I press submit button, nothing happens.
HTML of form in 'registrations/create.blade.php'
<form method="POST" action="{{route('registrations.store')}}"></form>
<div class="container">
<p>Prašome užpildyti visus laukus.</p>
<hr>
#csrf
<label for="vardas"><b>Vardas</b></label>
<input type="text" placeholder="Įveskite savo vardą" name="vardas" required>
<label for="pavarde"><b>Pavardė</b></label>
<input type="text" placeholder="Įveskite savo pavardę" name="pavarde" required>
<label for="el_pastas"><b>El. paštas</b></label>
<input type="text" placeholder="Įveskite savo el. paštą" name="el_pastas" required>
<label for="tel_nr"><b>Telefono nr.</b></label>
<input type="text" placeholder="Įveskite savo telefono nr." name="tel_nr" required>
<b>Pasirinkite norimą gitaros mokytoją</b><br><br>
<input type="radio" name="mokytojas_id" value="1"> Petras Petrauskas<br>
<input type="radio" name="mokytojas_id" value="2"> Andrius Rimiškis<br>
<input type="radio" name="mokytojas_id" value="3"> Virgis Stakėnas<br>
<hr>
<button type="submit" class="registerbtn"><b>Registruotis</b></button>
</div>
</form>
'routes.web.php'
Route::get('/', 'PagesController#index');
Route::get('/contacts', 'PagesController#contacts');
Route::get('/form', 'PagesController#form');
Route::get('/guitarists', 'PagesController#guitarists');
Route::get('/news', 'PagesController#news');
Route::resource('questions', 'QuestionsController');
Route::resource('registrations', 'RegistrationsController');
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/admin', 'AdminController#dashboard');
Route::resource('guitarists', 'MokytojaiController');
Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Registration extends Model
{
protected $fillable = ['vardas', 'pavarde', 'el_pastas', 'tel_nr', 'mokytojas_id'];
}
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\Registration;
class RegistrationsController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//$questions = DB::select('SELECT * FROM questions');
//$questions = Question::orderBy('id','desc')->take(1)->get();
//$questions = Question::orderBy('id','desc')->get();
$registrations = Registration::orderBy('id','desc')->paginate(10);
return view ('registrations.index')->with('registrations', $registrations);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('registrations.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'vardas' => 'required',
'pavarde' => 'required',
'el_pastas' => 'required',
'tel_nr' => 'required',
'mokytojas_id' => 'required'
]);
$post = $request->all();
Registration::create($post);
return redirect('/registrations/create')->with('status', 'Registracija atlikta!');
}
Your form tag is closed immediately.
<form method="POST" action="{{route('registrations.store')}}"></form>
Is this a type when you posted here or most probably this is the issue. Button is doing nothing since its not inside the form tag.

How to fix 'The POST method is not supported for this route. Supported methods: GET, HEAD.'?

I'm trying to make a website where you can upload games and see them on the home page, but because I need a two-step form I can't directly send them to the database.
my controller:
public function createstep1(Request $request)
{
$naam = $request->session()->get('naam');
return view('games.game',compact('naam', $naam))->with('games', game::all());
}
public function postcreatestep1(Request $request)
{
$validatedData = $request->validate([
'naam' => 'required',
'geslacht' => 'required',
]);
if(empty($request->session()->get('naam'))){
return redirect('/game');
}else{
$naam = $request->session()->get('naam');
$naam->fill($validatedData);
$request->session()->put('naam', $naam);
}
return redirect('/newgame');
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create(Request $request)
{
$naam = $request->session()->get('naam');
return view('games.newgame',compact('naam',$naam));
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$game= new Game();
$game->game= $request['game'];
$game->naam= $request['naam'];
$game->geslacht= $request['geslacht'];
$game->save();
return redirect('/game');
}
<div id="newgame" style="height: 500px; width: 250px; float: left;">
<form method="post" name="naam">
#csrf
<input id="naam" name="naam" placeholder="naam">
<select name="geslacht" type="text">
<option name="man">man</option>
<option name="vrouw">vrouw</option>
</select>
<a type="submit"><button>volgende</button></a>
</form>
</div>
<div id="games" style="float: right">
#foreach($games as $game)
{{$game->game}} <br><br>
#endforeach
</div>
<h1>welkom {{$naam}}</h1>
<form method="post">
#csrf
<h3>game invoeren</h3>
<input type="text" id="gamenaam" name="gamenaam" placeholder="game">
<a id="submit" type="post" name="game" href="/newgame/store">
<button>verstuur</button></a>
</form>
Route::get('/', function () {
return view('welcome');
});
Route::get('/newgame', function () {
return view('games.newgame');
});
//Route::post('/newgames', ['as' => '/newgames', 'uses' => 'GameController#create']);
Route::get('/game', 'GameController#createstep1');
Route::post('/game', 'GameController#postcreatestep1');
Route::get('/newgame', 'GameController#create');
Route::post('/newgame/store', 'GameController#store');
I expect it will drop the game + name and gender in the database but the actual code gives an error message.
This work is for school but they can't help me if you have suggestions or can help me fix the problem that would be great.
When registering a new route you need to specify which HTTP method the route is for. Usually Route::get() is alright but since you're sending a POST request with your form to the controller method postcreatestep1, this one needs to be registered as a POST route with Route::post().
You may also declare a route available for multiple HTTP methods with the Route::match() method.
To get an overview of all available router methods the official documentation of Laravel is a good starting point.

Laravel 5.1 Basic Authentication

I am newbie to laravel, I have several doubts here to ask.
It's like when I do basic login and registeration using Auth Class which is by default provided by Laravel 5.1, it gives me 404 Not found error.
Here is my directory structure:
resources/views/auth/register.blade.php
resources/views/auth/login.blade.php
I am following laravel 5.1 official doc, to get this.
When I press for submit button in register form it throws me 404 not found error.
register.blade.php
<!-- resources/views/auth/register.blade.php -->
<form method="POST" action="/auth/register">
{!! csrf_field() !!}
<div>
Name
<input type="text" name="name" value="{{ old('name') }}">
</div>
<div>
Email
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
Password
<input type="password" name="password">
</div>
<div>
Confirm Password
<input type="password" name="password_confirmation">
</div>
<div>
<button type="submit">Register</button>
</div>
</form>
I have my auth class as a :
app/Http/Controllers/Auth/AuthController.php
app/Http/Controllers/Auth/PasswordController.php
My basic routes:
// Authentication routes...
Route::get('auth/login', 'Auth\AuthController#getLogin');
Route::post('auth/login', 'Auth\AuthController#postLogin');
Route::get('auth/logout', 'Auth\AuthController#getLogout');
// Registration routes...
Route::get('auth/register', 'Auth\AuthController#getRegister');
Route::post('auth/register', 'Auth\AuthController#postRegister');
Route::controllers([
'password' => 'Auth\PasswordController',
]);
Still it throws me 404 not found error. Any Solution What I am missing?
Also the routes shows AuthController#getRegister, do I have to manually create the function of getRegister, as I couldn't find any.?
I am new to laravel
Also my AuthController.php looks like
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectPath = '/dashboard';
protected $loginPath = '/login';
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}
I am not sure, but I guess the problem is coming from your action attribute in form. Never use plain url in form action in laravel.
Try to use
<form method="POST" action="{{ url('/auth/login') }}">
You can create also your forms in this way:(You have to add the dependency in your composer.json, search in google about laravel forms)
{!! Form::open(array('url' => 'http://other.domain.com')) !!}
<input type="text" name="test" value="something" />
<button type="submit">Submit</button>
{!! Form::close() !!}

Edit profile page using laravel

Whenever a user goes to mywebsite.com/profile I want a form to pre populate the values they've entered during the signup/registration flow. I was able to do that with my form here
<h1><b>Your Profile</b></h1>
<form method="POST" action="/profile/update">
<div class="form-group hidden">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="PATCH">
</div>
<div class="form-group {{ $errors->has('name') ? ' has-error' : '' }}">
<label for="email" class="control-label"><b>Name:</b></label>
<input type="text" name="name" placeholder="Please enter your email here" class="form-control" value="{{ $user->name }}"/>
<?php if ($errors->has('name')) :?>
<span class="help-block">
<strong>{{$errors->first('name')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group {{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="control-label"><b>Email:</b></label>
<input type="text" name="email" placeholder="Please enter your email here" class="form-control" value="{{ $user->email }}"/>
<?php if ($errors->has('email')) :?>
<span class="help-block">
<strong>{{$errors->first('email')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default"> Submit </button>
</div>
</form>
But now im running into the issue if the user just hits submit button without changing any fields, laravel's built in validations checks and gives me an error message of The name has already been taken. which is true. so im not sure how to handle this issue, but here is my controller below
<?php
namespace App\Http\Controllers;
use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ProfileController extends Controller
{
/**
* Update user profile & make backend push to DB
*
**/
public function index() {
/**
* fetching the user model
**/
$user = Auth::user();
//var_dump($user);
/**
* Passing the user data to profile view
*/
return view('profile', compact('user'));
}
public function update(Request $request) {
/**
* Validate request/input
**/
$this->validate($request, [
'name' => 'required|max:255|unique:users',
'email' => 'required|email|max:255|unique:users',
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('name','email');
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
}
and here is my routes file.
// only authenticated users
Route::group( ['middleware' => 'auth'], function() {
Route::get('/home', 'HomeController#index');
// practicing using forms for sending data to the DB & populating form fields with DB data
Route::get('profile', 'ProfileController#index');
Route::patch('profile/{id}', 'ProfileController#update');
});
Issue is due to unique validation rule. You can exclude the current user id by specifying unique validation rule. your code will be like this
public function update(Request $request) {
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Validate request/input
**/
$this->validate($request, [
'name' => 'required|max:255|unique:users,name,'.$user->id,
'email' => 'required|email|max:255|unique:users,email,'.$user->id,
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('name','email');
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
here is laravel documentation link for this https://laravel.com/docs/5.1/validation#rule-unique

Categories