This is a community collaborative translation of the article, has been translated, more information please click
Introduction to collaborative translation 。


The Eloquent ORM seems like a simple mechanism, but underneath, there are plenty of semi-hidden functions and little-known ways to do even more. In this article, I’ll demonstrate a few tips.

1. Increase and decrease

Instead of the following implementation:

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

Here’s what you can do:

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

The following methods can also be implemented:

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


2
retranslation

rayle

2. Execute method X first. If method X fails, execute method Y

Eloquent There is a whole bunch of functions that combine both methods, such as: Execute method X first, execute method Y if method X fails.

findOrFail()

Instead of implementing the following code:

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

You can write:

$user = User::findOrFail($id);
Copy the code

firstOrCreate()

Instead of implementing the following code:

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

I can write it like this:

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


1
retranslation

wilson_yang

3. Boot () method of the model

boot()

class User extends Model { public static function boot() { parent::boot(); Static ::updating(function($model) {$model->something = transform($something); updating(function($model) {$model->something = transform($something); }); }}Copy the code

UUID field

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


1
retranslation

wilson_yang

4. Association relation with condition and sort

General way to define association relationships:

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

where
orderBy


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


0
retranslation

JiaZombie

5. Model features: time, append, etc

The Eloquent model has parameters that take the form of properties of classes. The most commonly used are:

class User extends Model { protected $table = 'users'; protected $fillable = ['email', 'password']; Protected $dates = ['created_at', 'deleted_at']; $appends = ['field1', 'field2']; // json returns with additional fields}Copy the code

Not only that, but also:

protected $primaryKey = 'uuid'; Public $incrementing = false; $perPage = 25; // Define the number of pages to display per page (default 15) const CREATED_AT = 'CREATED_AT '; const UPDATED_AT = 'updated_at'; Public $timestamps = false; // Setting does not require a maintenance time fieldCopy the code

abstract Model class



0
retranslation

JiaZombie

6. Query multiple records using the ID

find()

$user = User::find(1);
Copy the code

I was surprised how few people knew that this method could take an array of multiple ids:

The $users = User: : find ([1, 2, 3]);Copy the code


0
retranslation

wilson_yang

7. WhereX

There is an elegant way to put this code:

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

Convert to this:

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

where

Also, there are some predefined ways to use time, 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'));
Copy the code


0
retranslation

wilson_yang

View the other version

8. Sort by relationship

A slightly more complicated “trick”. Do you want to sort forum topics by the most recent posts? It’s a common requirement to have the latest theme up front in a forum, right?

First, define a separate relationship for the topic’s most recent post:

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

Then, in the controller, we can implement this “magic” :

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


1
retranslation

Summer

Eloquent:: When () — No more if-else

Many people like to use “if-else” to write query conditions like this:

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

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

It may not look very elegant, but its powerful function is passing parameters:

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


0
retranslation

wilson_yang

BelongsTo default model

If you have a Post model attached to an Author model, you could write something like this in a Blade template:

{{ $post->author->name }}
Copy the code

But what if the author is deleted, or not set for some reason? You’ll get an error message like “Object property does not exist.”

Well, here’s how you can avoid it:

{{ $post->author->name ?? "'}}Copy the code

But you can do this at the Eloquent relationship model level:

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

author()
App\Author

In addition, we can assign a default property value to the default model.

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


1
retranslation

JiaZombie

View the other three versions

11. Sort by assignment function

Imagine you have code like this:

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

Now, you want to sort by “full_name”? Discovery is not effective:

$clients = Client::orderBy('full_name')->get(); // No effectCopy the code

The solution is simple. We need to sort the results after we get them.

$clients = Client::get()->sortBy('full_name'); / / success!Copy the code

Notice that the method name is different — it’s not Order Derby, it’s sortBy



0
retranslation

JiaZombie

12. Default sort under global scope

User::all()
name
boot()

protected static function boot() { parent::boot(); Static ::addGlobalScope('order', function (Builder $Builder) {$Builder ->orderBy('name', 'asc'); }); }Copy the code

Query scope



0
retranslation

wilson_yang

13. Native query methods

Sometimes, you need to add a native query to your Eloquent statement. Fortunately, there is.

// 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();Copy the code


0
retranslation

wilson_yang

14. Copy: Make a copy of a row

Very simple. Without going too far, here is the best way to replicate a database entity (a piece of data) :

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


0
retranslation

rayle

15. Chunk() method of Chunk data

1. Not entirely related to Eloquent, which is more about collections, but is still useful for working with large data collections. You can use chunk() to split this data into smaller chunks

Modify before:

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

Here’s what you can do:

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


0
retranslation

JiaZombie

16. Add extra actions when creating the model

We all know the Artisan command:

php artisan make:model Company
Copy the code

But you know that there are three very useful identifiers that can be used to generate model-related files

php artisan make:model Company -mcr
Copy the code
  • -m Creates a migration file
  • -c Creates a controller file
  • -r Indicates the operation of adding resources to a controller



1
retranslation

rayle

View the other version

17. Specify updated_at when calling the save method

->save()
updated_at

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

save
updated_at



1
retranslation

Summer

18. What is the result of the update()?

Have you ever wondered what this code actually returns?

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

$result
update()



0
retranslation

rayle

Convert the parentheses into a Eloquent query

and
or

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

1. How do you translate it Eloquent Here’s the wrong way to do it:

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

Not in the right order. The correct way to open is slightly more complicated, using closures as subqueries:

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


0
retranslation

rayle

20. OrWhere for complex parameters

orWhere()

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

Here’s what you can do:

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

I’m pretty sure there are more hidden secrets, but I hope at least some of the above are new to you.


0
retranslation

rayle

Original address:
Laravel-news.com/eloquent-ti…Translation Address:
Laravel-china.org/topics/9991…


All translations in this article are for study and communication purposes only. Please note the translator, source, and link to this article


Our translation work is in accordance with
CCIf our work has violated your rights and interests, please contact us immediately.