了解和使用Laravel雄辩的宏

The ability to define macros for Eloquent relationships is a new feature in Laravel 5.4. It offers us the flexibility of fetching just a single instance of a hasMany() relationship by defining it in one place and then to utilize it for any related tables in the database with a one to many relationship.

为雄辩关系定义宏的能力是Laravel 5.4中的一项新功能。 它为我们提供了灵活性,只需在一个位置定义hasMany()关系的单个实例,然后将其用于具有一对多关系的数据库中的任何相关表即可。

As you might be aware, Eloquent is the name of a very simple, yet powerful and expressive ORM (object relational mapping) in Laravel. Getting started with Eloquent in Laravel requires creating a model which corresponds to and represent a particular table within the database.

如您所知,Eloquent是Laravel中非常简单但功能强大且富有表现力的ORM(对象关系映射)的名称。 在Laravel中使用Eloquent入门需要创建一个模型,该模型对应并代表数据库中的特定表。

This makes the process of defining relationships and retrieving related models very simple. Eloquent provides some very helpful ways of properly interacting with the tables in the database, thereby making it easy to carry out basic database operations, such as adding, deleting, updating and retrieving a specific record.

这使得定义关系和检索相关模型的过程非常简单。 Eloquent提供了一些非常有用的方式来与数据库中的表进行正确的交互,从而使执行基本的数据库操作变得容易,例如添加,删除,更新和检索特定记录。

Here on Scotch, Chris Sevilleja wrote a well-structured article about Eloquent ORM.

克里斯·塞维利亚Chris Sevilleja )在苏格兰语上写了一篇有关口才ORM的结构良好的文章。

The good news is Eloquent is now macroable.

好消息是,Eloquent现在可以宏了。

Which means you can simply create a function (Macro function) that will give you the possibility of chaining Eloquent relationship into one function and calling it anywhere within your application.

这意味着您只需创建一个函数(宏函数),就可以将雄辩的关系链接到一个函数中,并在应用程序中的任何位置调用它。

一个简单的例子 ( A Quick Example )

With an Eloquent macro function, you can easily extend Laravel API for model (i.e Illuminate\Database\Eloquent\Model) with your own custom functions.

使用Eloquent宏函数,您可以使用自己的自定义函数轻松扩展适用于模型的Laravel API(即Illuminate \ Database \ Eloquent \ Model)。

Take a look at this piece of code used to retrieve the last reply to a particular comment on a thread

看一下这段代码,该代码用于检索对线程上的特定注释的最后答复

// A particular comment Model
public function replies()
{
    return $this->hasMany(Reply::class);
}

public function latestReply()
{
    return $this->hasOne(Reply::class)->latest();
}

But assuming we have an Eloquent macro function (justHasOne) defined already within our application, we can simply do this

但是,假设我们已经在应用程序中定义了一个雄辩的宏函数(justHasOne),我们可以简单地执行此操作

public function latestReply()
{
    // If macro justHasOne has been defined
    return $this->replies()->latest()->justHasOne();
}

With Eloquent macros, you can chain functions and greatly improve readability.

使用雄辩的宏,您可以链接函数并大大提高可读性。

Let's quickly look into how seamless it is to create a macro function for Laravel Eloquent relationship. Just like this

让我们快速研究一下为Laravel Eloquent关系创建宏函数的无缝性。 像这样

HasMany::macro('toHasOne', function() {
     return new HasOne(
     $this->getQuery,
     $this->getParent,
     $this->foreignKey,
     $this->localKey
     );
});

让我们开始 ( Let's Begin )

In this article I'll assume you are already conversant with the basics of Laravel i.e

在本文中,我假设您已经熟悉Laravel的基础知识,即

  • How to set up Laravel using composer

    如何使用作曲家设置Laravel
  • If not, quickly go through this documentation

    如果没有,请快速阅读此文档

设置Laravel ( Setup Laravel )

To get started, we need a fresh installation of Laravel. Ensure that your local development server meets the requirement for Laravel 5.4 as stated here. If you are set, let's quickly run the installation command using composer

首先,我们需要重新安装Laravel。 确保您的本地开发服务器满足此处所述的Laravel 5.4的要求。 如果已设置,让我们使用composer快速运行安装命令

# install laravel
composer create-project --prefer-dist laravel/laravel laravel-macro

And if you have Laravel installer installed on your computer, you can simply run the command below

如果您的计算机上安装Laravel安装程序,则只需运行以下命令

laravel new laravel-macro

By now you should have Laravel setup and ready to go.

现在,您应该已经安装Laravel并可以开始使用了。

示范项目 ( Demo project )

This project is to get you started with Eloquent macros within Laravel application, so it's really going to be based on showcasing a very simple use case of this new feature. You can then build on this and use as you deem fit in your projects.

这个项目是为了让您开始使用Laravel应用程序中的Eloquent宏,因此它实际上将基于展示此新功能的一个非常简单的用例。 然后,您可以在此基础上构建并在您认为适合的项目中使用。

用例 ( Use case )

We will consider a very simple use case for this article. Let's assume that we intend to display the latest post by a particular user on a blog page (for example). We can simply define a HasOne relation in addition to HasMany relation with the posts model.

我们将为本文考虑一个非常简单的用例。 假设我们打算在博客页面上显示特定用户的最新帖子(例如)。 除了具有posts模型的HasMany关系之外,我们还可以简单地定义一个HasOne关系。

移民 ( Migration )

Since a fresh installation of Laravel comes with User model and migration file for user table out of the box, all we have to do right now is create a new model for Post.

由于Laravel的全新安装随附了用户模型和用于用户表的迁移文件,因此我们现在要做的就是为Post创建一个新模型。

# Create post model and migration file 
php artisan make:model Post -m

Let us add more fields

让我们添加更多字段

  • post field

    邮政领域
  • user_id

    用户身份
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            /*add this*/
            $table->string('post');
            $table->integer('user_id')->unsigned();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Now we are ready to migrate our file

现在我们准备迁移文件

php artisan migrate

引导服务 ( Bootstrap Service )

To register our macro function, it will be best to create a service provider for it. Service providers are central place to configure Laravel application.

要注册我们的宏功能,最好为其创建一个服务提供者。 服务提供商是配置Laravel应用程序的中心位置。

We will create a service provider and call it MacroServiceProvider with the command below

我们将创建一个服务提供者,并使用以下命令将其称为MacroServiceProvider

php artisan make:provider MacroServiceProvider

This will create a new file called MacroServiceProvider within App\Providers directory.

这将在App \ Providers目录中创建一个名为MacroServiceProvider的新文件。

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class MacroServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

The service provider file usually contains a register and a boot method. The boot method is where we will need to declare our macro function. It will be bootstraped once we start our Laravel application.

服务提供者文件通常包含一个寄存器和一个引导方法。 boot方法是我们需要声明宏函数的位置。 一旦启动Laravel应用程序,它将被引导。

Let's edit the boot method

让我们编辑启动方法

// MacroServiceProvider.php
namespace App\Providers;

use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\ServiceProvider;

class MacroServiceProvider extends ServiceProvider
{
    public $foreignKey = 'user_id';

    public $localKey = 'id';

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        HasMany::macro('toHasOne', function(){
           return new HasOne(
               $this->getQuery(),
               $this->getParent(),
               $this->foreignKey,
               $this->localKey
           );
        });

    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

So, we basically defined a name for our Eloquent macro function as 'toHasOne' and also declared both the foreignKey and localKey in order to ensure the relationship between our models.

因此,我们基本上将Eloquent宏函数的名称定义为“ toHasOne”,并且还声明了foreignKey和localKey以确保模型之间的关系。

The Eloquent macro function accepts a name as its first argument and a closure as its second. This closure will be executed once we call the function from a model within our application.

雄辩的宏函数接受名称作为其第一个参数,并接受闭包作为其第二个参数。 一旦我们从应用程序中的模型调用函数,便会执行此关闭。

P.S Don't forget to add this at the top of your file

PS不要忘记在文件顶部添加此内容

use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

The next step is to register the service provider we just created. All service providers are registered within config/app.php

下一步是注册我们刚刚创建的服务提供商。 所有服务提供商都在config / app.php中注册

'providers' => [
    /*
    * Package Service Providers...
    */

        App\Providers\MacroServiceProvider::class,
],

Back to the User model and to make use of the Eloquent macro function we just created.

回到用户模型,并利用我们刚刚创建的Eloquent宏功能。

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function posts() {
        return $this->hasMany(Post::class);
    }

    public function lastPost(){
        return $this->posts()->latest()->toHasOne();
    }
}

The newly created function lastPost() can now be used within our application. This will give us access to the last post by a user.

现在可以在我们的应用程序中使用新创建的函数lastPost()。 这将使我们能够访问用户的最新帖子。

We will create a simple view to display the usage of the macro function within our demo project, but before that, it will make sense to have some contents in our database.

我们将创建一个简单的视图来显示演示项目中宏功能的用法,但在此之前,在数据库中包含一些内容是有意义的。

Let us quickly achieve this by inserting some dummy data via a shell command called "tinker". This is just a really quick way for you to interact with your application in the command line. For more information on how to use "Tinker", check this post by Samuel.

让我们通过称为“ tinker”的shell命令插入一些虚拟数据来快速实现这一目标。 这只是您在命令行中与应用程序进行交互的一种非常快捷的方法。 有关如何使用“ Tinker”的更多信息,请查看Samuel的这篇文章

Tinker example

Inserting the data into the database using Tinker

使用Tinker将数据插入数据库

Inserting data into the database using tinker

Using the Eloquent macro function we created

使用我们创建的雄辩的宏函数

With the results above, it is obvious that a macro function comes handy when it comes to establishing relationships within models.

根据上面的结果,很明显,在建立模型内的关系时,宏函数很方便。

Alternatively, one can just create a database seeder file to input dummy data into the database as well.

或者,可以只创建一个数据库种子文件,以将伪数据也输入到数据库中。

路线 ( Route )

We are just going to make use of the existing route created by default and pass a new view to it.

我们将使用默认情况下创建的现有路由,并将新视图传递给它。

use App\User;

    Route::get('/', function () {
    return view('view_post')->with('users', User::all());
});

更多说明 ( More Explanation )

// User model
public function posts() {
        return $this->hasMany(Post::class);
    }

    public function lastPost(){
        return $this->posts()->latest()->toHasOne();
    }

So what does this have to do with relationship macro?

那么,这与关系宏有什么关系?

/* The functions below will give the same results */
// with macro function 
 public function lastPost(){
        return $this->posts()->latest()->toHasOne();
    }

// without macro function
public function lastPost(){
        return $this->hasOne(Post::class)->latest();
    }

The answer is simple: instead of declaring a new one to one relationship specifically for fetching the last post (as stated in the second function above), the Eloquent macro function declared earlier has taking care of that.

答案很简单:与其声明新的一对一关系专门用于获取最后一个帖子(如上面的第二个函数中所述),不如之前声明的Eloquent宏函数来解决这个问题。

我们的观点 ( Our View )

Let's quickly create a simple view and pass our data into it.

让我们快速创建一个简单的视图并将数据传递到其中。

<!-- resources/views/view_post.blade.php-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title> Eloquent Macros </title>

    <!-- Styles -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <style>
        body { padding-top:50px; } /* add some padding to the top of our site */
    </style>
</head>
<body>
<div class="container">
    <div class="form-group">
        @foreach($users as $user)
            <h2>{{ $user->name }}</h2>
            <p><small>{{ $user->email }}</small></p>
            <div class="well">
                <h4> Latest Post</h4>

                {{ $user->lastPost->post }}
            </div>
            <div>
                <h4>All Posts </h4>
                @foreach($user->posts as $post)
                    <h4> {{ $post->post }}</h4>
                    <small> Created at: {{ $post->created_at }}</small>
                    <small> Updated at: {{ $post->updated_at }}</small>
                @endforeach
            </div>
            <hr>
        @endforeach
    </div>
</div>
</body>
</html>

The use case for Eloquent macro function might be different in your application, but the concept is still the same.

雄辩的宏功能的用例在您的应用程序中可能会有所不同,但是概念仍然相同。

结论 ( Conclusion )

Eloquent macro functions focus on improving interaction with the database in Laravel applications and greatly enhance readability. As we saw in this tutorial, you can easily chain Eloquent relationships and fetch data from the database. This is designed to help you get a good grasp of how to use Eloquent macros in your own Laravel applications. You can leverage the knowledge gained here to build bigger, better and more functional apps. I hope you found this tutorial helpful. You can drop a comment, if you have suggestions or encounter any issues while going through the tutorial.

雄辩的宏函数专注于改善Laravel应用程序中与数据库的交互,并大大提高了可读性。 正如我们在本教程中所看到的,您可以轻松地链接口才关系并从数据库中获取数据。 这旨在帮助您更好地掌握如何在自己的Laravel应用程序中使用Eloquent宏。 您可以利用在这里获得的知识来构建更大,更好,功能更多的应用程序。 希望本教程对您有所帮助。 如果您有建议或在阅读本教程时遇到任何问题,可以发表评论。

翻译自: https://scotch.io/tutorials/understanding-and-using-laravel-eloquent-macros

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值