Maison >cadre php >Laravel >Conseils pratiques essentiels pour Laravel Eloquent

Conseils pratiques essentiels pour Laravel Eloquent

藏色散人
藏色散人avant
2019-12-23 17:41:582542parcourir

Compétences pratiques nécessaires pour Laravel Eloquent

1. Incrémenter et décrémenter

Pour remplacer l'implémentation suivante :

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

Vous pouvez faire ceci :

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

Les méthodes suivantes peuvent également être implémentées :

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

2. Exécuter la méthode Utilisez, par exemple "Veuillez d'abord exécuter la méthode X, si la méthode X échoue, exécutez la méthode Y".

Exemple 1 -- findOrFail() :

Pour remplacer l'implémentation du code suivant :

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

Vous pouvez écrire comme ceci :

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

Exemple 2 -- firstOrCreate():

Pour remplacer l'implémentation du code suivant :

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

Écrivez-le simplement comme ceci :

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

3 La méthode boot() du modèle.

Dans un modèle Eloquent, il existe un endroit magique appelé boot(), où vous pouvez remplacer le comportement par défaut :

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        static::updating(function($model)
        {
            // 写点日志啥的
            // 覆盖一些属性,类似这样 $model->something = transform($something);
        });
    }
}

Définir les valeurs de certains champs lors de la création de l'objet modèle, probablement l'un des exemples les plus populaires. Voyons ce qu'il faut faire si vous souhaitez générer un champ UUID lors de la création d'un objet modèle.

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

4. Association avec conditions et tri

Manière générale de définir l'association :

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

Le savez-vous ? Vous pouvez également ajouter Where ou OrderBy en fonction de ce qui précède,

Par exemple, si vous souhaitez associer certains types d'utilisateurs et utiliser le champ email pour trier, vous pouvez faire ceci :

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

5. Caractéristiques du modèle : temps, ajout, etc.

Certains paramètres du modèle Eloquent se présentent sous la forme d'attributs de classe. Les plus couramment utilisés sont :

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返回时,附加的字段
}

Non seulement ceux-ci, mais aussi :

protected $primaryKey = 'uuid'; // 更换主键
public $incrementing = false; // 设置 不自增长
protected $perPage = 25; // 定义分页每页显示数量(默认15)
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at'; //重写 时间字段名
public $timestamps = false; // 设置不需要维护时间字段

Il y en a d'autres. Je n'ai répertorié que quelques fonctionnalités intéressantes. Veuillez vous référer au résumé du document Model class pour plus de détails.

6. Interrogez plusieurs enregistrements par ID

Tout le monde connaît la méthode find(), n'est-ce pas ?

$user = User::find(1);

Je suis très surpris que peu de gens sachent que cette méthode peut accepter des tableaux de plusieurs identifiants comme paramètres :

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

7 WhereX

Il existe une manière élégante de procéder. type de code :

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

est converti en ce type de code :

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

Oui, vous avez bien lu, utilisez le nom du champ comme suffixe et ajoutez-le après où, et il s'exécutera grâce à la méthode magique.

De plus, il existe quelques méthodes prédéfinies liées au temps dans 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. Tri par relation

Une "technique" plus compliquée. Voulez-vous trier les sujets du forum par derniers messages ? C'est une exigence courante d'avoir les sujets les plus récemment mis à jour dans un forum en haut, n'est-ce pas ?

Tout d'abord, définissez une relation distincte pour le dernier message du sujet :

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

Ensuite, dans le contrôleur, nous pouvons implémenter cette "magie" :

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

9. :when() -- Plus besoin d'utiliser if-else

Beaucoup de gens aiment utiliser "if-else" pour écrire des conditions de requête, comme ceci :

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'));
}

Il existe une meilleure méthode Méthode- -use 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'));
});

Cela n'a peut-être pas l'air très élégant, mais sa fonction puissante est de transmettre des paramètres :

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

10 Appartient au modèle par défaut

S'il y a un. Modèle de publication attaché au modèle Auteur, et le code suivant peut être écrit dans le modèle Blade :

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

Mais que se passe-t-il si l'auteur est supprimé ou n'est pas défini pour une raison quelconque ? Vous recevrez un message d'erreur du type "propriété d'objet inexistante".

Eh bien, vous pouvez l'éviter comme ceci :

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

Mais vous pouvez le faire au niveau du modèle relationnel Eloquent :

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

Dans cet exemple, si le message n'a pas author Sinon, la méthode de relation author() renverra un objet modèle AppAuthor vide.

De plus, nous pouvons également attribuer une valeur d'attribut par défaut au modèle par défaut.

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

11. Tri par fonction d'affectation

Imaginez que vous avez ce code :

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

Maintenant, vous souhaitez trier par "nom_complet" ?

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

La solution est simple. Nous devons trier les résultats après les avoir obtenus.

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

Notez que les noms de méthodes sont différents - ce n'est pas orderBy, mais sortBy

12. Tri par défaut dans la portée globale

Et si vous souhaitez que User::all() trie toujours par le champ de nom ? Vous pouvez lui attribuer une portée globale. Revenons à la méthode boot() que nous avons mentionnée ci-dessus :

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

Portée de la requête de lecture étendue.

13. Méthode de requête native

Parfois, nous devons ajouter des requêtes natives aux instructions Eloquent. Heureusement, il existe un moyen.

// 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. Copier : Faire une copie d'une ligne

est facile. L'explication n'est pas très approfondie, mais voici la meilleure façon de copier une entité de base de données (une donnée) :

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

15, méthode Chunk() de gros morceaux de données

n'est pas complètement lié à Eloquent, c'est plutôt More about Collection (set), mais il reste très utile pour traiter de grandes collections de données. Vous pouvez utiliser chunk() pour diviser ces données en petits morceaux de données

Avant modification :

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

Vous pouvez faire ceci :

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

Ajouter un supplément lors de la création du modèle. Opération

Nous connaissons tous cette commande Artisan :

php artisan make:model Company

Mais vous savez qu'il existe trois identifiants très utiles qui peuvent être utilisés pour générer des fichiers liés au modèle

php artisan make:model Company -mcr

-m Créer fichier de migration

-c Créer un fichier de contrôleur

-r Ajouter une méthode d'opération de ressource au contrôleur

17 Spécifiez update_at

lors de l'appel de la méthode de sauvegarde.

你知道 ->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教程栏目!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer