我们目前正在从一个数据库转换到另一个数据库。我们的旧数据库中的表具有不太理想的列名,例如:
some_crazy_name__xyz
在我们的新数据库中,我们希望列名为:
someCrazyName
在短期内,我们必须使用旧数据库中的数据。在不久的将来的某个时刻,我们希望切换而不必重构所有的Eloquent代码来查询不同的列名。例如:
$model = MyModel::where('someCrazyName', '=', 1);
我目前正在扩展Model类,其中所有实现模型都为友好名称提供了可怕名称的映射:
class MyModel extends BaseModel {
$columnMap = array(
'someCrazyName' => 'some_crazy_name__xyz'
);
}
我可以使用__get
中的__set
和BaseModel
来查找地图中的属性,例如:
$myModel = new MyModel;
// ...
echo $myModel->someCrazyName;
然而,这显然不适用于查询,而不必总是使用我的地图来查找列名。我想知道是否可以在不必覆盖处理列的Illuminate\Database\Eloquent\Model
,Illuminate\Database\Query\Builder
和Illuminate\Database\Eloquent\Builder
中的所有方法,其中基础查询是内置始终映射到正确的列?然后,在我们转换数据库之后,我们可以删除那一段代码,而不是删除可能的数千个列名映射。
答案 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__xyz
列someCrazyName
,那么您需要做的就是从模型中删除该函数。而且,至少在我看来,它比尝试覆盖所涉及的各种类的一堆方法更简单。
不幸的是,它没有充分解决在查询中使用列名的问题。为此,您可能需要查看repository pattern。但无论如何,看起来会涉及很多编码。
最后,您还没有提到您正在使用的数据库。如果是MySQL,则可以创建updatable and insertable views。使用视图,您可以简单地将旧列名称映射到new,并将您的Eloquent模型指向视图而不是表格。其他数据库服务器可能提供类似的功能。