2015-04-17 4 views
2

Я довольно новичок в sails.js, а также node.js, поэтому это может быть не особый вопрос Sails, но я создал модель User and Tag, У пользователя много тегов и наоборот. Соответствующие атрибуты пользовательской модели являются:Создайте и добавьте в коллекцию, если она не существует. Sails.js

# models/User.js 
tags  : { collection: 'Tag', via: 'users' }, 
add_tag: function(name) { 
    var self = this; 
    Tag.findOne({ name: name }) 
    .then(function(found){ 
    if(found) { 
     sails.log.info('found tag ' + found) 
     found.users.add(self.id); 
     self.save(sails.log.info); 
    } else { 
     sails.log.info('didnt find tag, creating with ' + self.id + ' and ' + name); 
     Tag.create({ name: name, users: [ self.id ] }).exec(console.log); 
    } 
    }); 
}, 

И модели Tag:

name  : { type: 'string', required: true, index: true }, 
users : { collection : 'User', via: 'tags' }, 

Теперь, когда я бегу sails console я использую следующий тест:

sails> var user = null; User.find().exec(function(err, u) { user= u[0]; }); 
undefined 
sails> user.add_tag('cataclysmic'); 
undefined 
sails> info: didnt find tag, creating with 2 and cataclysmic 

и там висит пока я не нажму Enter или Ctrl + C, и не будет создан тег.

Снова я очень новичок в Node and Sails, исходя из фона Rails, поэтому это может быть что-то очень глупое. Кроме того, если я не правильно использую обещания, сообщите мне, так как я тоже очень к ним отношусь.

Update

предложение Per Трэвис Уэбб, я попытался преобразовать в findOrCreate и это все еще не работает, к сожалению:

add_tag: function(name) { 
    var self = this; 
    Tag.findOrCreate({ name: name }) 
    .then(function(tags){ 
    sails.log.info(JSON.stringify(tags)); 
    return tags; 
    }).spread(function(tag){ // should get the first matching tag 
    sails.log.info(JSON.stringify(tag)); 
    Tag.update({ name: tag }, { user: self.id }) 
    .exec(sails.log.info); 
    }).catch(sails.log.error); //no errors are logged either 
}, 

Используя те же sails console команды, как описано выше, чтобы позвонить add_tag() я просто получить undefined и ни один операторов журнала. Трэвис, я сделал что-то не так в этой реализации?

Final Update

Я использовал ответ Джейсона ниже, чтобы создать свой окончательный ответ:

add_tag: function(name) { 
    var self = this; 
    Tag.findOrCreate({ name: name }, { name: name }) 
    .then(function(tag){ 
    tag.users.add(self.id); 
    tag.save(sails.log.info); 
    }).catch(sails.log.error); 
}, 

Причина мой код не показывал никаких ошибок, которые я использовал жизненный цикл обратного вызова в Tag.js для увеличения приоритет счетчика каждый раз, когда он обновляется, как так:

afterValidate: function() { 
this.priority++; 
} 

Когда я должен был вызовом следующего обратного вызова в цепочке, как так:

afterValidate: function(values, cb) { 
    values.priority++; 
    cb(); 
} 

Одна из вещей, которые вы не думаете, о приходе из фона Rails: P

+1

Вы смотрели на '.findOrCreate'? https://github.com/balderdashy/waterline-docs/blob/master/query-methods.md#findorcreate-search-criteria-values-callback- –

+0

@TravisWebb, см. вышеупомянутое обновление. Считаете ли вы, что это имеет какое-то отношение к взаимосвязи между пользователями и тегом? Может быть, с доминированием? Я не стал доминирующим, поскольку они не являются отношениями, связанными с перекрестными связями. – onetwopunch

ответ

2

Вы используете findOrCreate неправильно.

Определение функции является .findOrCreate(search criteria, [values, callback])

Вы, вероятно, будет необходимо изменить ваши функции выглядеть следующим образом:

add_tag: function(name) { 
    var self = this; 

    //for clarity we won't set the user when creating tags, 
    //instead we'll do it in the callback, so its the same for existing and new tags. 
    Tag.findOrCreate({ name: name }, { name: name }) 
    .then(function(tag){ 
    tag.users.add(self.id); 
    tag.save(sails.log.info); 

    }); 
}, 
+1

Пробовал этот ... тот же результат, даже если я поймаю ошибку после «затем». Обратный вызов никогда не вызван. Это намного чище, чем я.Я не видел в документах, пока вы не указали, что он вернет объект, если будет найден только один. Можете ли вы объяснить, почему вы решили экономить на себе, а не на теге? – onetwopunch

+1

Итак, я понял, что в теге был обратный вызов жизненного цикла, который останавливал цепочку обратного вызова. Как только я включил обратный вызов, он перемещается по фактической ошибке. Спасибо за помощь. Возможно, мне также понадобится и фактическая ошибка, но это другой вопрос. – onetwopunch

+2

Эй, рад, что я мог бы помочь. Вы правы, я должен был сэкономить на теге, а не на себе. Я отредактировал свой ответ. –

Смежные вопросы