Adonis.js——數(shù)據(jù)庫關聯(lián)

一對一

上一篇文章中新建了一個‘user'和’profile‘表,一個用戶對應一個用戶的詳細資料,此為一對一的關系。
database/migrations/1532938278888_profile_schema.js中修改表格結構:

'use strict'
const Schema = use('Schema')
class ProfileSchema extends Schema {
  up () {//創(chuàng)建時執(zhí)行內容
    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關聯(lián)起來,
      由于創(chuàng)建表格會默認在最后添加's',
      所以 user 表格在這里寫作 'users' */
      //---------------------------------
      table.timestamps()
    })
  }
  down () {//回滾時執(zhí)行內容
    this.drop('profiles')
  }
}
module.exports = ProfileSchema

然后,可以將之前創(chuàng)建好的表格手動刪除后再重新'adonis migration:run' 重新創(chuàng)建有關聯(liá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'來描述這個一對一的關系。

……
class User extends Model {
  profile(){
    return this.hasOne('App/Models/Profile')
  }
   ……
}
……

當然,還有個belongsTo的關系,是hasOne關系的反向關聯(lián),可以在Profile中定義其屬于User

一對多

一個用戶是多個文章的作者,這便構成了一對多的關系。
跟一對一一樣,創(chuàng)建一個article的模型和遷移,并使用seed填充數(shù)據(jù)。再到App/Models/User.js中添加一個方法,使用hasMany來描述一對多的關系。

……
class User extends Model {
  //這是之前添加的一對一的關系
  profile(){
    return this.hasOne('App/Models/Profile')
  }
  //這是新添加的一對多的關系
  article(){
    return this.hasMany('App/Models/Article')
  }
  ……
}
……

多對多

一篇文章可以對應多個標簽,一個標簽又可以用于多篇文章。這就是多對多的關系。
通過以下語句生成、填充一個tags表格。

adonis make:migration tag //構建遷移
……
adonis make:model tag //構建模型
……
adonis make:seed tag //生成seeder用于填充
……
adonis migration:run //運行遷移,生成表格(空)
……
adonis seed --files TagSeeder.js //運行seeder文件填充表格
……

為了創(chuàng)建一個多對多的關系,我們需要創(chuàng)建一個中間表,這個中間表有個專門的名詞“pivot”,其中記錄文章id以及標簽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以及標簽id相關聯(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中進行數(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)
  }
}

之后運行遷移并運行對應seeder文件。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容