laravel transform /规范化从遗留DB接收的列+值

时间:2018-02-05 12:01:02

标签: laravel-5 eloquent

Laravel的新手,善待。 :-)

我需要连接到旧数据库。我无法更改该数据库的结构或内容,它是完全只读的 我可以(如果是这样的话)创建模型,以便在我的应用程序中使用“标准化”版本吗?

E.g。

table 1:
  DB column           app model
  ---------------     -----------------------
- My_Title            title
- Some_Field1..10     (should not be retrieved)
- Label (int: 0,1,2)  label, lookup string from array ["labelA","labelB","labelC"]

table 2:
  DB column           app model
  ---------------     -----------------------
- The_Title           title
- ...

我可以使用$hidden$casts,例如public function getLabelAsStringAttribute() + $appends要实现其中的一部分,但尚未找到好的/推荐的方式:

  • 在应用程序(不是数据库)中“重命名”列,例如my_title --> title
  • 仅检索某些列;我只需要大型数据库中的一小部分字段;例如只检索My_Title, Label
  • 完全替换列内容(例如Label = 1 --> label = 'labelB'
    • 相关:$append将其添加到->toArray(),但不会将其添加到集合对象本身。确实如此documented,但我希望它成为集合/模型本身的一部分。

希望这也适用于Eloquent查询,例如App\Movie->where('title','Leon'),其中对数据库的请求仍应查询My_Title而不是title

我觉得我可以使用Collection method transform,但我不清楚在执行Eloquent查询时何时/何地/如何始终应用那个。{和/或创建一个Custom CollectionLike this example,我可以在哪里创建方法normalize,以便我可以使用\App\Movie->all()->normalize()->first()->title?但这似乎是构建查询(vs处理返回的数据库数据)的一部分,并且在构建查询时仍然会留下使用原始数据库列的不必要行为,例如: \App\Movie->where("My_Title","Leon")->normalize()->first()->title

WIP的片段:

// todo: enable e.g. 
// App\Movie->whereIn('label',['labelB','labelC'])
// which internally treats it as 
// App\Movie->whereIn('Label',[1,2])

// example of the final result of the query, with raw DB columns+values
// todo: don't even receive the unwanted columns, only receive "The_Title" and "Label"
$collection = collect([
    (Object) ["The_Title"=>"Leon","Some_Field1"=>"ignore me", "Some_Field2"=>"ignore me as well","Label"=>1],
    (Object) ["The_Title"=>"Dunkirk","Some_Field1"=>"ignore me","Label"=>2]
]);

// todo: for every collection: 
// after data is loaded, transform it to a normalized version of the model
$collection->transform(function ($item, $key) { 
    return (Object) [
        "title"=>$item->The_Title, 
        "label"=>["labelA","labelB","labelC"][$item->Label]
    ]; 
})

// after that it is possible to treat it as a regular collection
$collection->first()->title

建议?

0 个答案:

没有答案