Short answer
$model->relation()
returns the relationship object
$model->relation
returns the result of the relationship
Long answer
$model->relation()
can be explained pretty simple. You're calling the actual function you defined your relation with. Yours for distributor
probably looks somewhat like this:
public function distributors(){
return $this->hasMany('Distributor');
}
So when calling $store->distributors()
you just get the return value of $this->hasMany('Distributor')
which is an instance of IlluminateDatabaseEloquentRelationsHasMany
When do you use it?
You usually would call the relationship function if you want to further specify the query before you run it. For example add a where statement:
$distributors = $store->distributors()->where('priority', '>', 4)->get();
Of course you can also just do this: $store->distributors()->get()
but that has the same result as $store->distributors
.
Which brings me to the explanation of the dynamic relationship property.
Laravel does some things under the hood to allow you to directly access the results of a relationship as property. Like: $model->relation
.
Here's what happens in IlluminateDatabaseEloquentModel
1) The properties don't actually exist. So if you access $store->distributors
the call will be proxied to __get()
2) This method then calls getAttribute
with the property name getAttribute('distributors')
public function __get($key)
{
return $this->getAttribute($key);
}
3) In getAttribute
it checks if the relationship is already loaded (exists in relations
). If not and if a relationship method exists it will load the relation (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) In the end Laravel calls getResults()
on the relation which then results in a get()
on the query builder instance. (And that gives the same result as $model->relation()->get()
.