Eloquent Relation isset() always return false

Published 1 year ago by yohang

Hi. I got something weird with my code below.

Code:
dd($user->deposit);

Result:
App\Entities\Deposit {#1880
  #fillable: array:3 [
    0 => "user_id"
    1 => "balance"
    2 => "balance_available"
  ]
  #connection: null
  #table: null
  #primaryKey: "id"
  #perPage: 15
  +incrementing: true
  +timestamps: true
  #attributes: array:6 [
    "id" => 5
    "user_id" => 1
    "balance" => "16600153.00"
    "balance_available" => "16600153.00"
    "created_at" => "2016-05-03 10:36:04"
    "updated_at" => "2016-05-05 10:11:32"
  ]
  #original: array:6 [
    "id" => 5
    "user_id" => 1
    "balance" => "16600153.00"
    "balance_available" => "16600153.00"
    "created_at" => "2016-05-03 10:36:04"
    "updated_at" => "2016-05-05 10:11:32"
  ]
  #relations: []
  #hidden: []
  #visible: []
  #appends: []
  #guarded: array:1 [
    0 => "*"
  ]
  #dates: []
  #dateFormat: null
  #casts: []
  #touches: []
  #observables: []
  #with: []
  #morphClass: null
  +exists: true
  +wasRecentlyCreated: false
}
Code:
dd(isset($user->deposit));

Result:
false

Question: Why isset() always gave me false return?

PHP 7.0.6 (cli) (built: Apr 29 2016 04:21:39) ( NTS )
Laravel Framework version 5.2.29
kfirba
kfirba
1 year ago (210,265 XP)

@yohang hey.

That's happening because laravel uses magic method __call to determine what to do in case of someone accessing an attribute that doesn't exist. Think about it, did you add a deposit attribute to your model? You didn't. You've only added a deposit() method to your model.

Laravel is smart enough to know that when you are accessing the depposit variable you want to get the relationship. Behind the scenes it converts your call to something like:

$model->deposit()->get();

Anyways, the reason you get false is because there is no such an attribute deposit on the model.

Even after loading the relationship once, accessing the attribute will just fetch is from a cached version stored on the object and if you check there again whether the variable is set or not, you will get false again, as the cached data is stored under a global relationship array ($relations) on the model.

To check if your relationship is loaded you can use the relationLoaded method:

$this->relationLoaded('deposit'h;

Please sign in or create an account to participate in this conversation.