【问题标题】:How to implement many to many association using through in Sails?如何在 Sails 中使用 through 实现多对多关联?
【发布时间】:2016-01-02 21:07:10
【问题描述】:

我在 Mac OS X El Capitan 上使用 Sails v0.11.2MongoDB 3.2,我正在尝试实现 Many-To-Many 使用尚不支持的 Through 选项进行关联。

但是,通过谷歌搜索我发现了这个Waterline Github Issueelennaro,一个 github 用户,给了我几个链接和一些例子:

  1. First one
  2. Second one

我已尝试将它们调整为我自己的 Sails 应用程序,但我无法使其正常工作。我在控制台上没有错误,但记录或document on the intermediary table is not created 只有Form 表中的文档。

这些是我的模型:

User.js

module.exports = {
    schema: true,
    tableName: 'users',
    autoCreatedAt: false,
    autoUpdatedAt: false,

    attributes:
    {
        email               : { type: 'email', required: true, unique: true },
        encrypted_password  : { type: 'string' },
        reset_password_token: { type: 'string', defaultsTo: null},
        permission_level    : { type: 'integer', required: true, min: 1, max: 3, defaultsTo: 0 },
        belongs_to          : { type: 'string', required: true, defaultsTo: 0 },
        signin_count        : { type: 'integer', required: true, defaultsTo: 1 },
        status_active       : { type: 'boolean', required: true, defaultsTo: false },
        last_signin_at      : { type: 'datetime', defaultsTo: function (){ return new Date(); } },
        last_signin_ip      : { type: 'string', defaultsTo: '0.0.0.0' },

        // Add a reference to Person
        person_id:
        {
            model: 'person'
        },
        // Add a reference to Forms collection
        forms:
        {
            collection: 'form',
            via: 'user_id',
            through: 'userhasform'
        },
        has:
        {
            collection: 'userhasform',
            via: 'form_id'
        }
    }

};

Form.js

module.exports = {
    schema: true,
    tableName: 'forms',

    attributes:
    {
        name    : { type: 'string', required: true, unique: true },
        creator : { type: 'string', unique: false },
        sequence: { type: 'integer', autoIncrement: true },

        // Add a reference to Questions collection
        questions:
        {
            collection: 'question',
            via: 'form_id'
        },
        // Add a reference to the owners Users
        owners: {
            collection: 'user',
            via: 'form_id',
            through: 'userhasform'
        }
    }

};

UserHasForm.js

module.exports = {
    schema: true,
    tableName: 'users_have_forms',

    attributes:
    {
        to_edit     : { type: 'boolean' },
        to_delete   : { type: 'boolean' },
        user_id     : { model: 'user' },
        form_id     : { model: 'form' }
    }

};

我在其中创建表单并且假设在连接表中创建中间文档的控制器是:

FormController.js

module.exports = {
    create: function (req, res)
    {
        var ownerJson = {},
            tmpFolio;

        // Get the logged user to make the Folio and then create the form
        SessionService.getUser(req, createForm);
        // Callback function
        function createForm (err, session)
        {
            // If there's no logged user or any error
            if (err || !session)
            {
                console.log(err);
                return res.json(err.status, {error: err});
            }

            console.log('User to create Folio: ', session.id);

            ownerJson.owner_a = session.first_name;
            ownerJson.owner_b = session.second_name;
            ownerJson.owner_c = session.last_name;
            // Construct the Folio creator part like AVC
            tmpFolio = FolioService.generateFolio(ownerJson);

            Form.create({
                name: req.body.name,
                creator: tmpFolio
            })
            .then(function (form){
                if (err)
                {
                    console.log(err);
                    return res.json(err.status, {error: err});
                }

                // Create the jointable record
                var createdRecord = UserHasForm.create({
                        to_edit: true,
                        to_delete: true,
                        user_id: session.id,
                        form_id: form.id
                    })
                    .then(function (createdRecord){
                        if (err)
                        {
                            console.log(err);
                            return res.json(err.status, {error: err});
                        }

                        return createdRecord;
                    });

                return [form, createdRecord];
            })
            .spread(function (form, createdRecord){
                return res.json(200,
                {
                    message: 'The form was created successfuly!',
                    data: form,
                    sharing: createdRecord
                });
            })
            .fail(function (err){
                if (err)
                {
                    console.log(err);
                    res.json(err.status, {error: err});
                }
            });
        }
    },

};

当我运行这段代码时,我得到了下一个错误:

[ReferenceError: UserHasForm is not defined]
Unhandled rejection TypeError: Cannot read property 'toString' of undefined

所以我想它找不到模型所以我在开头的模型中添加下一行:

var UserHasForm = require('../models/UserHasForm');

现在我得到下一个错误:

[TypeError: UserHasForm.create is not a function]

所有这些都在列表中的the first example之后。

知道为什么会出现此错误吗?

欢迎任何形式的帮助!

【问题讨论】:

  • 我添加了一个没有名为 UserHasFormController 的方法的新控制器。但它仍然是同样的错误。
  • 我一直在寻找主要错误,我发现的只是当我使用引用此模型的 through: 'userhasform' 语句时出现此错误(中介UserHasForm) 来自任何其他型号。如果我退出其他模型的引用,它会完美运行,并且我可以在该表上创建记录。那么这句话有什么问题呢?
  • 查看型号列表:sails.model - 你在那里看到了什么?
  • @AlexanderArutinyants 很抱歉,我不明白你的意思。请你能再解释一下吗?感谢您的帮助。
  • 查看型号列表:sails.model - 你在那里看到了什么?您应该在使用关系表时准确地命名关系表:因此您最好将User_Has_Form.js 重命名为UserHasForm.js 或明确设置identityglobalId。请参阅文档:sailsjs.org/documentation/concepts/models-and-orm/…

标签: node.js many-to-many associations waterline sails-mongo


【解决方案1】:

在尝试了许多示例之后,我终于找到了解决方案,感谢@elennaro 的所有支持。整个对话可以在我们俩在主要问题的 cmets 下开始的聊天链接中找到。

另外我可以告诉你,他提供的链接中的示例(在上面的问题中)工作正常,问题是我使用的版本不支持这些示例显示的功能。

基本上我要做的就是为 NodeJSSailsJSWaterline 安装最新版本。

在我的情况下,我实际上有下一个:

  • 节点 v5.3.0
  • 帆 v0.11.3
  • Waterline v0.10.30

之后我必须对我的模型进行一些更改,最后它们看起来像这样:

User.js

module.exports = {

    schema: true,
    tableName: 'users',
    autoCreatedAt: false,
    autoUpdatedAt: false,

    attributes:
    {
        // username         : { type: 'string', unique: true, minLength: 5, maxLength: 15 },
        email               : { type: 'email', required: true, unique: true },
        encrypted_password  : { type: 'string' },
        reset_password_token: { type: 'string', defaultsTo: null},
        permission_level    : { type: 'integer', required: true, min: 1, max: 3, defaultsTo: 0 },
        belongs_to          : { type: 'string', required: true, defaultsTo: 0 },
        signin_count        : { type: 'integer', required: true, defaultsTo: 1 },
        status_active       : { type: 'boolean', required: true, defaultsTo: false },
        last_signin_at      : { type: 'datetime', defaultsTo: function (){ return new Date(); } },
        last_signin_ip      : { type: 'string', defaultsTo: '0.0.0.0' },

        // Add a reference to Forms collection
        forms:
        {
            collection: 'form',
            via: 'user',
            through: 'userhasform'

            // dominant: true
        }
    }

};

Form.js

module.exports = {

    schema: true,
    tableName: 'forms',

    attributes:
    {
        name    : { type: 'string', required: true, unique: true },
        creator : { type: 'string', unique: false },
        sequence: { type: 'integer', autoIncrement: true },

        // Add a reference to the owners Users
        owners: {
            collection: 'user',
            via: 'form',
            through: 'userhasform'
        }
    }

};

UserHasForm.js

module.exports = {

    schema: true,
    tableName: 'users_have_forms',

    attributes:
    {
        to_edit     : { type: 'boolean' },
        to_delete   : { type: 'boolean' },
        user        : { model: 'User', foreignKey: true, columnName: 'user_id' },
        form        : { model: 'Form',  foreignKey: true, columnName: 'form_id' }
    }

};

FormController.js

Still the same as in the question

我希望它对任何人都有用。再次感谢 @Alexander Arutinyants 的支持!

有任何问题,请留言!

【讨论】:

  • @elennaro 示例位于 github
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多