Bookshelf.js - 如何从连接表中获取列?

Posted

技术标签:

【中文标题】Bookshelf.js - 如何从连接表中获取列?【英文标题】:Bookshelf.js - How to get a column from join table? 【发布时间】:2015-05-09 16:01:41 【问题描述】:

我有一个 User 模型和一个 Course 模型,它们是多对多的关系,所以基本上用户可以加入多个课程并且课程有很多用户(学生)。我有一个连接表,我正在尝试向连接表添加其他信息。基本上,用户每个月都有一个每月可以提出的问题配额。所以我在 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。我想以编程方式确定当前配额值是多少,然后递减它。

【问题讨论】:

【参考方案1】:

试试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_namefunction 作为一个值,它有一个查询构建器(qb),您可以查询那张桌子分开。

希望这会有所帮助!

【讨论】:

感谢您的帮助!因此,我相信在我的情况下,您显示的语句如下所示:return this.belongsToMany('Course', 'User_Course', 'userId', 'courseId').withPivot(['quota']),但我相信这是试图为我提供与用户相关的所有 课程,当我只想返回时给定 courseId 和 userId 的配额列中的数字。 查询时也可以限制。只需在 withRelated 语句中传递查询属性 你能用更完整的例子来编辑你的答案吗?我正在玩 withRelated 语句,但我不确定我是否正确使用它。我认为 withRelated 采用模型,即“cmets”并返回相关对象。当我想传入参数时,即“courseId=1”和“userId=2”以取回配额列中的值。对不起,我还在努力理解书架,我对它很陌生。 好的,我已经编辑了我的回复。希望这能消除一些困惑! 谢谢!今天晚些时候我会看这个,但它已经教会了我一些新的东西。我不知道 withRelated 可以这样输入。它不是必需的,但如果您能向我解释使用 bookshelfs 函数的好处与在 knex 中使用原始 sql 查询的缺点,我将不胜感激。再次感谢!【参考方案2】:

直到我学会了一种更合适的方法来执行此操作,我使用 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) 

        );
    ,
)

【讨论】:

以上是关于Bookshelf.js - 如何从连接表中获取列?的主要内容,如果未能解决你的问题,请参考以下文章

Bookshelf.js belongsToMany 查询列错误

如何使用 MYSQL 中的连接从多个表中获取多个列并在非空列上显示数据以及在空列上显示 null 或零

Bookshelf.js/Knex.js 对 UTC DATETIME 列太“有用”

Bookshelf.js 查询相关表行

如何从两个表中获取数据以进行登录

如何监听 Bookshelf.js 模型中的属性何时更新?