Laravel Eloquent 必备的实用技能类别:Laravel / 日期:2019-12-24 / 浏览:245 / 评论:0
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网别的相干文章!