The issue
I would like to set accessors and mutators for one model attribute but with wildcards I have attribute stored for different languages called tags_en, tags_es, Tags_fr, etc.. for (8) language tags
I would like to set one accessor and one mutator in the Tag model for all of the 8 language sub-types once instead of using couple of accessor/mutator method for each of them.
Normally one would do the following for each of them e.g. tags_en
public function getTagsEnAttribute($tags){
return join(', ', json_decode($tags));
}
public function setTagsEnAttribute($tags){
$this->attributes['tags_en'] =
json_encode(
array_map('trim', explode(',', $tags))
);
}
Then I have to repeat them for each language variety of tags which are at the moment 8 languages which is not practical.
My Objective
Any way to do accessors and mutators with a wildcard something like (which of course do not work this way):
public function getTagsWildcardAttribute($tags){
return join(', ', json_decode($tags));
}
or
something like:
foreach ($tagsAttributes as $TagAttribute){
//method building code for each tags language
}
Similar Laravel idea exists for Validation with wildcard
I assume that there may be a way to do it through laravel Model class using wildcard. This is similar to Validator where you can validate each element of an array like this:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Questions:
You could extend castAttribute()
and setAttribute()
methods.
protected function castAttribute($key, $value) {
if (is_null($value)) {
return $value;
}
if ($this->isTagCastable($key)) {
return join(', ', json_decode($value));
}
return parent::castAttribute($key, $value);
}
public function setAttribute($key, $value)
{
if ($this->isTagCastable($key)) {
$this->attributes[$key] =
json_encode(
array_map('trim', explode(',', $value))
);
}
return parent::setAttribute($key, $value);
}
protected function isTagCastable($key) {
return preg_match('/tags_[a-z]{2}/', $key);
}