簡體   English   中英

如何在書架中自我引用多對多關系

[英]How to do a Self-Referencing Many-to-Many Relationship in Bookshelf

我正在嘗試在Bookshelf.Js中找出最明確和最正確的方法,為User模型建立多對多關系,以構建許多社交應用程序中存在的標准關注者/關注關系。 不過,Bookshelf中的文檔讓我陷入了困境。

我可以看到兩種可能的方法:1)單獨使用belongsToMany() ,或2)使用belongsToMany() throught() 兩者都沒有為我工作,但讓我先告訴你我正在做些什么(1)。 我從這個模型設置開始:

const User = bookshelf.Model.extend({
  tableName: 'users',
  initialize: function() {
    this.on('creating', this.encryptPassword);
  },
  hasTimestamps: true,
  posts: function() {
    return this.hasMany(Posts, 'author');
  },
  comments: function() {
    return this.hasMany(Comments);
  },
  following: function() {
    return this.belongsToMany(UserFollow, 'users_users', 'follower_id', 'user_id');
  },
  followers: function() {
    return this.belongsToMany(UserFollow, 'users_users', 'user_id', 'follower_id');
  },
});

為了匹配我有一個knex遷移,添加了一個users_users表,如下所示:

exports.up = function(knex, Promise) {
  return knex.schema.createTable('users_users', (tbl) => {
    tbl.integer('user_id').references('users.id');
    tbl.integer('follower_id').references('users.id');
    tbl.unique(['user_id', 'follower_id']);  
      // This b/c I read a few places that Bookshelf might require a composite key.
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('users_users');
};

然后我有以下測試:

it('User model can record a follower', (done) => {
    const saveUsr = (data) => {
      return User.forge().save(data, {transacting: transaction});
    };
    Promise.all([saveUsr(mockUser), saveUsr(anotherMockUser)])
      .then((results) => {
        let usr1 = results[0];
        let usr2 = results[1];
        return usr2.followers().attach(usr1.id, {transacting: transaction});
      })
      .then((usrWithFollower) => {
        return usrWithFollower.fetch({
          withRelated: ['followers'],
          transacting: transaction
        });
      })
      .then((usr) => {
        console.log(JSON.stringify(usr));
        console.log('followers: ', usr.get('followers'));
        done();
      })
      .catch((err) => { done(err); });
   });

我在這里測試的並不多,因為我無法獲得該功能,但是最后一個承諾中的JSON.stringify(user)的結果是回調如下:

[
   {
      "id":1,
      "name":"Sally Low",
      "username":"sally",
      "email":"sally@example.org",
      "created_at":"2016-06-05T15:24:41.835Z",
      "updated_at":"2016-06-05T15:24:41.835Z",
      "password":"$2a$10$613tL/baML9obsRN4Yg7MeU/2RiH7oK/nFUwfpQ1GYuA15VUFrFZu",
      "followers": [],
      "_pivot_user_id":2,
      "_pivot_follower_id":1
   }
]

正如你所看到的,看起來似乎已經設置了某種關系,因為有這些_pivot_道具,但它們對我來說並不清楚,而且我不確定為什么followers領域_pivot_回空洞。

如果有人能讓我直截了當或以任何方式闡明情況,我會非常感激。

我認為那些UserFollow模型是User別名。 這不是必需的。

嘗試添加Registry Plugin並將您的User模型編寫為:

const User = bookshelf.Model.extend({
  tableName: 'users',
  // ...
  following: function() {
    return this.belongsToMany('User', 'users_users', 'follower_id', 'user_id');
  },
  followers: function() {
    return this.belongsToMany('User', 'users_users', 'user_id', 'follower_id');
  },
});
bookshelf.model('User', User);

attach()代碼可以直接使用模型,不需要使用id

usr2.followers().attach(usr1);

我制作了模式的最小版本並嘗試:

new User({name: 'Bia'}).
  fetch({withRelated: 'followers'}).
  then((m) => {console.log(m.toJSON());});

這讓我回答:

{ name: 'Bia',
   id: 3,
   followers: 
    [ { id: 1, name: 'Ana', _pivot_user_id: 3, _pivot_follower_id: 1 },
      { id: 2, name: 'Mia', _pivot_user_id: 3, _pivot_follower_id: 2 } ] }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM