雄辩友好的专栏名称

时间:2015-06-02 20:50:31

标签: eloquent laravel-5

我们目前正在从一个数据库转换到另一个数据库。我们的旧数据库中的表具有不太理想的列名,例如:

some_crazy_name__xyz

在我们的新数据库中,我们希望列名为:

someCrazyName

在短期内,我们必须使用旧数据库中的数据。在不久的将来的某个时刻,我们希望切换而不必重构所有的Eloquent代码来查询不同的列名。例如:

$model = MyModel::where('someCrazyName', '=', 1);

我目前正在扩展Model类,其中所有实现模型都为友好名称提供了可怕名称的映射:

class MyModel extends BaseModel {
    $columnMap = array(
        'someCrazyName' => 'some_crazy_name__xyz'
    );
}

我可以使用__get中的__setBaseModel来查找地图中的属性,例如:

$myModel = new MyModel;
// ...
echo $myModel->someCrazyName;

然而,这显然不适用于查询,而不必总是使用我的地图来查找列名。我想知道是否可以在不必覆盖处理列的Illuminate\Database\Eloquent\ModelIlluminate\Database\Query\BuilderIlluminate\Database\Eloquent\Builder中的所有方法,其中基础查询是内置始终映射到正确的列?然后,在我们转换数据库之后,我们可以删除那一段代码,而不是删除可能的数千个列名映射。

2 个答案:

答案 0 :(得分:1)

这就是您所需要的:it's own page in Wikipedia

不仅可以将badly_named_columns映射到something_useful,还可以用于relational mappings

// simple aliasing
User::where('cool_name', 'value') // where badName = ?

// relations, eg. User hasOne Profile
User::where('first_name', 'Jon') // search through related profiles table

// and obviously mutators:
$user->first_name == $user->profile->first_name

$user->cool_name = 'Jon' // becomes $user->badName = 'value'
$user->cool_name;  // 'Jon'

答案 1 :(得分:0)

实现目标的一种方法是使用accessors

例如,在MyModel中,您可以为some_crazy_name__xyz列定义一个访问者,如下所示:

public function getSomeCrazyNameAttribute()
{
    return $this->attributes['some_crazy_name__xyz'];
}

然后,您可以使用$mymodel->someCrazyName透明地引用该列。您还可以定义一个mutator来设置值。

不可否认,如果您有这样的许多值,这可能不是最佳解决方案。但它确实有一个重要的好处:稍后,如果您重构数据库以便实际调用some_crazy_name__xyzsomeCrazyName,那么您需要做的就是从模型中删除该函数。而且,至少在我看来,它比尝试覆盖所涉及的各种类的一堆方法更简单。

不幸的是,它没有充分解决在查询中使用列名的问题。为此,您可能需要查看repository pattern。但无论如何,看起来会涉及很多编码。

最后,您还没有提到您正在使用的数据库。如果是MySQL,则可以创建updatable and insertable views。使用视图,您可以简单地将旧列名称映射到new,并将您的Eloquent模型指向视图而不是表格。其他数据库服务器可能提供类似的功能。

相关问题