Feathers: service.get(id)がすでに存在する場合、service.createを失敗/禁止します

作成日 2017年06月23日  ·  4コメント  ·  ソース: feathersjs/feathers

データベースに同じidを持つ既存のエントリがすでに存在する場合、 service.create(obj)が失敗すると予想しました。 これがfeathers、特定のデータベースサービスインターフェイス(ここではfeathers-nedb)またはfeathers-hooks-commonの範囲内にあるかどうかはわかりません。

再現する手順

const feathers = require('feathers');
const NeDB = require('nedb');
const service = require('feathers-nedb');

const app = feathers()
app.use('/users', service({ Model: userModel(), id: 'email' }));

const users = app.service('/users');
let user = { email: '[email protected]', password: '11111', role: 'admin' }
Promise.all([
  users.create(user),
  users.create(user)
]).then(results => console.log(results))
  .catch(err => console.log('Error occurred:', err));

function userModel() {
  return new NeDB({
    filename: 'users.db',
    autoload: true
  });
}

予想される行動

2番目のusers.createが失敗すると予想しました。

実際の動作

同じユーザーがデータベースに2回追加されます。

提案されたフック

const { validate } = require('feathers-hooks-common')

/**
 * Checks if item with same id already exists.
 */
module.exports = function unique () {
  return validate((values, hook) => {
    return hook.service.get(values[hook.service.id])
      .catch(() => null)  // not found, pass null to next .then
      .then(res => res === null
        ? null
        : Promise.reject(new Error(`${res[hook.service.id]} already exists in db`)))
  })
}

最も参考になるコメント

助けてくれてありがとう。 同じことを偶然見つけた他の人のための解決策は次のとおりです。

function userModel() {
  let Model = new NeDB({
    filename: 'users.db',
    autoload: true
  });

  Model.ensureIndex({ fieldName: 'email', unique: true }, err => {
    if (err) throw err
  });

  return Model;
}

全てのコメント4件

フックはさておき、フックにはよく見落とされる問題、 param値があります。 たとえば、 getでは認証情報は渡されません。 フックstashBeforeがそれをどのように処理するかをご覧ください。

これは、効率上の理由から、一般的にデータベースで処理する必要がある問題です。 フックとして実装することは間違いなく可能ですが、NeDBの一意の制約インデックスを使用するほど効率的ではありません: https

助けてくれてありがとう。 同じことを偶然見つけた他の人のための解決策は次のとおりです。

function userModel() {
  let Model = new NeDB({
    filename: 'users.db',
    autoload: true
  });

  Model.ensureIndex({ fieldName: 'email', unique: true }, err => {
    if (err) throw err
  });

  return Model;
}

この問題は、クローズされた後、最近のアクティビティがないため、自動的にロックされています。 関連するバグについては、この問題へのリンクを含む新しい問題を開いてください。

このページは役に立ちましたか?
0 / 5 - 0 評価