类别:Laravel / 日期:2019-12-24 / 浏览:245 / 评论:0

Laravel Eloquent 必备的实用技能

1. 递增和递减

要替换以下完成:

$article = Article::find($article_id);
$article->read_count++;
$article->save();

你能够如许做:

$article = Article::find($article_id);
$article->increment('read_count');

以下这些要领也能够完成:

Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // +10
Product::find($produce_id)->decrement('stock'); // -1

2. 先实行 X 要领,X 要领实行不胜利则实行 Y 要领

Eloquent 有相称一部分函数能够把两个要领连系在一同运用, 比方 『 请先实行 X 要领, X 要领实行不胜利则实行 Y 要领 』。

实例 1 -- findOrFail():

要替换以下代码的完成:

$user = User::find($id);
if (!$user) { abort (404); }

你能够如许写:

$user = User::findOrFail($id);

实例 2 -- firstOrCreate():

要替换以下代码的完成:

$user = User::where('email', $email)->first();
if (!$user) {
  User::create([
    'email' => $email
  ]);
}

如许写就可以够了:

$user = User::firstOrCreate(['email' => $email]);

3. 模子的 boot() 要领

在一个 Eloquent 模子中,有个奇异的处所,叫 boot(),在那里,你能够掩盖默许的行动:

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        static::updating(function($model)
        {
            // 写点日记啥的
            // 掩盖一些属性,相似如许 $model->something = transform($something);
        });
    }
}

在建立模子对象时设置某些字段的值,大概是最受迎接的例子之一了。 一同来看看在建立模子对象时,你想要生成 UUID 字段 该怎样做。

public static function boot()
{
  parent::boot();
  self::creating(function ($model) {
    $model->uuid = (string)Uuid::generate();
  });
}

4. 带前提与排序的关联关联

定义关联关联的寻常体式格局:

public function users()
{
    return $this->hasMany('App\User');
}

你晓得吗?也能够在上面的基础上增添 where 或许 orderBy,

举个例子,假如你想关联某些范例的用户,同时运用 email 字段排序,你能够如许做:

public function approvedUsers() {
    return $this->hasMany('App\User')->where('approved', 1)->orderBy('email');
}

5. 模子特征:时刻、追加等

Eloquent 模子有些参数,运用类的属性情势。最常用是:

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['email', 'password']; // 能够被批量赋值字段,如 User::create() 新增时,可运用字段
    protected $dates = ['created_at', 'deleted_at']; // 需要被Carbon保护的字段名
    protected $appends = ['field1', 'field2']; // json返回时,附加的字段
}

不只这些,另有:

protected $primaryKey = 'uuid'; // 替换主键
public $incrementing = false; // 设置 不自增进
protected $perPage = 25; // 定义分页每页显现数目(默许15)
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at'; //重写 时刻字段名
public $timestamps = false; // 设置不需要保护时刻字段

另有更多,我只列出了一些有意思的特征,细致参考文档 abstract Model class 相识一切特征.

6. 经由过程 ID 查询多条纪录

一切人都晓得 find() 要领,对吧?

$user = User::find(1);

我非常不测居然很少人晓得这个要领能够接收多个 ID 的数组作为参数:

$users = User::find([1,2,3]);

7. WhereX

有一种文雅的体式格局能将这类代码:

$users = User::where('approved', 1)->get();

转换成这类:

$users = User::whereApproved(1)->get();

对,你没有看错,运用字段名作为后缀增加到 where 背面,它就可以经由过程把戏要领运行了。

别的,在 Eloquent 里也有些和时刻相干的预定义要领:

User::whereDate('created_at', date('Y-m-d'));
User::whereDay('created_at', date('d'));
User::whereMonth('created_at', date('m'));
User::whereYear('created_at', date('Y'));

8. 经由过程关联排序

一个庞杂一点的「技能」。你想对论坛话题按最新宣布的帖子来排序?论坛中最新更新的主题在最前面是很罕见的需求,对吧?

起首,为主题的最新帖子定义一个零丁的关联:

public function latestPost()
{
    return $this->hasOne(\App\Post::class)->latest();
}

然后,在控制器中,我们能够完成这个「魔法」:

$users = Topic::with('latestPost')->get()->sortByDesc('latestPost.created_at');

9. Eloquent::when() -- 不再运用 if-else

很多人都喜好运用"if-else"来写查询前提,像如许:

if (request('filter_by') == 'likes') {
    $query->where('likes', '>', request('likes_amount', 0));
}
if (request('filter_by') == 'date') {
    $query->orderBy('created_at', request('ordering_rule', 'desc'));
}

有一种更好的要领 -- 运用 when()

$query = Author::query();
$query->when(request('filter_by') == 'likes', function ($q) {
    return $q->where('likes', '>', request('likes_amount', 0));
});
$query->when(request('filter_by') == 'date', function ($q) {
    return $q->orderBy('created_at', request('ordering_rule', 'desc'));
});

它可能看上去不是很文雅,但它壮大的功用是通报参数:

$query = User::query();
$query->when(request('role', false), function ($q, $role) {
    return $q->where('role_id', $role);
});
$authors = $query->get();

10. BelongsTo 默许模子

假如有一个 Post 模子附属于 Author 模子,在 Blade 模板里能够写作以下代码:

{{ $post->author->name }}

然则假如作者被删除了,或许由于某些缘由未设置?你就会获得一个毛病信息,相似「不存在的对象属性」。

那末,你能够这么防止它:

{{ $post->author->name ?? '' }}

然则你能够在 Eloquent 关联模子级别做到这类效果:

public function author()
{
    return $this->belongsTo('App\Author')->withDefault();
}

这个例子中,假如帖子没有作者的话,author() 关联要领会返回一个空的 App\Author 模子对象。

另外,我们还能够为默许模子分派一个默许的属性值。

public function author()
{
    return $this->belongsTo('App\Author')->withDefault([
        'name' => 'Guest Author'
    ]);
}

11. 经由过程赋值函数举行排序

设想一下你有如许的代码:

function getFullNameAttribute()
{
  return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}

如今,你想要经由过程 "full_name" 举行排序? 发现是没有效果的:

$clients = Client::orderBy('full_name')->get(); //没有效果

解决办法很简单.我们需要在猎取效果后对效果举行排序.

$clients = Client::get()->sortBy('full_name'); // 胜利!

注重的是要领名称是不相同的 -- 它不是 orderBy,而是 sortBy

12. 全局作用域下的默许排序

假如你想要 User::all() 老是根据 name 字段来排序呢? 你能够给它分派一个全局作用域。让我们回到 boot() 这个我们在上文提到过的要领:

protected static function boot()
{
    parent::boot();
    // 根据 name 正序排序
    static::addGlobalScope('order', function (Builder $builder) {
        $builder->orderBy('name', 'asc');
    });
}

扩大浏览 查询作用域 。

13. 原生查询要领

有时刻,我们需要在 Eloquent 语句中增加原生查询。 荣幸的是,确切有如许的要领。

// whereRaw
$orders = DB::table('orders')
    ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
    ->get();
// havingRaw
Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
// orderByRaw
User::where('created_at', '>', '2016-01-01')
  ->orderByRaw('(updated_at - created_at) desc')
  ->get();

14. 复制:复制一行的副本

很简单。申明不是很深切,下面是复制数据库实体(一条数据)的最好要领:

$task = Tasks::find(1);
$newTask = $task->replicate();
$newTask->save();

15. Chunk() 要领之大块数据

与 Eloquent 不完全相干,它更多的关于 Collection (鸠合),然则关于处置惩罚大数据鸠合,仍然是很有效的。你能够运用 chunk() 将这些数据分割成小数据块

修正前:

$users = User::all();
foreach ($users as $user) {
    // ...

你能够如许做:

User::chunk(100, function ($users) {
    foreach ($users as $user) {
        // ...
    }
});

16. 建立模子的时刻增添分外操纵

我们都晓得这条 Artisan 敕令:

php artisan make:model Company

然则你晓得有三个非常有效的标志符可用于生成模子相干文件

php artisan make:model Company -mcr

-m 建立迁徙文件

-c 建立控制器文件

-r 为控制器增加资本操纵要领

17. 挪用 save 要领的时刻指定 updated_at

你晓得 ->save() 要领能够接收参数吗? 我们能够经由过程传入参数阻挠它的默许行动:更新 updated_at 的值为当前时刻戳。

$product = Product::find($id);
$product->updated_at = '2019-01-01 10:00:00';
$product->save(['timestamps' => false]);

如许,我们胜利在 save 时指定了 updated_at 的值。

18. update() 的效果是什么?

你是不是想晓得这段代码实际上返回什么?

$result = $products->whereNull('category_id')->update(['category_id' => 2]);

我是说,更新操纵是在数据库中实行的,但 $result 会包括什么?

答案是受影响的行。 因而假如你想搜检若干行受影响, 你不需要分外挪用其他任何内容 -- update() 要领会给你返回此数字。

19. 把括号转换成 Eloquent 查询

假如你有个 and 和 or 夹杂的 SQL 查询,像如许子的:

... WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)

怎样用 Eloquent 来翻译它呢? 下面是一种毛病的体式格局:

$q->where('gender', 'Male');
$q->orWhere('age', '>=', 18);
$q->where('gender', 'Female');
$q->orWhere('age', '>=', 65);

递次就没对。准确的打开体式格局轻微庞杂点,运用闭包作为子查询:

$q->where(function ($query) {
    $query->where('gender', 'Male')
        ->where('age', '>=', 18);
})->orWhere(function($query) {
    $query->where('gender', 'Female')
        ->where('age', '>=', 65);
})

20. 复数参数的 orWhere

终究,你能够通报阵列参数给 orWhere()。寻常的体式格局:

$q->where('a', 1);
$q->orWhere('b', 2);
$q->orWhere('c', 3);

你能够如许做:

$q->where('a', 1);
$q->orWhere(['b' => 2, 'c' => 3]);

更多laravel框架相干技术文章,请接见laravel教程栏目!

以上就是Laravel Eloquent 必备的实用技能的细致内容,更多请关注ki4网别的相干文章!

打赏

感谢您的赞助~

打开支付宝扫一扫,即可进行扫码打赏哦~

版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。

 可能感兴趣的文章