skip to Main Content

EDIT: Problem solved by adding local key in the model relation.


Question:

I am trying to use a property from model relationship {{$item->items->item_name}}, but it says Attempt to read property "item_name" on null.

However, when I am trying to {{dd($item->items->item_name)}} it returns a string "Old Boots.

Why does it happen? The value is definitely there but I cant echo it…

UserItems table: id | user_id | item_id

UserItem Model:

<?php

namespace AppModels;

use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;

class UserItem extends Model
{
    use HasFactory;

    public function items()
    {
        return $this->hasOne(Item::class, 'id');
    }
}

Item table structure: id | item_name

Item Model:

<?php

namespace AppModels;

use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;

class Item extends Model
{
    use HasFactory;
}

Controller function:

public function heroView() :View
{
    return view('hero', [
        'userItems' => UserItem::with('items')->where('user_id', Auth::id())->get()
    ]);
}

View:

        <table>
            @foreach ($userItems as $item)
            <tr>
                <td>{{$item->items->item_name}}</td>
            </tr>
            @endforeach
        </table>

In view {{dd($item)}}:

enter image description here

3

Answers


  1. Chosen as BEST ANSWER

    I finally made it work. There was local key missing in the model.

    <?php
    
    namespace AppModels;
    
    use IlluminateDatabaseEloquentFactoriesHasFactory;
    use IlluminateDatabaseEloquentModel;
    
    class UserItem extends Model
    {
        use HasFactory;
    
        public function items()
        {
            return $this->hasOne(Item::class, 'id', 'item_id');
        }
    }
    

  2. You did not show your db, so I am just guessing with the data you shared here.
    First of all if there is one item for each user item, you need to change items name to "item".

    And there is something else too. You need to set inverse relationship to. I mean you have to add this to your item model. If it’s a one to one relationship read this for learning about inverse relationships.

    One to one inverse relationship(laravel document)

    And at last, please remove "with" method. You do not need it laravel will figure out the relationship by itself.

    Said all the possibilities. Hope to be helpful <3

    Login or Signup to reply.
  3. most likely reason is that one of your userItem does not have an item.

    dd appears to work because it stops on the first iteration of the loop, but your missing item could be missing from userItem 4 for instance.

    Whenever I use an arrow twice when accessing a relationship, I always code defensively and put in a null-coalesce operator to catch the situation where a relation is missing.

    So you could prove this with code like;

        <table>
          @foreach ($userItems as $item)
            <tr>
              <td>{{$item->items->item_name ?? "no item"}}</td>
            </tr>
          @endforeach
         </table>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search