Sequelize在where子句上访问父表的字段

时间:2016-07-05 16:45:34

标签: javascript node.js sequelize.js

我有AdBannerRedirectScript型号。 Ad是父表。

广告模式

import UID  from '../util/uid';

export default (sequelize, DataTypes) => {
    const Ad = sequelize.define('Ad',
    {
    uid: {
      type: DataTypes.STRING(40),
      allowNull: false,
      unique: true
    },
    name: {
      type: DataTypes.STRING(15),
      allowNull: false
    },
    type: {
      type: DataTypes.STRING(15),
      allowNull: false
    }
  });
  Ad.hook('beforeValidate', (ad, options) => ad.uid = UID.generate());
  return Ad;
};

横幅模型

export default (sequelize, DataTypes) => {
  const Banner = sequelize.define('Banner',
  {
      outcome: {
        type: DataTypes.STRING(120),
        allowNull: false
      },
      image: {
        type: DataTypes.STRING(120),
        allowNull: false
      }
  },
  {
    classMethods: {
      associate: (models) => {
        Banner.belongsTo(models.Ad);
        Banner.hasMany(models.Format);
      }
    }
  });
  return Banner;
};

因此,当我搜索横幅时,我需要访问Ad.uid才能检索所有数据:https://myapp.doamin.com/ads/uid/dh49mmx02?type=banner

广告API

router.get('/:uid', (request, response) => {
  const adType = request.query.type;
  let service = null;

  switch(adType) {
    case 'banner':
      service = bannerService; break;
    ...
  }
  service.findOne(request.params.uid, (ad) => {
    if(!ad) {
      response.json({eror: true, message: 'Ad not found'});
    } else {
      response.json(ad);
    }
  });
});

横幅服务

export default class BannerService {

  find(qty, cb) {
    Banner.findAll({offset: qty, limit: 10})
      .then((banners) => cb(banners));
  }

  findOne(uid, cb) {
    Banner.find({where: {'Ad.uid': uid}, include: [Ad, Format]})
      .then((banner) => cb(banner));
  }
  ...
}

当我尝试获取横幅时,会抛出此错误:Banner.Ad.uid column not exist。我也尝试使用$Ad.uid$,但它会抛出An entry for table Ad is missing in from clause

这是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

首先,我相信您还应该通过associate添加Ad.hasMany(models.Banner);功能来指定广告与横幅之间的关联。

对于查询,Sequelize实际上允许您在include

中添加where语句
findOne(uid, cb) {
  Banner.find({include: [
    {model: Ad, where: {uid: uid}},
    Format
  ]}).then((banner) => cb(banner));
}