Adonis.js——數據庫關聯

一對一

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

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

然後,可以將之前創建好的表格手動刪除後再重新'adonis migration:run' 重新創建有關聯關係的表格。然後創建seeder插入數據。

'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關係的反向關聯,可以在Profile中定義其屬於User

一對多

一個用戶是多個文章的作者,這便構成了一對多的關係。
跟一對一一樣,創建一個article的模型和遷移,並使用seed填充數據。再到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文件填充表格
……

爲了創建一個多對多的關係,我們需要創建一箇中間表,這個中間表有個專門的名詞“pivot”,其中記錄文章id以及標籤id。
創建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相關聯。

'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中進行數據填充。因爲這次沒有創建模型,所以填充與之前略有不同:

'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文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章