2014-02-06 40 views
0

我想在我的sequelize对象上定义一个自定义查找器。例如,假设我有一个Order模型。自定义数据检索/查找器

var Orders = sequelize.define('Orders', { 
    ... 
}) 

我有一个复杂的查询,我想在各个地方重复使用。

var sql = 'SELECT' 
    + ' CONCAT_WS(\':\', `type`, `id`) AS `id`' 
    + ' , `type`' 
    + ' , `name`' 
    + ' , `amount`' 
    + ' , `quantity`' 
    + ' , `total`' 
    + ' , `createdAt`' 
    + ' FROM (' 
    + ' SELECT' 
    + ' OrderItems.id AS `id`' 
    + ' , \'item\' AS `type`' 
    + ' , Items.name AS `name`' 
    + ' , Items.price AS `amount`' 
    + ' , OrderItems.quantity AS `quantity`' 
    + ' , OrderItems.quantity * Items.price AS `total`' 
    + ' , OrderItems.createdAt AS `createdAt`' 
    + ' FROM OrderItems' 
    + ' INNER JOIN Items ON Items.id = OrderItems.ItemId' 
    + ' WHERE OrderId = :OrderId' 
    + ' UNION' 
    + ' SELECT' 
    + ' OrderPayments.id AS `id`' 
    + ' , \'payment\' AS `type`' 
    + ' , Payments.name AS `name`' 
    + ' , OrderPayments.amount AS `amount`' 
    + ' , 0 AS `quantity`' 
    + ' , OrderPayments.amount AS `total`' 
    + ' , OrderPayments.createdAt AS `createdAt`' 
    + ' FROM OrderPayments' 
    + ' INNER JOIN Payments ON Payments.id = OrderPayments.PaymentId' 
    + ' WHERE OrderId = :OrderId' 
    + ') OrderLines' 
    + ' ORDER BY createdAt DESC' 

下面是我想如何运行查询。

Orders.find(123).success(function(order) { 
    order.getDataFromMyComplexQuery('arg1', 'arg2').success(function(results){ 
     // Do something with the results 
    }) 
}); 

或者像:

Orders.getDataFromMyComplexQuery('arg1', 'arg2').success(function(results){ 
    // Do something with the results 
}) 

这就像一个存储过程,但在Sequelize。

回答

0

您可以定义与instanceMethods和classMethods对象的自定义方法。从docs

Sequelize允许您通过自定义方法的模型,它的 实例。只需执行以下操作:

var Foo = sequelize.define('Foo', { /* attributes */}, { 
    classMethods: { 
    method1: function(){ return 'smth' } 
    }, 
    instanceMethods: { 
    method2: function() { return 'foo' } 
    } 
}) 

// Example: 
Foo.method1() 
Foo.build().method2() 
0

好吧,在这里我们似乎陷入了由不同的JavaScript开发人员提供的术语混乱。 Sequelize称为Model的东西看起来像Repository。但是模型 - 是定义中在Repository中传递的参数。并且正是模型(或模型集合)在任何发现者方法上被返回。 清除这些事情可以让您轻松理解您的任务是使用自定义查找器来扩展存储库。 这是我如何做:

/** 
    * custom method to retrieve matches by complex conditions 
    * @param roundId – integer, required 
    * @param conditions – optional object of type: { teamId: integer, isFinished: boolean, searchTerm: string } 
    * to catch result chain .success(function(matches){}) call 
    * to catch error chain .error(function(errorText){}) call 
    * @return this to make chaining available 
    */ 
    matchesRepository.getByRound = function(roundId, conditions){ 
     /** handling chaining for .success and .error callbacks */ 
     var successCallback, 
      errorCallback 
      self = this; 
     this.success = function(callback){ 
      if('function' != typeof callback){ 
       throw "Function expected as successCallback" 
      } 
      successCallback = callback; 
      return self; 
     } 
     this.error = function(callback){ 
      if('function' != typeof callback){ 
       throw "Function expected as callback"; 
      } 
      errorCallback = callback; 
      return self; 
     } 

     /** validate params */ 
     var roundId = parseInt(roundId); 
     if(isNaN(roundId)){ 
      errorCallback("Unable to getByRound matches until roundId not specified"); 
      return this; 
     } 

     if('undefined' == typeof conditions){ 
      conditions = {}; 
     } 

     /** build statement */ 
     var statement = "SELECT @matches.* FROM @matches " + 
         "LEFT OUTER JOIN @teams as team1 ON team1.team_id = @matches.id_team1 " + 
         "LEFT OUTER JOIN @teams as team2 ON team2.team_id = @matches.id_team2 WHERE "; 
     var where = []; 

     if('undefined' != typeof conditions.teamId){ 
      var teamId = parseInt(conditions.teamId); 
      if(isNaN(teamId)){ 
       errorCallback("Integer or eval string expected in conditions.teamId; `" + 
           conditions.teamId + "` provided"); 
       return this; 
      } 
      where.push('((id_team1 = ' + teamId + ' OR id_team2 = ' + teamId + '))'); 
     } 
     if('undefined' != typeof conditions.isFinished){ 
      if(true == conditions.isFinished){ 
       where.push('(gf IS NOT NULL AND ga IS NOT NULL)'); 
      } else { 
       where.push('(gf IS NULL AND ga IS NULL)'); 
      } 
     } 
     if('undefined' != typeof conditions.searchTerm){ 
      where.push('(team1.title LIKE "%' + conditions.searchTerm + '%" OR ' + 
         'team2.title LIKE "%' + conditions.searchTerm + '%")'); 
     } 
     var matchesTable = core.factories.match.name, 
      teamsTable = core.factories.team.name, 
      preparedQuery = statement + where.join(" AND "), 
      sqlQuery = preparedQuery.replace(/@matches/g, matchesTable) 
            .replace(/@teams/g, teamsTable); 

     sequelize.query(sqlQuery) 
      .success(function(matches){ 
       successCallback(matches); 
      }) 
      .error(function(errorText){ 
       errorCallback(errorText); 
      }); 
     return this; 
    } 
+0

感谢您提供答案。这不是我想要的。 –