New to Laravel, be kind. :-)
I need to connect to a legacy database. I can not make changes to the structure or contents of that database, it is completely read-only.
Can I (and if so: how) create models so that I have "normalized" versions in my app?
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
- ...
I can use $hidden
, $casts
and e.g. public function getLabelAsStringAttribute() + $appends
to achieve some of it, but have not found a good / recommended way to :
- "rename" columns in the app (not the database), e.g.
my_title --> title
- only retrieve certain columns; I only need a small subset of fields from the large database; e.g. only retrieve
My_Title, Label
. - completely replace column content (e.g.
Label = 1 --> label = 'labelB'
)- related:
$append
adds it to->toArray()
, but not the collection objects themselves. That is indeed how it is documented, but I would like it to be part of the collection/model itself.
- related:
Would like this to work in Eloquent queries as well, e.g. App\Movie->where('title','Leon')
, where the request to the database should still be querying for My_Title
instead of title
.
I have the feeling I can use Collection method transform, but it is not clear to me when/where/how to always apply that one when performing a Eloquent query. And/or create a Custom Collection? Like this example, where I could create a method normalize
so that I can use \App\Movie->all()->normalize()->first()->title
? But that seems to be part of building the query (vs processing the returned DB data) and would still leave me with the unwanted behavior of using the raw DB columns when building a query, e.g. \App\Movie->where("My_Title","Leon")->normalize()->first()->title
.
Snippet of 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]
]);
// 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
Suggestions?
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire