Eloquent ORM Instance Tutorial - Association Relationship and Its Definition in the Model (I)
![guide-to-eloquent-orm](https://laravel.gstatics.cn/wp-content/uploads/2015/09/guide-to-eloquent-orm.jpg)
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](https://laravel.gstatics.cn/wp-content/uploads/2015/09/user-accounts.png)
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](https://laravel.gstatics.cn/wp-content/uploads/2015/09/2015-09-28_220528.jpg)
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](https://laravel.gstatics.cn/wp-content/uploads/2015/09/2015-09-28_220906.jpg)
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](https://laravel.gstatics.cn/wp-content/uploads/2015/09/2015-09-28_222037.jpg)
At the same time, we create an intermediate table role_user
For recording users
Table and roles
Table correspondence:
![Middle table role_user](https://laravel.gstatics.cn/wp-content/uploads/2015/09/2015-09-28_222156.jpg)
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.