Laravel Custom Model Methods

前端 未结 3 999
孤街浪徒
孤街浪徒 2021-01-31 02:37

Whenever I add additional logic to Eloquent models, I end up having to make it a static method (i.e. less than ideal) in order to call it from the model\'s facade.

3条回答
  •  粉色の甜心
    2021-01-31 03:11

    Actually you can extend Eloquent Builder and put custom methods there.

    Steps to extend builder :

    1.Create custom builder

    where(['id' => 1]);
    
            return $this;
        }
    }
    

    2.Add this method to your base model :

    public function newEloquentBuilder($query)
    {
        return new CustomBuilder($query);
    }
    

    3.Run query with methods inside your custom builder :

    User::where('first_name', 'like', 'a')
        ->test()
        ->get();
    

    for above code generated mysql query will be :

    select * from `users` where `first_name` like ? and (`id` = ?) and `users`.`deleted_at` is null
    

    PS:

    First Laurence example is code more suitable for you repository not for model, but also you can't pipe more methods with this approach :

    public static function getAllSortedByMake()
    {
        return Car::where('....')->get();
    }
    

    Second Laurence example is event worst.

    public function scopeGetAllSortedByMake($query)
    {
        return $query->where('...')->get();
    }
    

    Many people suggest using scopes for extend laravel builder but that is actually bad solution because scopes are isolated by eloquent builder and you won't get the same query with same commands inside vs outside scope. I proposed PR for change whether scopes should be isolated but Taylor ignored me.

    More explanation : For example if you have scopes like this one :

    public function scopeWhereTest($builder, $column, $operator = null, $value = null, $boolean = 'and')
    {
        $builder->where($column, $operator, $value, $boolean);
    }
    

    and two eloquent queries :

    User::where(function($query){
        $query->where('first_name', 'like', 'a');
        $query->where('first_name', 'like', 'b');
    })->get();
    

    vs

    User::where(function($query){
        $query->where('first_name', 'like', 'a');
        $query->whereTest('first_name', 'like', 'b');
    })->get();
    

    Generated queries would be :

    select * from `users` where (`first_name` like ? and `first_name` like ?) and `users`.`deleted_at` is null
    

    vs

    select * from `users` where (`first_name` like ? and (`id` = ?)) and `users`.`deleted_at` is null
    

    on first sight queries look the same but there are not. For this simple query maybe it does not matter but for complicated queries it does, so please don't use scopes for extending builder :)

提交回复
热议问题