从一对多 table 关系中获取特定字段与 laravel eloquent?

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

我有 table 喜欢下面的图片:

所以,用户有很多 balance_transactions,最后插入的 balance_transactions 记录将是用户帐户余额。我的问题是,如何使 user model 具有 属性 account_balance 且值最后插入 total in balance_transactions table

我曾尝试在用户模型中使用类似的东西

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

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

我得到这样的数据

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

结果如下 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"
      }
   ]
}

但我想要的是 return 应该像下面这样 json:

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

我的问题,如何以 laravel eloquent 正确的方式制作类似的东西?所以我只能使用像 $user = user::find(1);.

这样的简单代码来获取 account_balance 数据

提前致谢

解决这个问题的一种方法是,您可以使用 laravel Accessors

所以在你的用户模型中你可以创建一个方法如下

/**
 * Get the user's balance.
 *
 * @return float
 */
public function getAccountBalanceAttribute()
{
    return $this->balance->last()->total;
}

那么无论你想在哪里使用它,你都可以通过以下方式使用它: $用户->account_balance;

我建议只从您的事务中加载一行 table 并着眼于性能。此外,您可以将访问器的值附加到模型的序列化输出(例如 __toArray()),并且仅当关系已经加载时 return 才是实际值。

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;
    }
}