Laravel追加

时间:2018-12-26 13:50:53

标签: laravel append

我有2张桌子。 1.users,2。user_meta

----------------------      ----------------------
|       users          |         user_meta
----------------------     ----------------------
|id | name | password  |   id|user_id|meta_key|meta_value
 5   xxx      xxxx          1  5       height  6

我想要类似的输出: {'id':1,'name':'xxx','height':6}

我在用户模型上所做的**(只需将高度附加到用户模型上)**

Protected $appends = ['height'];

public function getHeightAttribute($height)
{
    $height= (new UserMeta)->getUserMeta('height',$this->id);
    return $height;
}

但是,如果我有许多元数据,例如:身高,年龄,性别,颜色等...那么我认为将所有元数据附加到用户模型不是一个好主意。 有没有更好的解决方案来获得像{'id':1,'name':'xxx','height':6,'age':24,continue...}这样的响应而无需附加到用户模型?

1 个答案:

答案 0 :(得分:1)

非常简单,这就是您的用户模型。

  1. 在这种情况下,请定义您的元关系名称,我将使用metadata
  2. 急于在每个用户查询上加载元数据关系
  3. 将您的关系值隐藏在模型的json /数组形式上
  4. 设置获取属性更改器,重要提示:必须与关系名称使用不同的名称
  5. 将您的属性附加到meta属性上。

    class User {
        // 2. eager load user metadata on every user query
        protected $with = [ 'metadata' ];
    
        // 3. hide the relationship data from array/json
        protected $hidden = [ 'metadata' ];
    
        // 5. append meta attribute mutator
        protected $append = [ 'meta' ];
    
        // 1. your user meta relationship
        public function metadata() {
            return $this->hasMany(UserMeta::model, 'user_id', 'id');
        }
    
        // 4. `meta` get attribute mutator
        public function getMetaAttribute() {
            return $this->metadata->mapWithKeys(function($meta) {
                return [$meta['meta_key'] => $meta['meta_value']]
            })->all();
        }
    }
    

这将导致:

$user->toJson();

// result
{
  ...
  'email': 'email@domain.com',
  'meta': {
      'key1': 'value1',
      'key2': 'value2'
   }
   ...
}

我认为,这可以更好地反映代码,而不是直接与原始用户属性合并,因为您可以设置setMetaAttribute来更新元数据关系。

但是如果您坚持将所有内容与用户属性合并,则必须在用户模型上覆盖两种方法,__get($attribute)和/或toArray()