Eloquent ORM Instance Tutorial - Association Relationship and Its Definition in the Model (I)


 guide-to-eloquent-orm

Data tables are often not isolated, but crisscross and interrelated. For example, one user has published multiple articles, one article has multiple comments, and so on. Eloquent model supports multiple associations. Let's work together.

1. One to one

One to one is the simplest association relationship, which means that the records in Table A and Table B correspond one by one. For example, one user corresponds to one social account. Before demonstrating the association relationship, we first create a social account table user_accounts

 php artisan make:migration create_user_accounts_table --create=user_accounts

Edit the generated migration file as follows:

 <? php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUserAccountsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('user_accounts', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); $table->string('qq',20)->nullable(); $table->string('weixin',100)->nullable(); $table->string('weibo',100)->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('user_accounts'); } }

Then run the Artisan command:

 php artisan migrate

Insert a data in the generated table:

 user-accounts

Then use the following Artisan command to generate the model UserAccount

 php artisan make:model Models/UserAccount

Next, let's start User Defined in and UserAccount One-to-one correspondence of:

 public function account() { return $this->hasOne('App\Models\UserAccount'); }

Finally, write the test code in the controller as follows:

 $account = User::find(1)->account; dd($account);

The browser will output the corresponding UserAccount Model instance.

Relatively, we can also UserAccount Defined in the model and User One to one relationship of:

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

The corresponding test code is:

 $user = UserAccount::find(1)->user; dd($user);

The above code will output the corresponding User Model instance.

Note that we are not calling belongsTo When specifying the corresponding foreign key information, how does the Eloquent model determine User And UserAccount What about the corresponding relationship of?

By default, Eloquent calls belongsTo Associated method name of user As an association $relation And set the $relation.'_ id' Corresponding to the default foreign key name users Of table id If there is no corresponding column in the table and no specific foreign key is specified when defining the association relationship, an error will be reported.

How to specify a foreign key when defining an association?

In fact, at the bottom, whether hasOne Method or belongsTo Methods can receive additional parameters, such as if user_accounts Middle Association users The foreign key of is $foreign_key , the foreign key corresponds to users The columns in the table are $local_key , then we can call hasOne method:

 $this->hasOne('App\Models\UserAccount',$foreign_key,$local_key);

call belongsTo The method is the same:

 $this->belongsTo('App\User',$foreign_key,$local_key);

In addition, belongsTo Also receives an additional parameter $relation , used to specify the name of the association relationship. Its default value is call belongsTo Method name of, here is user

2. One to many

One to many is a common association relationship, which is used to indicate that a record in Table A corresponds to multiple records in Table B. On the contrary, a record in Table B belongs to a record in Table A. For example, if a user publishes multiple articles, it is also simple to define the one to many relationship User Definition and article model in Post The one to many relationship of is as follows:

 public function posts() { return $this->hasMany('App\Models\Post'); }

Corresponding test code:

 $posts = User::find(1)->posts; dd($posts);

In this way, all articles published by the user with ID 1 can be obtained.

Since the associated model instance itself is a query builder, we can add query conditions to the instance:

 $posts = User::find(1)->posts()->where('views','>',100)->get(); dd($posts);

Note that what we call here is posts Method, not a dynamic property posts The corresponding output is:

 user-posts

Similarly, we can use the article model Post The user model of the article is defined in User Correspondence of:

 public function author() { return $this->belongsTo('App\User','user_id','id'); }

Notice that we are belongsTo An additional parameter was passed into the method, meaning posts In the table user_id corresponding users In the table id If we define a method named user , you do not need to pass in these parameters:

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

As we mentioned in the one-to-one relationship above, this is because if we call belongsTo Method if the fourth parameter is not passed in $relation , the current call is used by default belongsTo The method name of the $relation , when no second parameter is passed in $foreign_key Use $relation.'_ id' As $foreign_key (If $relation If the hump style is named and includes uppercase letters, convert the uppercase letters to lowercase letters and add _ )。 Therefore, if the method name is user , corresponding to $foreign_key by user_id If the method name is author , do not specify foreign key user_id Corresponding $foreign_key by author_id , and author_id stay posts The table does not exist, so the corresponding association model can never be found.

We can obtain the user model instance corresponding to the specified article in the following way:

 $author = Post::find(1)->author; dd($author);

Page output as:

 post-author

3. Many to many

Another common association relationship is many to many, that is, a record in Table A is associated with multiple records in Table B through the middle table C, and vice versa. For example, a user has multiple roles, whereas a role corresponds to multiple users.

To test the association, we create a role table roles , and add some initialization data:

 User Role Table roles

At the same time, we create an intermediate table role_user For recording users Table and roles Table correspondence:

 Middle table role_user

Note that when we define the intermediate table, we do not add s at the end, and the naming rule is in alphabetical order, with roles at the front and users at the back, separated by _. All this is to adapt to the default settings of Eloquent model association: if no intermediate table is specified when defining many to many associations, Eloquent's default intermediate table is spliced using this rule.

Then we will create a Role Model:

 php artisan make:model Models/Role

Here we are In User Define many to many associations as follows:

 public function roles() { return $this->belongsToMany('App\Models\Role'); }
Note: As we mentioned above, if the intermediate table is not role_user , the intermediate table needs to be passed in as the second parameter belongsToMany Method, if the field in the intermediate table is not user_id and role_id , let's name it $user_id and $role_id , then you need to $user_id The method is passed in as the third parameter, $role_id The method is passed in as the fourth parameter. If the associated method name is not roles You can also pass the corresponding associated method name into the method as the fifth parameter.

Next, we write test code in the controller:

 $user = User::find(1); $roles = $user->roles; Echo 'User #'. $user ->name. 'Roles owned by:
'; foreach($roles as $role) { echo $role->name.'
'; }

The corresponding output is:

 User # Larravel has the following roles: writer reader

Relatively, we can also Role Get corresponding defined in User Model method:

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

The test code is as follows:

 $role = Role::find(4); $users = $role->users; Echo 'Role #'. $role ->name. 'Users below:
'; foreach ($users as $user) { echo $user->name.'
'; }

The corresponding output is:

 Users under Role # reader: Laravel Academy

In addition, we can also use dynamic attributes pivot Get the fields of the intermediate table:

 $roles = User::find(1)->roles; foreach ($roles as $role) { echo $role->pivot->role_id.'
'; }

The corresponding output is:

 three four

Let's talk about this section first, Next section We will discuss three more complex relationships and their definitions and uses in the model.


give the thumbs-up Cancel Like Collection Cancel Collection

<<Previous: Eloquent ORM Instance Tutorial - Query Scope and Model Events

>>Next: Eloquent ORM Instance Tutorial - Association Relationship and Its Definition in the Model (II)