【问题标题】:Laravel 5.1 Querying RelationshipLaravel 5.1 查询关系
【发布时间】:2015-10-13 23:42:18
【问题描述】:

通过构建股票投资组合应用来学习 Laravel。拥有用户、账户、股票、期权和交易的模型。我相信我已经正确建立了关系。

问题是我如何获得用户->帐户->交易。我确信我可以在查询生成器中做一些事情,但我希望有一种更“雄辩”的方法。

用户

public function accounts()
{
    return $this->hasMany('App\Account');
}

public function stocks()
{
    return $this->belongsToMany('App\Stock');
}

public function options()
{
    return $this->belongsToMany('App\Option');
}

public function transactions()
{
    return $this->hasMany('App\Transaction');
}

帐户

class Account extends Model
{
    protected $fillable = 
    [
        'name',
        'broker'

    ];

    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function stocks()
    {
        return $this->belongsToMany('App\Stock');
    }

    public function options()
    {
        return $this->belongsToMany('App\Option');
    }

    public function transactions()
    {
        return $this->hasMany('App\Transaction');
    }

交易

class Transaction extends Model
{
    protected $fillable = 
    [
        'type',
        'account_id',
        'transaction_date',
        'quantity',
        'stock_id',
        'option_id',
        'amount',
        'description'

    ];


    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function stock()
    {
        return $this->belongsTo('App\Stock');
    }

    public function option()
    {
        return $this->belongsTo('App\Option');
    }

    public function account()
    {
        return $this->belongsTo('App\Account');
    }

    public function accounts()
    {
        return $this->hasManyThrough('App\Account', 'App\User');
    }
}

最终,我想我会寻找用户可能拥有的每个帐户的总金额。 (用户可以有很多账户,每个账户会有很多交易、股票和期权。)

感谢您的帮助,或者至少让我知道我是否走在正确的道路上!!

【问题讨论】:

  • 查询构建器方法似乎是要走的路。否则,您最终会将每个 Transaction 对象加载到内存中,而您真正需要的只是每个帐户的聚合值。
  • 我有点害怕。这个想法是有一个页面列出所有用户的单独帐户和余额,然后单击该帐户以打开一个列出所有交易的页面。对于特定的股票也是如此。您可以看到一个用户的股票总量,然后按账户拆分,然后在每个单独的账户中列出涉及该股票的交易列表。

标签: laravel eloquent relationships


【解决方案1】:

如果$user 是一个用户对象,那么$user->accounts 是一个 Eloquent 模型的集合

您可以通过预先加载来加载所有帐户及其交易:

$user->load([
    'accounts',
    'accounts.transactions',
]);

但是$user->accounts->transactions 不是您可以做的事情,因为“交易”是每个个人 Account 对象的关系,而不是帐户对象的集合 .因此,要获取您需要遍历每个帐户的交易:

foreach ($user->accounts as $account) {
    // do something with $account->transactions;
}

我强烈不建议这样做,正如@alexw 在他的评论中提到的那样,Eloquent 对象非常大,并且拥有 x many x many 是您加载到内存中的指数级大量数据。但一般来说,这就是您访问关系关系的方式。

最好使用查询生成器

好消息是关系可以使查询变得非常容易!例如,您可以这样做:

注意:在 Laravel 5.2 中,lists 方法已被替换为 pluck

$user->load(['accounts']);

foreach ($user->accounts as $account) {
    $amounts = $account->transactions()->lists('amount');
    $total = $amounts->sum();

    // - or -

    $query = $account->transactions()
        ->select(\DB::raw('SUM(amount) AS total'))
        ->first();
    $total = $query->total;
}

【讨论】:

  • 感谢两位的帮助。我会接受你的建议。你给出的最后一个例子返回了一个总数,并向我展示了如何 .只是为了让我理解这个过程,如果我要使用急切加载示例,它是否只为该用户加载所有数据?或加载所有用户及其交易,然后过滤掉请求的用户。我的观点是,如果它只返回一个用户,那么数据可能不会那么大,但是如果它将所有用户都放入内存中,那么它就会拉出请求的用户,这肯定是巨大的。再次感谢你们!
  • @BrioDev 它只是为那个用户加载数据。你说它“可能没有那么大”,但总是考虑长期和边缘情况。也许 2 年后 将是大量数据,即使只是针对一个用户。或者,也许您的用户进行了大量交易。
  • 完全正确。非常感谢你。我的下一座山是学习 React,并打算用它来更新价格和排序视图等。我想也许将所有数据作为一个块发送给它可能是要走的路,然后让它把所有东西都整理好意见去。我敢肯定,较小的 JSON 会更容易管理。还有很多东西要学,很高兴知道有像你这样的人愿意提供帮助!非常感谢。
  • 不客气。除了接受我的回答之外,如果你也给我投票那就太好了:)
猜你喜欢
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 1970-01-01
  • 2016-01-02
  • 1970-01-01
相关资源
最近更新 更多