一對一
在上一篇文章中新建了一個‘user'和’profile‘表,一個用戶對應(yīng)一個用戶的詳細(xì)資料,此為一對一的關(guān)系。
在database/migrations/1532938278888_profile_schema.js
中修改表格結(jié)構(gòu):
'use strict'
const Schema = use('Schema')
class ProfileSchema extends Schema {
up () {//創(chuàng)建時執(zhí)行內(nèi)容
this.create('profiles', (table) => {
table.increments() // id字段
//這里是手動添加的---------
table.string('userNick')
table.string('introduction')
table.integer('age')
table.integer('user_id').unsigned()
table.foreign('user_id').references('users.id')
/* 將 user_id 與 users 表格中的id關(guān)聯(lián)起來,
由于創(chuàng)建表格會默認(rèn)在最后添加's',
所以 user 表格在這里寫作 'users' */
//---------------------------------
table.timestamps()
})
}
down () {//回滾時執(zhí)行內(nèi)容
this.drop('profiles')
}
}
module.exports = ProfileSchema
然后,可以將之前創(chuàng)建好的表格手動刪除后再重新'adonis migration:run' 重新創(chuàng)建有關(guān)聯(lián)關(guān)系的表格。然后創(chuàng)建seeder插入數(shù)據(jù)。
'use strict'
const Factory = use('Factory')
const Profile = use('App/Models/Profile')
class ProfileSeeder {
async run() {
const profile = [{
userNick: '尼基塔·謝爾蓋耶維奇·赫魯曉夫',
age: 76,
introduction: '吃玉米吧',
user_id: 1,
},
{
userNick: '列昂尼德·伊里奇·勃列日涅夫',
age: 76,
introduction: '別說話,看我的勛章',
user_id: 2,
},
]
await Profile.createMany(profile)
}
}
module.exports = ProfileSeeder
λ adonis seed --files ProfileSeeder.js
Seeded database in 208 ms
在'app/Models/User.js'中,添加一個方法,使用'hasOne'來描述這個一對一的關(guān)系。
……
class User extends Model {
profile(){
return this.hasOne('App/Models/Profile')
}
……
}
……
當(dāng)然,還有個belongsTo
的關(guān)系,是hasOne
關(guān)系的反向關(guān)聯(lián),可以在Profile
中定義其屬于User
。
一對多
一個用戶是多個文章的作者,這便構(gòu)成了一對多的關(guān)系。
跟一對一一樣,創(chuàng)建一個article的模型和遷移,并使用seed填充數(shù)據(jù)。再到App/Models/User.js
中添加一個方法,使用hasMany
來描述一對多的關(guān)系。
……
class User extends Model {
//這是之前添加的一對一的關(guān)系
profile(){
return this.hasOne('App/Models/Profile')
}
//這是新添加的一對多的關(guān)系
article(){
return this.hasMany('App/Models/Article')
}
……
}
……
多對多
一篇文章可以對應(yīng)多個標(biāo)簽,一個標(biāo)簽又可以用于多篇文章。這就是多對多的關(guān)系。
通過以下語句生成、填充一個tags表格。
adonis make:migration tag //構(gòu)建遷移
……
adonis make:model tag //構(gòu)建模型
……
adonis make:seed tag //生成seeder用于填充
……
adonis migration:run //運行遷移,生成表格(空)
……
adonis seed --files TagSeeder.js //運行seeder文件填充表格
……
為了創(chuàng)建一個多對多的關(guān)系,我們需要創(chuàng)建一個中間表,這個中間表有個專門的名詞“pivot”,其中記錄文章id以及標(biāo)簽id。
創(chuàng)建pivot migration,以及用于填充的seeder。
λ adonis make:migration article_tag
> Choose an action Create table
√ create database\migrations\1533003492037_article_tag_schema.js
λ adonis make:seed article_tag_pivot
√ create database\seeds\ArticleTagPivotSeeder.js
在database/migrations/1533003492037_article_tag_schema.js
文件中,添加兩個外鍵,分別與文章id以及標(biāo)簽id相關(guān)聯(lián)。
'use strict'
const Schema = use('Schema')
class ArticleTagSchema extends Schema {
up () {
this.create('article_tag', (table) => {
table.increments()
table.integer('article_id').unsigned()
table.foreign('article_id').references('articles.id')
table.integer('tag_id').unsigned()
table.foreign('tag_id').references('tags.id')
})
}
down () {
this.drop('article_tag')
}
}
module.exports = ArticleTagSchema
然后再在database/seeds/ArticleTagPivotSeeder.js
中進(jìn)行數(shù)據(jù)填充。因為這次沒有創(chuàng)建模型,所以填充與之前略有不同:
'use strict'
const Factory = use('Factory')
const Database = use('Database')
class ArticleTagPivotSeeder {
async run () {
await Database.table('article_tag').insert([
{article_id:1,tag_id:1},
{article_id:1,tag_id:4},
{article_id:3,tag_id:2},
{article_id:4,tag_id:2},
{article_id:2,tag_id:3},
])
}
}
module.exports = ArticleTagPivotSeeder
App/Models目錄下的 Article.js 以及 Tag.js 中分別添加:
//-----Article.js
class Article extends Model {
tags(){
return this.belongsToMany('App/Models/Tag')
}
}
//-----Tag.js
class Tag extends Model {
article(){
return this.belongsToMany('App/Models/Article)
}
}
之后運行遷移并運行對應(yīng)seeder文件。