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

mtp*_*ltz 1 laravel laravel-5.6

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

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

例如,Model::table如果表名不遵循约定,则类似于如何设置表名 ( ):

例子

private $columns = [
    // convention => actual
    'first_name' => 'first',
    'last_name' => 'last',
    'mobile_phone' => 'phone',
    'home_phone' => 'otherPhone', // seriously!?
];
Run Code Online (Sandbox Code Playgroud)

我已经研究过Model这个HasAttributes特征,但我仍然希望这可能存在,或者有人找到了一种方法来做到这一点作为临时解决方案。

Jon*_*eir 5

您可以为所有模型创建一个父类:

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

$columns然后在你的模型中覆盖:

protected $columns = [
    'first_name' => 'first',
    'last_name' => 'last',
    'mobile_phone' => 'phone',
    'home_phone' => 'otherPhone',
];
Run Code Online (Sandbox Code Playgroud)