我缺少一些基本的理解/理论,我不理解这些函数调用之间的区别:
$distributors = $store->distributors(); $distributors = $store->distributors; $distributors = $store->distributors()->get(); $distributors = $store->distributors->get();
我在这里想要做到的是获取一家商店的分销商列表(多对多关系),并且他们将每个啤酒分销商列表都整合到一个巨型列表中。
foreach ($distributors as $distributor) { $available_beers = array_merge($distributor->beers(), $available_beers); }
我不知道这是否是执行此操作的最佳方法,但我无法使其正常工作。与第一批方法类似,我不知道是否需要->$beers或->$beers()
->$beers
->$beers()
更新资料
感谢所有回答!这将是我前进的良好参考。我最大的教训是取回集合与取回查询构建器/关系对象之间的区别。为了将来向发现此问题的人员提供参考,以下是我在控制器中设置的内容:
$store = $this->store->find($id)->first(); $distributors = $store->distributors; $beers = []; foreach ($distributors as $distributor){ $beers = array_merge($distributor->beers->lists('name', 'id'), $beers); }
$model->relation()返回 关系对象
$model->relation()
$model->relation返回关系的 结果
$model->relation
$model->relation()可以解释得很简单。您正在调用定义关系的实际函数。您的for distributor可能看起来像这样:
distributor
public function distributors(){ return $this->hasMany('Distributor'); }
因此,在调用时,$store->distributors()您仅获得其返回值$this->hasMany('Distributor')是的一个实例Illuminate\Database\Eloquent\Relations\HasMany
$store->distributors()
$this->hasMany('Distributor')
Illuminate\Database\Eloquent\Relations\HasMany
什么时候使用?
如果要在运行查询之前进一步指定查询,通常会调用关系函数。例如,添加一个where语句:
$distributors = $store->distributors()->where('priority', '>', 4)->get();
当然,您也可以这样做:$store->distributors()->get()但这与的结果相同$store->distributors。
$store->distributors()->get()
$store->distributors
这使我对 动态关系属性 进行了解释。
Laravel在幕后做了一些事情,使您可以直接访问关系的结果作为属性。像:$model->relation。
这是发生在 Illuminate\Database\Eloquent\Model
Illuminate\Database\Eloquent\Model
1) 这些属性实际上不存在。因此,如果您访问$store->distributors该电话,它将被代理到__get()
__get()
2) 然后此方法getAttribute使用属性名称进行调用getAttribute('distributors')
getAttribute
getAttribute('distributors')
public function __get($key) { return $this->getAttribute($key); }
3) 在getAttribute其中检查该关系是否已经加载(存在于中relations)。如果不存在并且存在关系方法,它将加载关系(getRelationshipFromMethod)
relations
getRelationshipFromMethod
public function getAttribute($key) { // code omitted for brevity if (array_key_exists($key, $this->relations)) { return $this->relations[$key]; } $camelKey = camel_case($key); if (method_exists($this, $camelKey)) { return $this->getRelationshipFromMethod($key, $camelKey); } }
4) 最后,Laravel调用getResults()该关系,然后在get()查询生成器实例上产生a 。(结果与相同$model->relation()->get()。
getResults()
get()
$model->relation()->get()