Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9042

BookShelfアノテーションで複数取得する方法で迷ったのでアウトプットする。

$
0
0

はじめに

BookShelfを使ったデータの取り込みで、データベースの依存関係が複数ある場合の
クエリ取得方法で迷ったので、やった内容をアウトプットする。
その為、説明等は適当な部分多い。

作成していたアプリは、ルーム毎にユーザとメッセージを保存する。
メッセージ交換用アプリ

Bookshelfとは

Node.jsとかで使えるデータベースに対して、データを取得できる便利な道具です。

アノテーションについて

DBのテーブル同士を関連づけて取得できるものになります。

 var Room = Bookshelf.Model.extend({
   tableName: 'rooms',
   hasTimestamps: true,
   messages: function() {
     return this.hasMany(Message);
  }
 });

アノテーションに当たる部分

  • hasMany : 一対多(Roomテーブルの1行に紐づくMessageテーブルの行は多数あるって意味)
  • belongsTo : 一対一(MessageとUserテーブルで紐づくデータは1行に対して1行のみ)
//Roomテーブルを取得する際に紐ずいているMessageテーブルのデータを取得する。

   messages: function() {
     return this.hasMany(Message);
  }

DBの構成

  • こんなかんじ Image from Gyazo

階層アノテーション取得方法

  • それぞれのテーブル定義
var Bookshelf = require('bookshelf')(knex);

var User = Bookshelf.Model.extend({
  tableName: 'users'
});

var Room = Bookshelf.Model.extend({
  tableName: 'rooms',
  hasTimestamps: true,
  messages: function() {
    return this.hasMany(Message);
  }
});

var Message = Bookshelf.Model.extend({
  tableName: 'messages',
  hasTimestamps: true,
  user: function() {
    return this.belongsTo(User);
  }
});

結局のところ、一対多のデータから、さらに一対一のデータを取り出すには、fetchでwithRelatedで
'message.user'のように、Roomテーブルでアソシエーションとして指定したmessageからさらにMessageでアソシエーションした
userを指定するとデータとして取得できる。

/**
*     RoomテーブルからroomIdを紐づけてMessageテーブルのデータを取得
*                    Messageテーブルからい1対1関係のデータを取得する。
**/

                  new Room().query({where:{id : roomId}})
                          .fetch({withRelated:['messages','messages.user']})
                          .then((messageRoom) => {

                            res.render('chat',{
                              roomName: messageRoom.attributes.room_name,
                              roomId : messageRoom.attributes.id,
                              userName: login.name,
                              userId: login.id,
                              message: messageRoom.relations.messages.models
                            });


                            var messageTests = messageRoom.relations.messages.models;

                            for(var val of messageTests){

                              console.log(val.attributes.message);
                            }

                          });

また、一対多の時にデータを取得する場合は、
room.relations.messages.modelsというようにいったんmodelsを指定してから
attributes.[カラム名]といった形でデータを取得する。
一対一の場合には、messages.relations.user.attributes.[カラム名]という形にすればいい。

初めてQiita書いたので、間違っている事もあると思われますが、ご了承ください。


Viewing all articles
Browse latest Browse all 9042