2015-10-13 151 views
1

通过构建股票投资组合应用程序学习Laravel。为用户,账户,股票,期权和交易提供模型。我相信我有正确的关系。Laravel 5.1查询关系

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

用户

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

最后,我想我要寻找每个总额帐户的用户可以拥有。 (用户可以有很多账户,每个账户都有很多交易,股票和期权。)

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

+1

好像查询生成器的方法是要走的路。否则,您将最终将每个“Transaction”对象加载到内存中,而您真正需要的只是每个帐户的总值。 – alexw

+0

我有点害怕。这个想法是让一个页面列出所有用户单独的账户和一个余额,然后点击账户打开列出所有交易的页面。同一个特定的股票。您可以看到一个用户的股票总量,然后按账户分割,然后在每个个人账户中分离涉及该股票的交易清单。 – BrioDev

回答

2

如果$user为用户对象,然后$user->accounts口若悬河车型

集合

您可以加载所有帐户以及它们与预先加载的交易:

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

$user->accounts->transactions是不是你可以这样做,因为“交易”是关于每个个人Account对象,而不是集合的帐户对象。

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

我强烈不建议这样做,因为@alexw在他的评论中提到的,雄辩的对象是相当大的,并且具有X多X许多是:通过这样每个账户获得的交易你会循环您要加载到内存中的指数级大量数据。但一般来说,这就是你如何获得关系的关系。

你最好不要使用查询生成器

的好消息是关系可以使查询很容易!例如,你可以做这样的事情,而不是:

注:在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; 
} 
+0

谢谢你们的帮助。我会采纳你的建议。你给出的最后一个例子返回了总数并向我展示了如何去做。只要我理解了这个过程,如果我要使用急切的加载示例,它是否只为该用户加载所有数据?或加载所有用户及其交易,然后过滤掉请求的用户。我的观点是,如果它只是返回一个用户,那么数据可能不会那么大,但如果它将所有用户放入内存中,那么就会将请求的用户抽出来,这肯定会很大。再次感谢你们! – BrioDev

+0

@BrioDev它只是加载该用户的数据。你说它“可能不是那么大”,但总是想到长期和边缘情况。也许从现在开始2年,*将*成为大量数据,即使只是一个用户。或者,也许你有一个用户谁做了一些淫秽的交易。 – andrewtweber

+0

绝对正确。非常感谢你。我的下一个山区是学习React,并将用它来更新价格和排序视图等等。我认为可能将所有数据发送给它,因为一个块可能是要走的路,然后让它将所有东西排除在外意见去了。更小的JSON我相信会更容易管理。还有很多东西要学习,很高兴知道有像你这样的人愿意帮助!非常感谢。 – BrioDev