问题
我想为一个模型属性设置访问器和更改器,但是使用通配符 我有为不同语言存储的属性,名为tags_en,tags_es,Tags_fr等。(8)语言标签
我想在Tag模型中为所有8种语言子类型 一次 设置一个访问者和一个mutator,而不是使用几个accessor / mutator方法对于他们每个人。
通常人们会为每个人做以下事情,例如: 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))
);
}
然后我必须为每种语言标记重复它们,这些标签目前只有8种不实用的语言。
我的目标
任何方式使用通配符做的访问器和变更器(当然这不起作用):
public function getTagsWildcardAttribute($tags){
return join(', ', json_decode($tags));
}
或
类似的东西:
foreach ($tagsAttributes as $TagAttribute){
//method building code for each tags language
}
类似的Laravel想法存在使用通配符验证
我假设可能有一种方法可以通过使用通配符的laravel Model类来实现。这类似于Validator,您可以在其中验证数组的每个元素:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
问题:
答案 0 :(得分:1)
您可以扩展castAttribute()
和setAttribute()
方法。
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);
}
答案 1 :(得分:1)
关于数据库的设置方式,我有点不清楚,但根据我的理解,它有一个包含tags_en
,tags_fr
,tags_de
等列的表格。
这是一个想法:
$casts
boot()
方法并使用它来设置creating
和updating
castAttribute($key, $value)
方法,并在检索时将其用于转换值(这将像访问者一样运行)它看起来像这样
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
protected static $tags = [
'tags_en',
'tags_fr',
'tags_de',
];
public static function boot()
{
static::creating(function ($model) {
foreach (static::$tags as $tag) {
// You can customize exactly what you need to do here
$model->$tag = json_encode($model->tag);
}
unset($model->tag);
});
static::updating(function ($model) {
foreach (static::$tags as $tag) {
// You can customize exactly what you need to do here
$model->$tag = json_encode($model->tag);
}
unset($model->tag);
});
parent::boot();
}
/**
* Cast an attribute to a native PHP type.
*
* @param string $key
* @param mixed $value
* @return mixed
*/
protected function castAttribute($key, $value)
{
if (in_array($key, static::$tags)) {
return join(', ', (array) json_decode($value));
}
parent::castAttribute($key, $value);
}
}
创建模型实例时:
$t = App\MyModel::create([
'name' => 'My Tags',
'tag' => ['key' => 'value', 'key2' => 'value2']
]);
然后当你检索一个实例时:
$t = App\MyModel::find($id);
echo $t->tags_en; // This will be handled by the `castAttribute($key, $value)` override
关于你的最后3个问题:如果你认为它应该被包括在内,那么最好的办法是a)通过GitHub回复询问甚至更好b)编码并放入PR。 Stack Overflow工作人员与Laravel无关,因此他们不能也不会,也无法做任何事情。
答案 2 :(得分:0)
有一个解决方案,口才突变者 https://github.com/topclaudy/eloquent-mutators
安装软件包后,您将能够为Eloquent模型注册自定义访问器/更改器扩展。