2017-09-22 16 views
0

問題Laravelモデルアクセサとミューテーター(*)

、など。(8)言語タグ

のために私は一度の代わりに、アクセサ/ミューテータのカップルを使用して、サブタイプ8言語のすべてのタグモデルで1つのアクセサと1つのミューテータを設定したいと思いますそれぞれの方法について説明します。

通常、それぞれについて以下のことを行います。 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)); 
} 

または

何かlike:

foreach ($tagsAttributes as $TagAttribute){ 
    //method building code for each tags language 
} 

同様Laravelのアイデアは、私は、ワイルドカードを使用してlaravelモデルクラスを介してそれを行う方法があるかもしれないことを前提とし、ワイルドカード

と検証のために存在します。これは、このような配列の各要素を検証できる検証のようになります。

$validator = Validator::make($request->all(), [ 
    'person.*.email' => 'email|unique:users', 
    'person.*.first_name' => 'required_with:person.*.last_name', 
]); 

質問:

  1. これらのモデルは、ワイルドカードでのアクセサとミューテータが利用できない場合現在のlaravelフレームワークで - これは価値があると私に同意しますか次のlaravelのバージョンでは?
  2. もしそうならば、次のバージョンで正式にこれを考慮する方法を教えてください
  3. 私たちに代わってスタッフがその改善のためにlaravelビルダーに質問することができますか?
+0

アクセサーとミューテータが必要ですか?あなたはモデルのメソッドだけではできないreasongはありますか? – tptcat

+0

私は、モデルに利用可能なlaravelフレームワークメソッドを、ホイールを再作成するよりも使用する方が好きです。もちろん、laravel Modelクラスを使って行うことができると仮定します。これはValidatorに似ています。 $ validator = Valid($ request-> all()、[ 'person。*。email' => 'email | unique :ユーザー '、 ' person。*。first_name '=>' required_with:person。*。last_name '、 ]); – WillKoz

+0

私はちょっと混乱しています:あなたは実際にこれらをdb: 'tags_en'、' tags_es'などの列としてすべて持っていますか?あるいは、 'tags'という名前のJSON列を1つだけ持っていますか? – tptcat

答えて

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); 
} 
0

など、それはあなたのデータベースのセットアップがどのようにのように私には少しは不明だが、私が理解から、それはtags_enという名前の列を持つテーブルを持っている、tags_frtags_deここでアイデアです:

  1. 設定したい列を保持しているプロパティを追加/
  2. $casts
  3. でカスタムタイプを作成し得ます

それを(これはアクセサのように機能します)boot()メソッドをオーバーライドしtagson creatingupdating

  • オーバーライド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とは関係がないので、何もできないし、できないだろうし、できないだろう。