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

Bradley James Ahrens's avatar

Trying to get property of non-object - for authorized users only

Hi guys,

I'm having a weird problem that I can't see to figure out.

I am using the typical CRUD method. When I put the show route under the auth middleware, I can see it by authorized users, but of course, not by unauthorized users. Weirdly enough, when I put the show route outside of the auth middleware, then authorized users cannot see the create page. I'm really confused.

Let me share some code: (Here, the unauthorized users can see the posts, but when an authorized user tries to create a new post, he gets the following error

(2/2) ErrorException Trying to get property of non-object (View: /Users/code/resources/views/rooms/show.blade.php)

web.php

<?php

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

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

Route::get('{provider}/auth', [
  'uses' => 'SocialsController@auth',
  'as' => 'social.auth'
  ]);
Route::get('/{provider}/redirect', [
  'uses' => 'SocialsController@auth_callback',
  'as' => 'social.callback'
  ]);
Route::get('rooms/index', [
  'uses' => 'RoomsController@index',
  'as' => 'rooms.index'
  ]);
  Route::get('rooms/{slug}', [
  'uses' => 'RoomsController@show',
  'as' => 'room'
  ]);

Route::group(['middleware'=>'auth'], function() {

  Route::get('rooms/create', [
    'uses' => 'RoomsController@create',
    'as' => 'rooms.create'
    ]);
  Route::post('rooms/store', [
    'uses' => 'RoomsController@store',
    'as' => 'rooms.store'
    ]);
  Route::get('rooms/edit/{slug}', [
    'uses' => 'RoomsController@edit',
    'as' => 'rooms.edit'
    ]);
  Route::put('rooms/update/{id}', [
    'uses' => 'RoomsController@update',
    'as' => 'rooms.update'
    ]);
  Route::delete('rooms/delete/{slug}', [
    'uses' => 'RoomsController@destroy',
    'as' => 'rooms.destroy'
    ]);
});

RoomsController.php


...
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('rooms.create');
    }

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

        $room = Room::create([
            'title' => request()->title,
...
        ]);

        return redirect()->route('room', ['slug' => $room->slug]);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($slug)
    {
        return view('rooms.show')->with('rooms', Room::where('slug', $slug)->first());
    }

Is there anyway to perhaps put the show route available to both authorized and non-authorized users? (This seems to be the case for everything outside of the auth middleware.... but, at this point, I'm not really sure.)

Thanks a lot for any ideas or help that you can provide. You guys have been really great!

Thanks!

Brad

0 likes
30 replies
Dry7's avatar

Show the code show.blade.php

1 like
Bradley James Ahrens's avatar

Hi @Dry7 here is my show.blade.php. I include edit and delete buttons which should only be shown to authenticated users, but this is already within an IF statement. Even if I comment this section out, I still have the same problem. It only fully works if I comment out all of the {{ $rooms->XYZ }} tags.

show.blade.php

@extends('layouts.app')

@section('content')

<h1 class="text-center">{{ $rooms->title }}</h1>
<div class="container" style="margin-bottom: 90px;">

@if(Auth::id() == $rooms->user->id)
  <a href="{{ route('rooms.edit', ['slug' => $rooms->slug ])}}" class="btn btn-lg btn-info">Edit</a>
  <form action="{{ route('rooms.destroy', ['rooms' => $rooms->id ])}}" method="post" style="display: inline" class="delete">
    {{ csrf_field() }}
    {{ method_field('DELETE') }}
    <button type="submit" class="btn btn-lg btn-danger" style="color: white;">Delete</button>
  </form>
@endif

<br>

<label for="title" class="form-title">Basic Information</label>
<h2>Price: {{ $rooms->price }}</h2>
....

</div>



 @endsection
Dry7's avatar

maybe

<form action="{{ route('rooms.destroy', ['slug' => $rooms->slug ])}}" method="post" style="display: inline" class="delete">
Snapey's avatar

can you look at the actual error messages. it will give you enough detail to work out where the error is. Also, look for error 1 not 2

if you cannot understand it, post the top few of lines of the error

1 like
Bradley James Ahrens's avatar

@Snapey , good point. Sorry for not posting it earlier.

Here is the first error. I think the problem is probably described below... but, I'm still having problems understanding what it is trying to say.

First error

(1/2) ErrorException Trying to get property of non-object in 894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php (line 3) at HandleExceptions->handleError(8, 'Trying to get property of non-object', '/Users/me/code/lsh/storage/framework/views/894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php', 3, array('__path' => '/Users/me/code/lsh/storage/framework/views/894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php', '__data' => array('__env' => object(Factory), 'app' => object(Application), 'count' => 1, 'errors' => object(ViewErrorBag), 'rooms' => null), 'obLevel' => 1, '__env' => object(Factory), 'app' => object(Application), 'count' => 1, 'errors' => object(ViewErrorBag), 'rooms' => null)) in 894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php (line 3)
Bradley James Ahrens's avatar

Wild guess: if 'rooms' => null... does this mean that I should share a view of rooms in the AppServiceProvider?

Jaytee's avatar

I'm pretty sure Auth::id() required the user to be logged in, it doesn't check so that's probably where your error is coming from.

1 like
Snapey's avatar

you can check the view by looking for the file mentioned in the storage/app/views folder

1 like
bipin's avatar

@almost_pitt did you check using dd in controller what you are getting i think you are getting same auth::id more than once

Bradley James Ahrens's avatar

@Snapey , I was able to find the file in storage/framework/views. However, it didn't seem to tell me much. It's just in php instead of blade. Any idea what I should be looking for here?

Snapey's avatar

Look at the line mentioned in the error message

Bradley James Ahrens's avatar

What is interesting is that the page that I want to go to, create.blade.php doesn't load even if it is all commented out. It only loads if I comment out everything on the show.blade.php.

The only connection I can see between them is in the RoomsController, where I define show as:

    public function show($slug)
    {
        return view('rooms.show')->with('rooms', Room::where('slug', $slug)->first());
    }

So, it is getting the slug from the create page... maybe I can change this with the $id and it will work...

---> nevermind this is a dumb idea. I need the slug to show the pages.

Jaytee's avatar

create.rooms.php ?

Should have a blade extension

Bradley James Ahrens's avatar

@Snapey - So, I'm still a bit lost. I like your direction, but I think I'm going astray at some point. Let me bring you through what I think you are saying.

So, here is the error:

(1/2) ErrorException Trying to get property of non-object

details:

at HandleExceptions->handleError(8, 'Trying to get property of non-object', '/Users/bradahrens/code/lisbonstudenthousing/storage/framework/views/894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php', 3, array('__path' => '/Users/bradahrens/code/lisbonstudenthousing/storage/framework/views/894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php', '__data' => array('__env' => object(Factory), 'app' => object(Application), 'count' => 1, 'errors' => object(ViewErrorBag), 'rooms' => null), 'obLevel' => 1, '__env' => object(Factory), 'app' => object(Application), 'count' => 1, 'errors' => object(ViewErrorBag), 'rooms' => null)) in 894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php (line 3)

now, I go to that page:

894e2bd7f138b5576c5cc3c1673cfa9dedca267b.php

(this is a the show.blade.php)
<?php $__env->startSection('content'); ?>

<h1 class="text-center"><?php echo e($rooms->title); ?></h1>
<div class="container" style="margin-bottom: 90px;">

So, it doesn't like line 3. That is where I first introduce $rooms and in fact, if I comment out everything below and including this, the page loads.

My question is, why does it not like $rooms?

Should I share $rooms in the AppServiceProvider?

(I have tried to do this previously, unsuccessfully.)

Bradley James Ahrens's avatar

Another weird thing is that I can view the edit.blade.php page, but cannot view the create.blade.php page. They are nearly identical, exept of course, I pull in data from the database to insert into the edit.blade.php page.

Snapey's avatar

is that part of the page in the view or in a master layout?

obviously $rooms is not set, so how should it get set?

1 like
kheengz's avatar

@almost_pitt

public function show($slug)
    {
    $rooms = Room::where('slug', $slug)->first();

        return view('rooms.show', compact('rooms'));
    }   

try this

1 like
Bradley James Ahrens's avatar

@Snapey , how do I set the variable $rooms? I thought I had set it in the roomscontroller. Take a look how I have my show function setup:

RoomsController.php

    public function show($slug)
    {
        return view('rooms.show')->with('rooms', Room::where('slug', $slug)->first());
    }
thomaskim's avatar

Looks like there is no room with that slug.

Change first() to firstOrFail() and I'm guessing you'll get the ModelNotFoundException.

1 like
Snapey's avatar

Do you have a scope on the model so that an authorised used only sees their own rooms?

1 like
Bradley James Ahrens's avatar

@Snapey , Good idea, but, no, I don't have any scope on the model so that an authorized user can only see his own rooms. In fact, I'd like everyone to be able to see all rooms.

Snapey's avatar

I get a different error

(1/2) ModelNotFoundException No query results for model [App\Room].

That was the point of changing it to find or fail. There is something wrong with your slug and the model that you want to edit is not found.

1 like
Bradley James Ahrens's avatar

@Snapey okay, okay, I like where you're going with this.

So, the questions are: what is wrong with the slug and how do the create and show pages interact?

Ideas:

Idea 1

The only connection from the RoomsController.php to the slug, other than creating it, is:

return redirect()->route('room', ['slug' => $room->slug]);

To see if this was the problem, I commented this out and replaced it with

return redirect()->route('/home');

Unfortunately, the problem persisted.

Idea 2

Since authorized users don't have access to the create route when show the show route is open to all users, maybe I should leave access to the $slug variable to all users as well.

I went to the AppServiceProvider.php to try to share this with all users:

        $slug = Room::all('slug');
        View::share('slug', $slug);

I'm not sure if that is the right syntax, but, again, unfortunately, that didn't work.

Idea 3

I also tried to pass the $slug into the store method in the RoomsController

public function store(Request $request, $slug)

This also had no effect.

Idea 4

So, the authorized users don't have access to the create route when show the show route is open to all users. However, the unauthorized users don't have access to the show route whenever it is in the Auth middleware. (Makes sense.)

Can I leave it open another way?

Within the RoomsController, I tried to give unauthorized users access to the show route by changing


    public function show($slug)
    {
        return view('rooms.show')->with('rooms', Room::where('slug', $slug)->first());
    }

to

    public function show($slug)
    {
        if(Auth::guest())
        {
            return view('rooms.show')->with('rooms', Room::where('slug', $slug)->first());
        }
        if(Auth::check())
        {
            return view('rooms.show')->with('rooms', Room::where('slug', $slug)->first());
        }
    }

Unfortunately, this also didn't work.

Snapey's avatar

I honestly don't know what you are trying to do here?

In your layout you are trying to display $rooms->title but you appear not to have set $rooms

You have not set $rooms because the slug that you passed to the Show method was not valid

So, where did you build the URL that lead you to the show method?

If you enter directly in the address bar /rooms/valid_slug_here what happens

Bradley James Ahrens's avatar
Level 20

@Snapey - > Sorry for the confusion. I was such an idiot!

I figured out the problem.

Here is how I had my web.php before

<?php

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

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

Route::get('{provider}/auth', [
  'uses' => 'SocialsController@auth',
  'as' => 'social.auth'
  ]);
Route::get('/{provider}/redirect', [
  'uses' => 'SocialsController@auth_callback',
  'as' => 'social.callback'
  ]);
Route::get('rooms/index', [
  'uses' => 'RoomsController@index',
  'as' => 'rooms.index'
  ]);
Route::get('rooms/{slug}', [
  'uses' => 'RoomsController@show',
  'as' => 'room'
  ]);

Route::group(['middleware'=>'auth'], function() {

  Route::get('rooms/create', [
    'uses' => 'RoomsController@create',
    'as' => 'rooms.create'
    ]);
  Route::post('rooms/store', [
    'uses' => 'RoomsController@store',
    'as' => 'rooms.store'
    ]);
  Route::get('rooms/edit/{slug}', [
    'uses' => 'RoomsController@edit',
    'as' => 'rooms.edit'
    ]);
  Route::put('rooms/update/{id}', [
    'uses' => 'RoomsController@update',
    'as' => 'rooms.update'
    ]);
  Route::delete('rooms/delete/{slug}', [
    'uses' => 'RoomsController@destroy',
    'as' => 'rooms.destroy'
    ]);
});

Notice how the rooms/{slug} is above rooms/create. Well, the problem with this is that it thinks that "create" is a slug and it can't find it in the database.

I figured this out by going to the RoomsController and putting in dd($slug); into the show function. When it told me "create" I found out what was the problem.

To fix this, I needed to not only put the show route at the bottom of the web.php file, but also outside of the auth middleware.

<?php

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

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

Route::get('{provider}/auth', [
  'uses' => 'SocialsController@auth',
  'as' => 'social.auth'
  ]);
Route::get('/{provider}/redirect', [
  'uses' => 'SocialsController@auth_callback',
  'as' => 'social.callback'
  ]);
Route::get('rooms/index', [
  'uses' => 'RoomsController@index',
  'as' => 'rooms.index'
  ]);

Route::group(['middleware'=>'auth'], function() {

  Route::get('rooms/create', [
    'uses' => 'RoomsController@create',
    'as' => 'rooms.create'
    ]);
  Route::post('rooms/store', [
    'uses' => 'RoomsController@store',
    'as' => 'rooms.store'
    ]);
  Route::get('rooms/edit/{slug}', [
    'uses' => 'RoomsController@edit',
    'as' => 'rooms.edit'
    ]);
  Route::put('rooms/update/{id}', [
    'uses' => 'RoomsController@update',
    'as' => 'rooms.update'
    ]);
  Route::delete('rooms/delete/{slug}', [
    'uses' => 'RoomsController@destroy',
    'as' => 'rooms.destroy'
    ]);
});

Route::get('rooms/{slug}', [
  'uses' => 'RoomsController@show',
  'as' => 'room'
  ]);

Now, everything is working! :)

Thanks again everyone who has spent the time to help me! I really appreciate your feedback and ideas.

And, sorry this was such a stupid mistake. It seems obvious now.

Thanks again,

Brad

Please or to participate in this conversation.