Laravel - 扩展模型

时间:2015-11-07 07:31:12

标签: laravel inheritance eloquent extending-classes

我创建了一个BaseModel类,它从Model扩展而来。似乎一切都运转良好,但现在我在保存时遇到了问题。我重写了这个BaseModel中的save()方法。我想在保存之前向模型添加一些属性。所以我这样做,然后拨打return parent::save($options);。方法签名仍然相同:public function save(array $options = [])

在执行插入时(它使用base_models作为表名),它似乎抓取了表名的BaseModel类的名称,而不是正在保存的实际模型。有没有人遇到过这个?从模型类扩展的正确方法是什么?

我最初创建了一些特性来处理一些额外的功能,但我认为最好只创建一个基础模型并让我的模型从中扩展出来。

3 个答案:

答案 0 :(得分:2)

在您的模型中(扩展基本模型的子模型)明确添加表名称,例如:

class SomeChildModel extends BaseModel {

    // Manually set the table name
    protected $table = 'table_name';

}

答案 1 :(得分:0)

我意识到我以前有一个静态方法,它使用new self()创建自己的实例,并且在我使用trait中的方法时会设置一些属性。以前很好,但是现在因为我将方法移动到基本模型中,该方法实际上是在基本模型本身上调用而不是具有特征的类。

我基本上使用静态方法来实例化类,因为我已经读过它是避免构造函数混乱的一种方法。但是这次我只是选择在构造函数中执行它,因为它是有意义的,所以这是我的解决方案。

答案 2 :(得分:0)

如果没有设置save实例变量,Laravel将默认使用类名称的蛇案例(调用$table方法的类)。在您的情况下,它将使用BaseModel的蛇案例作为表名。你有两个解决方案:

解决方案1:

在扩展BaseModel的类中添加$table实例变量,如下所示:

class User extends BaseModel {
    protected $table = 'table_name'; // Your table name in the database;
}

解决方案2:

您可以使用Laravel Eloquent's Events,这可以让您了解模型生命周期中的各个点。

您可以按照以下方式挂钩save方法并进行更改。您可以在BaseClass特征等中使用这些方法。例如,在BaseModel中:

class BaseModel extends Model
{
    /**
     * Listen for save event
     */
    protected static function boot()
    {
        parent::boot();

        static::saving(function($model)
        {
            if ( ! $model->isValid()) {
                return false;
            }
        });
    }
}

在将模型保存到存储中之前,上述内容始终会调用isValid。在这种情况下,它将返回false并且不会保存对象。

有关详细信息,请参阅此处的官方docs。如果不清楚,请告诉我。