如何正确使用 "Base model" 和 Laravel 来扩展 getAttribute()?

How can I correctly use a "Base model" with Laravel to extend getAttribute()?

我试图找到一个地方来在返回字段时添加一些全局行为,而不是为所有模型中的所有字段定义访问器。

这促使我尝试创建一个扩展 getAttribute()BaseModel class。我的印象是在查询模型时应该为每个字段调用它。但是,似乎只有在请求特定字段时才会调用它。

有人可以帮助我理解 getAttribute() 以及为什么在下面的第一个示例中没有调用它吗?也许还有一个更好的地方来定义某种我不知道的 "global accessor" 行为。谢谢!

示例模型:

class Thingy extends BaseModel {

}

基础模型:

class BaseModel extends Eloquent {
  public function getAttribute($key) {
    Log::alert($key);

    parent::getAttribute($key);
  }   
}

结果:

return Thingy::find(1);  // Returns all fields, but does not hit getAttribute()

return Thingy::find(1)->title  // Returns and logs only title

getAttribute() 将在您访问 属性:

时调用
$model->title;

当您只是 return 来自控制器的模型时,它将被转换为 JSON。这通过在模型上调用 toArray() 来实现。这不会调用 getAttribute() 而是稍后直接访问 $attributes 数组。


基本上对于此类类型转换(tinyint 到布尔值,null 到空字符串)您可以使用两种方法 getAttribute()toArray().

toArray() 如果您使用 JSON 将数据发送到客户端,getAttribute 如果您将模型传递到服务器端视图。 (如果你两者都做,那么你需要两种方法)

public function toArray(){
    $array = parent::toArray();
    foreach($array as $attribute){
        // conversions
    }
    return $array;
}

public function getAttribute($key){
    $attribute = parent::getAttribute($key);
    // conversions
    return $attribute;
}