milkncookiez's avatar

Wrong POST url

This is in my store method in the controller:

if (Auth::attempt(Input::only('username', 'password'))) {
                    $user = Auth::user();

                    return Redirect::to('user/' . $user->username);
                }

The show method:

public function show(User $user)
    {
        return View::make('user.profile', ['user' => $user]);
    }

and the view to it:

<h1>Profile page of {{ $user->username }}</h1>
    {{ Form::open(['route' => 'user.destroy']) }}
    <div class="form-group">
        {{ Form::submit('Logout', ['class' => 'btn btn-primary']) }}
        {{ link_to('user/'.$user->username.'/edit', 'Edit', ['class' => 'btn btn-default']) }}
    </div>
    {{ Form::close() }}

which should lead to the destroy action (but it doesn't because of the wrong POST action URL, that you can see a bit further down):

public function destroy(User $user)
    {
        Auth::logout();

        return Redirect::route('user.index');
    }

and, as you might have thought already, I am using Route resources + model minding. This is my routes.php file:

Route::bind('user', function ($username) {
    return User::where('username', $username)->first();
});
Route::resource('user', "UsersController");

So, when I log-in the user, I am redirected to .../user/relevant_usrename, which is fine, but when I inspect the Form, it looks like this:

<form method="POST" action="http://localhost:8000/user/%7Buser%7D" accept-charset="UTF-8">
...
</form>

You see that the POST action is wrong, although I seem to be passing correctly the object. How can I fix this? And please give me some explanation around the problem, instead of just a code solution, because I would like to understand what have I mistaken.

0 likes
6 replies
pmall's avatar

You have to put the method to delete

<h1>Profile page of {{ $user->username }}</h1>
    {{ Form::open(['route' => 'user.destroy', 'method' => 'delete']) }}
    <div class="form-group">
        {{ Form::submit('Logout', ['class' => 'btn btn-primary']) }}
        {{ link_to('user/'.$user->username.'/edit', 'Edit', ['class' => 'btn btn-default']) }}
    </div>
    {{ Form::close() }}
1 like
milkncookiez's avatar

@pmall, the POST action url is still with the weird symbols. And now, when I click the Logout button I get

Argument 1 passed to UsersController::destroy() must be an instance of User, none given

exception. I tried passing the object like that:

{{ Form::open(['route' => ['user.destroy', $user], 'method' => 'delete']) }}

but this is totally incorrect.

TL;DR: the action URL is still wrong and the user object is not being passed...

bart's avatar

You form opener should look like this:

{{ Form::open(['route' => ['user.destroy', $user->id], 'method' => 'delete']) }}

This will open a form using the delete method (adds a hidden _method field) and passes the user id as parameter for the restful resource.

1 like
pmall's avatar
pmall
Best Answer
Level 56

With a resource route the id of the entity is used. And 'route' => ['user.destroy', $user] will put the id in the url. Your binding function use the username of the user so it can't work. Try :

{{ Form::open(['route' => ['user.destroy', $user->username], 'method' => 'delete']) }}

Not sure if it will work.

Anyway I think it is a bad idea to use route-model bindings.

pmall's avatar

@milkncookiez other topic answered.

Route-model binding is a bad idea because it mix model selection and route definition. I will not be surprised if it gets removed.

Please or to participate in this conversation.