Jon Garbayo
Jon Garbayo

Reputation: 105

Sails.js and Waterline: dynamic validation by DB request

I use Sails 11.1 and Waterline 2.11.2 with a MongoDB database.

I would like to validate data inserted in my "Article" model using a in validator for 1 attribute. Before, I was doing the job with lifecycle callbacks (beforeCreate and beforeUpdate especially), but it makes double code.

Here you have the model, truncated with just the attribute in question :

module.exports =
{
    schema: true,

    autoCreatedAt: false,
    autoUpdatedAt: false,

    attributes:
    {
        theme:
        {
            model: 'Theme',
            required: true
        }
    }
}

I know how to define it statically:

in: ['something', 'something other']

I know how to call constants I defined in my constants.js file :

defaultsTo: function ()
{
    return String(sails.config.constants.articleDefaultTheme);
}

But I would like to get all themes in my DB, to have a dynamic in validation. So, I wrote this :

theme:
{
    model: 'Theme',
    required: true,
    in: function () 
    {
        Theme.find()
        .exec(function (err, themes) 
        {
            if (err)
            {
                return next({ error: 'DB error' });
            }
            else if (themes.length === 0)
            {
                return next({ error: 'themes not found' });
            }
            else
            {
                var theme_ids = [];

                themes.forEach(function (theme, i)
                {
                    theme_ids[i] = theme.theme_id;
                });

                return theme_ids;
            }
        });
    }
}

But it's not working, I have always the "1 attribute is invalid" error. If I write them statically, or if I check in the beforeCreate method with another DB request, it works normally. If I sails.log() the returned variable, all the themes ids are here.

I tried to JSON.stringify() the returned variable, and also to JSON.parse(JSON.stringify()) it. I also tried to convert the theme.theme_id as a string with the String() function, but nothing else...

What am I doing wrong? Or is it a bug?

You can also check my question here : Waterline GitHub issues

Upvotes: 3

Views: 508

Answers (1)

Andi N. Dirgantara
Andi N. Dirgantara

Reputation: 2051

Models's configuration at your attributes scope at in field of course will throw an error, because it should not use a function, especially your function is not return anything, also if you force it to return something, it will return Promise that Theme.find()... did.

Try use different approach. There are exist Model Lifecycle Callbacks. You can use something like beforeCreate, or beforeValidate to manually checking your dynamic Theme, if it's not valid, return an error.

Or if it's achievable using standard DB relation, just use simple DB relation instead.

Upvotes: 2

Related Questions