Lansana Camara
Lansana Camara

Reputation: 9873

Laravel 5: Redirect "blog/{id}" to "blog/{slug}" - Trying to get property of non-object error

I'm trying to redirect users that go to blog/{id} to blog/{slug} with the slug being the slug of the id they entered.

What I am doing is not working. I dd{$article->slug} and get the correct string, yet when I try to redirect I get "Trying to get property of non-object" error.

I'm using route/model binding. This is my RouteServiceProvider:

    $router->bind('blog', function($slug)
    {
        if ($slug) {
            if(is_numeric($slug)) {
                $article = Article::findOrFail($slug);

                return redirect('blog/' . $article->slug);
            }

            return Article::with('images')->where('slug', $slug)->first();
        }
    });

This is my show method in controller:

public function show(Article $article)
{
    return view('blog.show', compact('article'));
}

Any ideas would be greatly appreciated!

articles migration file:

class CreateArticlesTable extends Migration
{
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->string('title');
            $table->string('slug');
            $table->text('body');
            $table->timestamps();

            $table->foreign('user_id')
                  ->references('id')
                  ->on('users')
                  ->onDelete('cascade');
        });
    }

    public function down()
    {
        Schema::drop('articles');
    }
}

Upvotes: 1

Views: 656

Answers (1)

Thomas Kim
Thomas Kim

Reputation: 15941

Your controller is expecting an instance of Article. So, if you're returning a RedirectResponse from your closure, it won't work.

At the moment, I can only think of 2 ways of achieving what you want with route-model binding.

  1. The first method is simpler. Just don't type-hint the Article. Instead, check if it's a RedirectResponse. If so, return it. If not, return the view. Something like this:

    public function show($article)
    {
        if ($article instanceof \Illuminate\Http\RedirectResponse)
        {
            return $article;
        }
        return view('blog.show', compact('article'));
    }
    

You could also check if it's an instance of an Article just to be absolutely certain since you're no longer type-hinting.

  1. The second method is overly complex in my opinion for a simple check. You would have to throw a custom exception, catch it from within app/Exceptions/Handler.php, and then redirect from there.

Upvotes: 1

Related Questions