Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MrAli's avatar
Level 1

Route pattern "/{username}/{{username}}" cannot reference variable name "username" more than once.

Hi

I am building web app. where url need to be like:

site.com/{username}/{id}

Route::get('/', 'PsotsController@index');

Auth::routes();
Route::resource('post', 'PsotsController');

Route::get('/profile', 'ProfileController@index')->name('home');

so i did

Route::resource('{username}', 'PostsController');

and i get the error : Route pattern "/{username}/{{username}}" .

λ php artisan route:list
.

 {username}                   | {username}.index   | App\Http\Controllers\PostsController@index
 {username}                   | {username}.store   | App\Http\Controllers\PostsController@store
 {username}/create            | {username}.create  | App\Http\Controllers\PostsController@create
 {username}/{{username}}      | {username}.update  | App\Http\Controllers\PostsController@update
 {username}/{{username}}      | {username}.show    | App\Http\Controllers\PostsController@show
 {username}/{{username}}      | {username}.destroy | App\Http\Controllers\PostsController@destroy
 {username}/{{username}}/edit | {username}.edit    | App\Http\Controllers\PostsController@edit

How to delete the second {{username}} from the url pattern?

0 likes
19 replies
MichalOravec's avatar

Why you dont't create it just like this? It should be CRUD?

Route::get('{username}', 'UserController@show')->name('user.show');
1 like
MrAli's avatar
Level 1

@m7vm7v Thank you for your replay. I am sill looking for solution.

web.php

Route::resource('{user}', 'PostsController');
λ php artisan route:list 


GET|HEAD  | {user}               | {user}.index   | App\Http\Controllers\PostsController@index
POST      | {user}               | {user}.store   | App\Http\Controllers\PostsController@store
GET|HEAD  | {user}/create        | {user}.create  | App\Http\Controllers\PostsController@create
DELETE    | {user}/{{user}}      | {user}.destroy | App\Http\Controllers\PostsController@destroy
GET|HEAD  | {user}/{{user}}      | {user}.show    | App\Http\Controllers\PostsController@show
UT|PATCH | {user}/{{user}}      | {user}.update  | App\Http\Controllers\PostsController@update
GET|HEAD  | {user}/{{user}}/edit | {user}.edit    | App\Http\Controllers\PostsController@edit

index store create Work Fine destroy show update edit show the username twice

site.com/M7VM7V/M7VM7V/slug wrong

site.com/M7VM7V/slug correct

And i sow the video and tried getRouteKeyName() in the Model.

I think the problem is from Route::resource.

MrAli's avatar
Level 1

@michaloravec Thank you for your replay.

Yes, It should be CRUD.

Is there away so i can edit Route::resources ?

drewdan's avatar
Route::resource('{user}', 'PostsController')->only(['show']);

What about that?

MichalOravec's avatar

@mrali

Route::resource('{user}', 'PostsController', ['parameters' => ['{user}' => 'optional?']]);

But in edit method you will need add something as optional parameter, also to show, update, destroy and edit method you will need add $optional = null as parameter

Or

Route::resource('{user}', 'PostsController', ['parameters' => ['{user}' => 'optional?'], 'except' => ['edit']]);
Route::get('{user}/edit', 'PostsController@edit')->name('{user}.edit');

But it's still better use classic resource like

Route::resource('users', 'PostsController');
1 like
MrAli's avatar
Level 1

@michaloravec @m7vm7v @drewdan

I still getting this error

 Trying to get property 'slug' of non-object (View: C:\xampp\htdocs\d\resources\views\editpost.blade.php)
http://127.0.0.1:8000/MrAli/5478/edit 

And this error

 Trying to get property 'body' of non-object (View: C:\xampp\htdocs\d\resources\views\showpost.blade.php)
http://127.0.0.1:8000/MrAli/5478 

web.php

<?php

use Illuminate\Support\Facades\Route;

Auth::routes();

Route::Get('/{user}', 'PostsController@index');
Route::Get('/{user}/create', 'PostsController@create'); 
Route::Post('/{user}/{post}', 'PostsController@store');
Route::GET('/{user}/{post}', 'PostsController@show');
Route::GET('/{user}/{post}/edit', 'PostsController@edit');
Route::PUT('/{user}/{post}', 'PostsController@update');
Route::DELETE('/{user}/{post}', 'PostsController@destroy');


Route::group(['prefix' => 'admin'], function () {
    Voyager::routes();
});


User.php

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends \TCG\Voyager\Models\User
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'username'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function posts()
    {
        return $this->hasMany('App\Post')->latest();
    }

    public function getRouteKeyName() __//Thanks To @m7vm7v__
        {
            return 'username';
        }
}

public function getRouteKeyName() //Thanks To @m7vm7v

Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function getRouteKeyName()
        {
            return 'slug';
        }
}

PostController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; 
// use Illuminate\Support\Facades\DB;
use App\post;
use App\User;

class PostsController extends Controller
{
    public function __construct()
        {
            $this->middleware('auth', ['except' => ['index', 'show']]);
        }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // $user_id = Auth::id();
        // $user = User::find($user_id);
        // $posts = $user->posts()->get(); 
        // return view('posts')->with('posts', $posts);

         // https://github.com/laracasts/Tweety/blob/master/app/Http/Controllers/HomeController.php
           return view('posts', [
            'posts' => auth()->user()
            // 'tweets' => auth()->user()->timeline()
        ]);
    
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $user_id = Auth::id();
        $user = User::find($user_id);
        return view('createpost')->with('user', $user);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'body'  => 'required',            
        ]);

        // Create post
        $post              =  new Post;
        $post->user_id     =  auth()->user()->id;
        $post->link        =  bin2hex(random_bytes(3)).time(); 
        $post->body        =  $request->input('body');
        $post->ip          =  $request->ip();
        $post->post_id      =  null;
        $post->is_active   =  1;

        $post->save();

        return redirect('/profile')->with('success', 'Send!'); //   /{username}/{link}
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    // public function show($id)
    // public function show(User $user, Post $post)
    public function show($id)
    {
        $post = Post::find($id);
        return view('showpost')->with('post', $post);        
        
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $post = Post::find($id);
        $user_id = Auth::id();
        $user = User::find($user_id);
        return view('editpost')
        ->with('post', $post)
        ->with('user', $user);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'body'  => 'required',            
        ]);

        // Create Post
        $post              =  Post::find($id);
        $post->user_id     =  auth()->user()->id;
        $post->link        =  bin2hex(random_bytes(3)).time(); 
        $post->body        =  $request->input('body');
        $post->ip          =  $request->ip();
        $post->post_id      =  null;
        $post->is_active   =  1;

        $post->save();

        return redirect('/profile')->with('success', 'Send!'); //   /{username}/{link}
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $post = Post::find($id);
        $post->delete();

        return redirect('/profile')->with('success', 'Send! ');
    }
}

MichalOravec's avatar

@mrali If your route is like this

Route::get('/{user}/{post}/edit', 'PostsController@edit');

So you have to have both parameters in controller method, and in all of them where it is neccesary.

public function edit($userId, $postId)
{
    // your code
}

So second paramteter is $postId

MichalOravec's avatar

@mrali Did you read what I write before?

And one more thing, instead of Post::find($id); use Post::findOrFail($id)

MrAli's avatar
Level 1

@michaloravec

I did read what you wrote.

 Missing required parameters for [Route: ] [URI: {user}/{post}]. (View: C:\xampp\htdocs\d\resources\views\editpost.blade.php)
http://127.0.0.1:8000/MrAli/5478/edit 
Route::Get('/{user:username}', 'PostsController@index');
Route::Get('/{user:username}/create', 'PostsController@create'); // {user:username}/add
Route::Post('/{user:username}/{post:link}', 'PostsController@store');
Route::GET('/{user:username}/{post:link}', 'PostsController@show');
Route::GET('/{user:username}/{post:link}/edit', 'PostsController@edit');
Route::PUT('/{user:username}/{post:link}', 'PostsController@update');
Route::DELETE('/{user:username}/{post:link}', 'PostsController@destroy');

public function edit($post_link, $user_username) 
    {
        $post = Post::find($post_link);
        $user_id = Auth::id();
        $user = User::find($user_username);
        return view('editpost')
        ->with('post', $post)
        ->with('user', $user);
    }

I comment out getRouteKeyName() in User.php and Post.php

MrAli's avatar
Level 1

Post::findOrFail($id) Don't show error details so i use Post::find($id).

MrAli's avatar
Level 1

Let's Back to square one.

web.php

oute::resource('{user:username}/{img:link}', 'MsgsController');

λ php artisan route:list

Green Box: What i need. Red Box: What laraval give me. Yellow Box: \resources\views*.blade.php

users in db

msgs in db

MrAli's avatar
Level 1

I just can't finger this out . I did a lot of googling and laravel Docs reading.

User.php

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends \TCG\Voyager\Models\User
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'username'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function msgs()
    {
        return $this->hasMany('App\Msg')->latest();
    }

    public function getRouteKeyName()
        {
            return 'username';
        }
}

Msg.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Msg extends Model
{
    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function getRouteKeyName()
        {
            return 'link';
        }
}

web.php

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', 'MsgsController@index');

Auth::routes();
// Route::resource('{user:username:user:usernamename}/{img:link}', 'MsgsController');

Route::get('/profile', 'ProfileController@index')->name('home');


Route::group(['prefix' => 'admin'], function () {
    Voyager::routes();
});


Route::Get('/{user:username}', 'MsgsController@index');
Route::Get('/{user:username}/create', 'MsgsController@create')->name('create'); // {user:username}/add
Route::Post('/{user:username}/{msg:link}', 'MsgsController@store')->name('store');
Route::GET('/{user:username}/{msg:link}', 'MsgsController@show')->name('show');
Route::GET('/{user:username}/{msg:link}/edit', 'MsgsController@edit')->name('edit');
Route::PUT('/{user:username}/{msg:link}', 'MsgsController@update')->name('update');
Route::DELETE('/{user:username}/{msg:link}', 'MsgsController@destroy')->name('destroy');

MsgsController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; 
// use Illuminate\Support\Facades\DB;
use App\Msg;
use App\User;

class MsgsController extends Controller
{
    public function __construct()
        {
            $this->middleware('auth', ['except' => ['index', 'show']]);
        }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index($id)
    {
        // $msgs = Msg::orderBy('created_at', 'desc')->get();
        // $msg = Msg::orderBy('created_at', 'desc')->get();
        // return view('msgs')->with('msg', $msg);
        $msg = Msg::find($id);
        $user_id = Auth::id();
        $user = User::find($user_id);
        return view('msgs')
        ->with('msg', $msg)
        ->with('user', $user);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $user_id = Auth::id();
        $user = User::find($user_id);
        return view('createmsg')->with('user', $user);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'body'  => 'required',            
        ]);

        // Create Msg
        $msg              =  new Msg;
        $msg->user_id     =  auth()->user()->id;
        $msg->link        =  bin2hex(random_bytes(3)).time(); 
        $msg->body        =  $request->input('body');
        $msg->ip          =  $request->ip();
        $msg->msg_id      =  null;
        $msg->is_active   =  1;

        $msg->save();

        return redirect('/profile')->with('success', 'Send'); //   /{username}/{link}
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($msg)
    {
        $msg = Msg::find($msg);
        $user_id = Auth::id();
        $user = User::find($user_id);
        return view('showmsg')
        ->with('msg', $msg)
        ->with('user', $user);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $msg = Msg::find($id);
        $user_id = Auth::id();
        $user = User::find($user_id);
        return view('editmsg')
        ->with('msg', $msg)
        ->with('user', $user);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'body'  => 'required',            
        ]);

        // Create Msg
        $msg              =  Msg::find($id);
        $msg->user_id     =  auth()->user()->id;
        $msg->link        =  bin2hex(random_bytes(3)).time();
        $msg->body        =  $request->input('body');
        $msg->ip          =  $request->ip();
        $msg->msg_id      =  null;
        $msg->is_active   =  1;

        $msg->save();

        return redirect('/profile')->with('success', 'Send'); //   /{username}/{link}
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $msg = Msg::find($id);
        $msg->delete();

        return redirect('/profile')->with('success', 'Send');
    }
}

ProfileController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; // i added from https://laravel.com/docs/7.x/authentication#retrieving-the-authenticated-user
use App\User;

class ProfileController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        $user_id = Auth::id();
        $user_id = Auth::id();

        $user = User::find($user_id);

        return view('profile')->with('msgs', $user->msgs);
    }
}

createmsg.blade.php

@extends('layouts.app')

@section('content')
  <div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1>Create.blade.php</h1>
            <div class="card">
                <div class="card-header">Write Msg</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{-- You are logged in! --}}
                    {!!Form::open(['action' => ['MsgsController@store' , $user->username], 'method' => 'POST', 'enctype' => 'multipart/form-data'])!!}
                      {{Form::bsTextArea('body', '', ['placeholder' => 'msg text'])}}

                      <input type="submit" value="Senddd" class="btn btn-primary btn-lg" id="send">
                    {!!Form::close()!!}
                </div>
            </div>
        </div>
    </div>
</div>    
@endsection

editmsg.blade.php

@extends('layouts.app')

@section('content')
  <div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1>editmsg.blade.php</h1>
            <div class="card">
                <div class="card-header">Edit Msg</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{-- You are logged in! --}}
                    {!!Form::open(['action' => ['MsgsController@update' , $msg->id], 'method' => 'POST', 'enctype' => 'multipart/form-data'])!!}
                      {{Form::bsTextArea('body', $msg->body , ['placeholder' => 'Msgs Text'])}}
                      {{Form::hidden('_method', 'PUT')}}

                      <input type="submit" value="Sendd" class="btn btn-primary btn-lg" id="send">
                  {!!Form::close()!!}
                </div>
            </div>
        </div>
    </div>
</div>    
@endsection

msgs.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1>msgs.blade.php</h1>
            <div class="card">
                <div class="card-header">msgs</div>
                {{-- {{dd($msg)}} --}}
                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{-- You are logged in! --}}
                    @if (count($msgs))
                      <ul class="list-groug">
                            @foreach ($msgs as $msg)
                      {{-- <li class="list-group-item"><a href="{{route('show', $msg->link)}}">{{$msg->body}}</a></li>                                  --}}
                      <a href="{{ route('show', $msg->id) }}">{{$msg->body}}</a>
                            @endforeach
                      </ul>
                    @else
                      <p>There is no Msg</p>
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

profile.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1>Profile.blade.php</h1>
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{-- You are logged in! --}}
                    <h3>your Msgs</h3>
                    @if (count($msgs))
                        <table class="table table-striped">
                            <tr>
                                <th>Msg</th>
                                <th></th>
                                <th></th>
                            </tr>
                            @foreach ($msgs as $msg)
                                <tr>
                                    <td>{{$msg->body}}</td>
                                    <td><a class="btn btn-primary" href="/d/{{$msg->id}}/edit">Edit</a></td>
                                    <td>
                                        {!!Form::open(['action' => ['MsgsController@destroy' , $msg->id], 'method' => 'POST', 'enctype' => 'multipart/form-data', 'onsubmit' => 'return confirm("Are yOU sURE??")'])!!}

                                            {{Form::hidden('_method', 'DELETE')}}
                                            <input type="submit" value="Deleteee" class="btn btn-danger btn-lg" id="send">
                                        {!!Form::close()!!}
                                    </td>
                                </tr>
                            @endforeach
                        </table>                        
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

showmsg.blade.php

@extends('layouts.app')

@section('content')
  <div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1>Showmsg.blade.php</h1>
            <div class="card">
                <div class="card-header">MSG</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{-- You are logged in! --}}
                    <div class="well">
                      {{$msg->body}}
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>    
@endsection
MrAli's avatar
Level 1

Msgs

Schema::create('msgs', function (Blueprint $table) {
            $table->id();
            $table->string('link')->nullable();
            $table->string('body');
            $table->foreignId('user_id')->constrained()->nullable();
            $table->foreignId('msg_id')->constrained()->nullable(); // For replays 
            $table->string('ip')->nullable();
            $table->boolean('is_active')->nullable();
            $table->softDeletes();
            $table->timestamps();

Users

$table->id();
            $table->string('name');
            $table->string('username')->unique();
            $table->string('avatar')->nullable();
            $table->string('email')->unique();
            $table->string('bio')->nullable();
            $table->string('url')->nullable();
            $table->string('city')->nullable();
            $table->string('country')->nullable();
            $table->string('ip')->nullable();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('provider')->nullable(); // https://artisansweb.net/login-with-twitter-in-laravel-using-laravel-socialite/
            $table->string('provider_id')->nullable();
            $table->boolean('is_active')->default('1');
            $table->rememberToken();
            $table->softDeletes();
            $table->timestamps();
MichalOravec's avatar

@mrali How I menioned before on this example

Route::resource('{user}', 'PostsController', ['parameters' => ['{user}' => 'optional?']]);

// or

Route::resource('{user}', 'PostsController')->parameters([
    '{user}' => 'optional?'
]);

parameters is important.

But if you have problem with resource just don't use it a make your routes by hand for that.

That's it.

Documentation: https://laravel.com/docs/7.x/controllers#restful-naming-resource-routes

jaseofspades88's avatar

If you find yourself having to make modifications to the expected behaviour of Route::resource then I recommend you declare all of your routes as you require them. Write some tests to help you assert that those endpoints are working and then when you have the routes working then you have a base for regressions in your tests if you wish to refactor later.

Snapey's avatar

I could have cut this short by saying its not possible to have a resource route as the / route

All resource routes need a prefix of some sort.

Please or to participate in this conversation.