Bookshelf.js - 如何从关联表中获取列?

3

我有一个用户模型和一个课程模型,它们之间存在多对多的关系,因此基本上用户可以加入多个课程,而课程也有许多用户(学生)。我有一个连接表,并且正在尝试向连接表添加其他信息。基本上,用户每月可以在每门课程中提出一定数量的问题。因此,我已将一个配额列添加到User_Course连接表中。我无法访问配额列。以下是相关代码,以便了解。

var User = DB.Model.extend({
    Courses: function() {
        return this.belongsToMany('Course', 'User_Course', 'userId', 'courseId');
    },
});

var Course = DB.Model.extend({
    Users: function() {
        return this.belongsToMany('User', 'User_Course', 'courseId', 'userId');
    }
})

而 User_Course 是我的连接表,它还有一个额外的配额列:

**User_Course:**
userId: int
courseId: int
quota: int

我希望能够减少我的配额值。我可以使用updatePivot来更新它,但我无法获取当前配额值。这是我用来更新值的代码:

var userPromise = new User.User({userId: userId}).fetch({withRelated: ['Courses']});
userPromise.then(function(_user) {
    _user.related('enrolledCourses').updatePivot({courseId:courseId, quota:1}).then(function() {
        return;
    })

})

正如您所看到的,我在这里每次都将配额值更新为1。我想以编程方式确定当前的配额值,然后对其进行递减。

2个回答

8
尝试使用withPivot。例如,return this.belongsToMany(Comment).withPivot(['created_at', 'order']);你可以在这里放置你的配额,并在加载关系时获取它。 更新: 好的,这里有一个例子:
    new Town().where({
            town_number: 2301
        }).fetchAll({
            columns: ['town_title', 'id'],
            withRelated: [{
                'address': function(qb) {
                    qb.select('addresses.town_id', 'addresses.participant_id');
                    qb.columns('addresses.street_name');
                    // here you could simply do qb.where({something_id: 1}); as well
                }
            }]
        }).then(function(result) {
            res.json(result);
        });

基本上,您不仅可以使用 withRelated: ['table_name'],而且可以将该表名定义为一个对象,包含属性 table_name 和值为 function 的查询构建器 (qb),从而可以单独查询该表。希望能帮到您!

感谢您的帮助!因此,我相信在我的情况下,您展示的语句将如下所示:return this.belongsToMany('Course', 'User_Course', 'userId', 'courseId').withPivot(['quota']),但我认为这试图给我返回与用户相关的所有课程,而我想要返回给定课程ID和用户ID中配额列中的数字。 - kaustubhb
你也可以在查询时进行限制。只需在 withRelated 语句中传递查询属性即可。 - uglycode
你能否编辑你的回答,提供一个更完整的例子?我正在尝试使用withRelated语句,但我不确定是否使用正确。我认为withRelated需要一个模型,比如“comments”,然后返回相关的对象。当我想要传递参数,比如“courseId=1”和“userId=2”,以便获取配额列中的值时,该怎么办呢?抱歉,我仍在努力理解bookshelf,我对它还很陌生。 - kaustubhb
好的,我已经编辑了我的回复。希望这能消除一些困惑! - uglycode
谢谢!我稍后会看一下这个,但它已经教给我一些新东西了。我不知道 withRelated 可以那样输入。虽然不是必要的,但如果您能向我解释使用 bookshelf 函数的好处与使用 knex 中原始 SQL 查询的缺点,我也会很感激的。再次感谢! - kaustubhb
没问题!我对Bookshelf(以及其构建在其上的Knex)的内部运作不是很熟悉,但我认为如果你在Bookshelf模型中混合使用knex,性能方面没有实质性的差异。我想,仅使用Knex可能会加快程序速度,因为你可以更好地控制哪些表格正在连接(以及如何连接)。我个人喜欢尽可能多地使用Bookshelf,并仅在特定问题上使用Knex。 - uglycode

0
直到我学会更合适的方法,我使用knex.raw来使用mysql语句减少配额列。在我的控制器中,我调用decrementQuota并传入userId和courseId:
function decrementQuota(userId, courseId) {
    new User.User({userId: userId}).decrementQuota(userId, courseId);
}

在我的用户模型中,knex.raw调用更新User_Course,通过减少配额的值。
var User = DB.Model.extend({
    decrementQuota: function(uid, cid) {
        DB.knex.raw('update User_Course set quota = quota -1 where userId=' + uid + ' and courseId=' + cid).then(function(quota) {

        });
    },
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接