如何在Sails中实现多对多关联?

时间:2016-01-02 21:07:10

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

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

然而,谷歌搜索我发现这个Waterline Github Issue elennaro ,一个github用户,给了我一些链接和一些例子:

  1. First one
  2. Second one
  3. 我试图让它们适应我自己的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之后。

    知道我为什么会收到此错误?

    欢迎任何形式的帮助!

1 个答案:

答案 0 :(得分:1)

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

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

基本上我要做的是为 NodeJS SailsJS Waterline 安装最新版本。

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

  • Node v5.3.0
  • Sails 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的支持!

如有任何问题,请发表评论!