dongpi3237 2017-02-11 23:23
浏览 65

使用Eloquent ORM自定义方法链接?

This is my current query:

$cars = Cars::with('brand')->get();

$cars->map(function($cars){

    $cars->fullName = $cars->brand->brand." ".$cars->name;
    //other manipulation...
    return $cars;
});

I want to manipulate my collection in the model so that I can run something like $cars = Cars::with('brand')->getWithBrand();

How can I do this, so I don't have to write map functions for every time I run the query?

  • 写回答

1条回答 默认 最新

  • dongnan1899 2017-02-12 01:21
    关注

    In your particular example, you don't need to use map to modify the Collection at all. You can use an Eloquent accessor to define attributes on a Model that don't exist in the database. In your example, you would define the following method on your Cars model:

    public function getFullNameAttribute($value)
    {
        // make sure brand exists first
        if ($this->brand) {
            return $this->brand->brand.' '.$this->name;
        }
    
        // default if brand doesn't exist
        return $this->name;
    }
    

    By defining that function on your Model, that function will be called whenever you attempt to use the full_name attribute, as shown in the following code:

    $car = Cars::with('brand')->first();
    
    // this will echo the result of the getFullNameAttribute method
    echo $car->full_name;
    

    Edit

    If you would also like this new attribute to automatically show up in your toArray() or toJson() output, you can add the attribute to the $appends property on your Cars model:

    class Cars extends Model
    {
        protected $appends = ['full_name'];
    
        public function getFullNameAttribute($value)
        {
            // make sure brand exists first
            if ($this->brand) {
                return $this->brand->brand.' '.$this->name;
            }
    
            // default if brand doesn't exist
            return $this->name;
        }
    }
    

    Be aware, however, that your custom attribute depends on a related object. So, if you do something that accidentally calls toArray(), toJson(), __toString(), etc on a Collection of Cars that has not eager loaded the brand relationship, this will cause the N+1 query issue.

    For example:

    // Bad: N+1 issue because each printed Car will execute a
    // separate query to get its brand to output full_name.
    echo Cars::get();
    
    // Good: No N+1 issue because all brands are already loaded.
    echo Cars::with('brand')->get();
    
    评论

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看