Ad

Laravel - Make Throw Exception When Trying To Access Attribute Which Is Not In Select

- 1 answer

For example a model has a lot of attributes, but in select I specify only a few.

$listings = Realty::select('city', 'mls', 'class_id')->get();

How to make a trait (prefebable) or class inherits Eloquent which will throw exception if I try to access attribute which was not in select:

$propertyType = $listings[0]->property_type; // returns `null`, but I need 
                                             // RuntimeException or ErrorException
Ad

Answer

When you try to read a property of Eloquent object, Eloquent tries to read that value from different places in following order:

  • attributes fetched from the database
  • dynamic attribute getters
  • relations

Therefore if you want to get an exception when you try to access an attribute that does not exist in any of the above, you'd need to override the last part - getRelationValue method in your model:

public function getRelationValue($key)
{
    if ($this->relationLoaded($key)) {
        return $this->relations[$key];
    }

    if (method_exists($this, $key)) {
        return $this->getRelationshipFromMethod($key);
    }

    throw new \Exception;
}

Keep in mind that this is not future-proof. If future versions of Eloquent change how fetching attributes is implemented, implementation of above method might need to be updated.

UPDATE for Laravel 5.0

In Laravel 5.0 it should be enough to overwrite getAttribute method in Eloquent model:

public function getAttribute($key)
{
    $inAttributes = array_key_exists($key, $this->attributes);
    if ($inAttributes || $this->hasGetMutator($key))
    {
        return $this->getAttributeValue($key);
    }

    if (array_key_exists($key, $this->relations))
    {
        return $this->relations[$key];
    }

    if (method_exists($this, $key))
    {
        return $this->getRelationshipFromMethod($key);
    }

    throw new \Exception;
}
Ad
source: stackoverflow.com
Ad