2017-02-22 46 views
1

У меня есть модель intent, которая имеет hasMany связь с conditions и links и nodes. У самих nodes есть связь с links.Есть ли способ быть более кратким при использовании classMethods в Sequelize?

По экспресс-маршруту я хочу получить всю эту информацию в одном объекте. То, как я это сделал, теперь очень обратное и нечитаемое. Это работает, но я надеюсь, что есть лучший способ написать такие вещи.

app.get('/api/intents/:id', function(req, res) { 
    models.intent.findOne({ 
     where: { 
      id: req.params.id 
     } 
    }) 
    .then(function(intent) { 
     intent.getConditions() // call generated function from intent model for conditions 
     .then(function(conditions) { 
      intent.getLinks() // then call generated function from intent model for links 
      .then(function(links) { 
       intent.getNodes() // then call generated function from nodes model for links 
       .then(function(nodes) { 
        Promise.map(nodes, function(node) { 
         return node.getLinks() // Even deeper nested and getting out of hand 
         .then(function(links) { 
          node.setDataValue('links', links) 
         }) 
        }) 
        .then(function() { 
         intent.setDataValue('conditions', conditions) 
         intent.setDataValue('links', links) 
         intent.setDataValue('nodes', nodes) 
         res.json(intent) 
        }) 
       }) 
      }) 
     }) 
    }) 
}) 

ответ

2

Я думаю, что вы полностью пропустили концепцию include в options объекта метода, как findOne. Просто используйте

models.intent.findById(req.params.id, { 
    include: [ 
     { model: models.condition }, 
     { model: models.link }, 
     { model: models.node, include: [ { model: models.link } ] 
    ] 
}).then((intent) => { 
    // here you get intent with conditions, links and nodes with links 
}); 

Другой способ заключается в определении и использовании scopes на моделях.

+0

Ваш гораздо лучший способ. –

+0

О, ничего себе, я думаю, я был ослеплен автоматически сгенерированными функциями. Это прекрасно, спасибо. – Hyra

0

Вы можете использовать Promise.all() ждать все обещания должны быть решены, а затем сделать что-то с данными.

Ниже приводится частичный пример, чтобы вы на трассе:

app.get('/api/intents/:id', function(req, res) { 
models.intent.findOne({ 
    where: { 
     id: req.params.id 
    } 
}) 
.then(function(intent) { 
    let promises = [] 

    promises.push(intent.getConditions()) 
    promises.push(intent.getLinks()) 
    promises.push(intent.getNodes()) 

    Promise.all(promises) 
    .then(function(resolvedPromises) { 
     Promise.map(resolvedPromises, function(node) { 
      intent.setDataValue('conditions', resolvedPromises[0]) 
      intent.setDataValue('links', resolvedPromises[1]) 
      ... 
     }) 
    }) 
}) 
+0

Это кажется намного лучше, за исключением отчужденного массива разрешенных процессоров. Я получу это, приветствую. – Hyra