Laravel 带通配符 (*) 的模型访问器和修改器
Laravel Model Accessor and Mutator with wildcard (*)
问题
我想为一个模型属性设置访问器和修改器,但要使用通配符
我为不同的语言存储了属性,称为 tags_en、tags_es、Tags_fr 等。对于 (8) 语言标签
我想在 Tag 模型中为所有 8 种语言子类型设置一个访问器和一个修改器 once对每个方法使用一对 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 种语言,这是不实用的。
我的Objective
使用类似通配符的访问器和修改器的任何方式(当然不能这样工作):
public function getTagsWildcardAttribute($tags){
return join(', ', json_decode($tags));
}
或
类似于:
foreach ($tagsAttributes as $TagAttribute){
//method building code for each tags language
}
存在类似的 Laravel 验证通配符的想法
我认为可能有一种方法可以通过使用通配符的 laravel 模型 class 来完成。这类似于 Validator,您可以在其中验证数组的每个元素,如下所示:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
问题:
- 如果这些模型 带有通配符 的访问器和修改器在当前 laravel 框架中不可用 - 您是否同意我认为这值得在下一个 laravel 版本中 添加 吗?
- 如果是这样,那么 如何正式要求 laravel 制造商在即将发布的版本中考虑这一点?
- Whosebug 工作人员能否代表我们向 laravel 构建者提出改进(如果他们看到了)?
您可以扩展 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);
}
我不太清楚你的数据库是如何设置的,但据我了解,它有一个 table,其中的列名为 tags_en
、tags_fr
、tags_de
,等等
这是一个想法:
- 添加一个 属性 来保存您想要 set/get
的列
- 在
$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 无关,因此他们不能也不会也不会做任何事情。
有一个解决方案,Eloquent Mutators https://github.com/topclaudy/eloquent-mutators
安装包后,您将能够为您的 Eloquent 模型注册自定义 accessors/mutators 扩展。
问题
我想为一个模型属性设置访问器和修改器,但要使用通配符 我为不同的语言存储了属性,称为 tags_en、tags_es、Tags_fr 等。对于 (8) 语言标签
我想在 Tag 模型中为所有 8 种语言子类型设置一个访问器和一个修改器 once对每个方法使用一对 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 种语言,这是不实用的。
我的Objective
使用类似通配符的访问器和修改器的任何方式(当然不能这样工作):
public function getTagsWildcardAttribute($tags){
return join(', ', json_decode($tags));
}
或
类似于:
foreach ($tagsAttributes as $TagAttribute){
//method building code for each tags language
}
存在类似的 Laravel 验证通配符的想法
我认为可能有一种方法可以通过使用通配符的 laravel 模型 class 来完成。这类似于 Validator,您可以在其中验证数组的每个元素,如下所示:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
问题:
- 如果这些模型 带有通配符 的访问器和修改器在当前 laravel 框架中不可用 - 您是否同意我认为这值得在下一个 laravel 版本中 添加 吗?
- 如果是这样,那么 如何正式要求 laravel 制造商在即将发布的版本中考虑这一点?
- Whosebug 工作人员能否代表我们向 laravel 构建者提出改进(如果他们看到了)?
您可以扩展 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);
}
我不太清楚你的数据库是如何设置的,但据我了解,它有一个 table,其中的列名为 tags_en
、tags_fr
、tags_de
,等等
这是一个想法:
- 添加一个 属性 来保存您想要 set/get 的列
- 在
$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 无关,因此他们不能也不会也不会做任何事情。
有一个解决方案,Eloquent Mutators https://github.com/topclaudy/eloquent-mutators
安装包后,您将能够为您的 Eloquent 模型注册自定义 accessors/mutators 扩展。