Search code examples
laraveleloquentone-to-manylaravel-6eloquent-relationship

Get specific field from one to many table relationship with laravel eloquent?


I have table like this following image: enter image description here

so, user have many balance_transactions and last inserted balance_transactions record will be user account balance. my question, how to make user model have property account_balance with value last inserted total in balance_transactions table

I was tried using something like this in user model

public function balance {
    return $this->hasMany(App\BalanceTransaction::class);
}

public function account_balance {
    return $this->balance()->orderBy('id', 'DESC')->limit(1);
}

And I get the data like this

$user = User::where('id', 1)->with('account_balance')->first();
return response()->json($user);

and the result look like this folowing json:

{
   "id": 1,
   "username": "john0131",
   "full_name": "john doe",
   "email": john@test.com,
   "account_balance": [
      {
          "id": 234,
          "user_id": 1,
          "total": 7850
          "added_value": 50
          "created_date": "2020-02-28 12:18:18"
      }
   ]
}

but what I want, the return should be like this following json:

{
   "id": 1,
   "username": "john0131",
   "full_name": "john doe",
   "email": "john@test.com",
   "account_balance": 7850
}

my question, how to make something like that in laravel eloquent proper way? so I can get account_balance data only with simple code like $user = user::find(1);.

Thanks in advance


Solution

  • I would suggest loading only one row from your transaction table with an eye on performance. Additionally you can append the value of the accessor to the serialised output of the model (e.g. __toArray()) and return the acutal value only if the relationship has already been loaded.

    class User extends Authenticatable
    {
        protected $appends = ['account_balance'];
    
        public function balance()
        {
            return $this->hasMany(App\BalanceTransaction::class);
        }
    
        public function latestBalance()
        {
            return $this
                ->hasOne(App\BalanceTransaction::class)
                ->latest();
        }
    
        public function getAcountBalanceAttribute()
        {
            if (! $this->relationLoaded('latestBalance')) {
                return null;
            }
    
            return $this->latestBalance->total;
        }
    }