Laravel 使用适当的约定将数据库列名称映射到模型中的实际数据库列名称

Laravel Map DB Column Names Using Proper Convention to Actual DB Column Names in Model

作为第一步,我们正在构建一个门户来替换现有应用程序的一部分,但数据库架构完全没有任何约定。除了缺少任何约束、索引等之外,列的名称不是描述性的,也不是蛇形的。

是否可以映射数据库 table 列名,以便门户使用正确的描述性和蛇形列名,如 first_name 但写入实际数据库列 first 到至少门户网站是清理技术债务的第一步?

例如,如果 table 名称不符合约定,则类似于 table 名称 (Model::table) 的设置方式:

例子

private $columns = [
    // convention => actual
    'first_name' => 'first',
    'last_name' => 'last',
    'mobile_phone' => 'phone',
    'home_phone' => 'otherPhone', // seriously!?
];

我已经查看了 ModelHasAttributes 特征,但我仍然希望这可能存在,或者有人找到了一种临时解决方案。

正确的方法是使用accessors and mutators

定义访问器

public function getFirstNameAttribute() {
    return $this->first;
}

然后,您可以通过$model->first_name访问该值。

定义 Mutator

public function setFirstNameAttribute($value) {
    $this->attributes['first'] = $value;
}

然后,您可以改变值,例如:

$model->first_name = 'first_name';
$model->save();

您可以为所有模型创建父项 class:

abstract class Model extends \Illuminate\Database\Eloquent\Model {

    protected $columns = [];

    public function attributesToArray()
    {
        $attributes = parent::attributesToArray();
        foreach ($this->columns as $convention => $actual) {
            if (array_key_exists($actual, $attributes)) {
                $attributes[$convention] = $attributes[$actual];
                unset($attributes[$actual]);
            }
        }
        return $attributes;
    }

    public function getAttribute($key)
    {
        if (array_key_exists($key, $this->columns)) {
            $key = $this->columns[$key];
        }
        return parent::getAttributeValue($key);
    }

    public function setAttribute($key, $value)
    {
        if (array_key_exists($key, $this->columns)) {
            $key = $this->columns[$key];
        }
        return parent::setAttribute($key, $value);
    }

}

然后在您的模型中覆盖 $columns

protected $columns = [
    'first_name' => 'first',
    'last_name' => 'last',
    'mobile_phone' => 'phone',
    'home_phone' => 'otherPhone',
];