【问题标题】:Trouble updating a resource更新资源时遇到问题
【发布时间】:2021-04-07 04:59:13
【问题描述】:

我正在尝试更新交易,但它更新了该交易并同时删除了其他交易。我的重点是只更新一笔交易。有人可以检查我的后端逻辑吗?

我的架构:

const mongoose = require('mongoose')

mongoose.Schema.Types.String.set('trim', true)

const transactionSchema = mongoose.Schema(
  {
    note: { type: String, required: true },
    amount: { type: Number, default: 0 },
    user: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
      ref: 'User',
    },
  },
  {
    timestamps: true,
  }
)

const WalletSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true,
  },
  name: {
    type: String,
    trim: true,
    required: [true, 'Please enter a name'],
  },
  balance: {
    type: Number,
    default: 0,
  },
  transactions: [transactionSchema],
  createdAt: {
    type: Date,
    default: Date.now,
  },
})

module.exports = mongoose.model('Wallet', WalletSchema)

我的后端控制器逻辑:

exports.updateWalletTransactions = asyncHandler(async (req, res, next) => {
  const { amount, note } = req.body
  const foundWallet = await Wallet.findOne({ user: req.user.id })

  foundWallet.transactions = foundWallet.transactions.filter(
    (trans) => trans._id.toString() === req.params.id
  )

  if (foundWallet.transactions) {
    foundWallet.transactions[0].amount =
      amount || foundWallet.transactions[0].amount
    foundWallet.transactions[0].note = note || foundWallet.transactions[0]
    const updatedTransaction = await foundWallet.save()
    return res.status(200).json(updatedTransaction)
  } else {
    return next(new ErrorResponse('Transaction not found', 404))
  }
})

【问题讨论】:

    标签: javascript node.js reactjs mongoose


    【解决方案1】:

    问题是您使用的数组的filter 方法只会返回指定的事务。

    更好的方法是使用map 方法编写代码,如下所示:

    exports.updateWalletTransactions = asyncHandler(async (req, res, next) => {
      const { amount, note } = req.body;
      const foundWallet = await Wallet.findOne({ user: req.user.id });
    
      if (!foundWallet) return next(new ErrorResponse("no wallet found", 404));
    
      const transIndex = foundWallet.transactions.findIndex(
        (trans) => trans._id.toString() === req.params.id
      );
    
      if (!transIndex) return next(new ErrorResponse("Transaction not found", 404));
    
      foundWallet.transactions = foundWallet.transactions.map((trans) => {
        if (trans._id.toString() === req.params.id) {
          trans.amount = amount || trans.amount;
          trans.note = note || trans.note;
        }
        return trans;
      });
    
      const updatedWallet = await foundWallet.save();
      const updatedTransactions = updatedWallet.transactions;
      return res.status(200).json(updatedTransactions);
    });
    
    

    或者你可以这样做:

    exports.updateWalletTransactions = asyncHandler(async (req, res, next) => {
      const { amount, note } = req.body;
      const foundWallet = await Wallet.findOne({ user: req.user.id });
    
      if (!foundWallet) return next(new ErrorResponse("no wallet found", 404));
    
      const transIndex = foundWallet.transactions.findIndex(
        (trans) => trans._id.toString() === req.params.id
      );
      
      const trans = foundWallet.transactions[transIndex];
      
      if (trans) {
        trans.amount = amount || trans.amount;
        trans.note = note || trans.note;
      } else {
        return next(new ErrorResponse("Transaction not found", 404));
      }
    
      const updatedWallet = await foundWallet.save();
      const updatedTransactions = updatedWallet.transactions;
      return res.status(200).json(updatedTransactions);
    });
    
    

    【讨论】:

    • 无意冒犯,但使用 forEach 有点过时了,最佳实践是使用数组方法,这将为您提供更简洁的代码。顺便说一下,在我的第二种方法中,您不必使用 if 检查每个数组元素,因此它更快、性能更高。
    • 两者都是很好的解决方案,我都很欣赏他们。由于支票,我选择了第一个。如果我高兴,我会试试你的代码,并更新最佳答案。
    • 就像你说的,你的性能更好,更干净。我选择了你的。谢谢。
    【解决方案2】:

    您正在覆盖交易。更好地迭代每个事务并更新匹配的事务 id。

    exports.updateWalletTransactions = asyncHandler(async(req, res, next) => {
      const {
        amount,
        note
      } = req.body;
      const foundWallet = await Wallet.findOne({
        user: req.user.id
      })
      let transFound = false;
      if (foundWallet) {
        foundWallet.transactions.forEach(trans => {
          if (trans._id.toString() === req.params.id) {
            transFound = true;
            trans.amount = amount || trans.amount
            trans.note = note || trans.note
          }
        })
        if(transFound){
          const updatedTransaction = await foundWallet.save()
          return res.status(200).json(updatedTransaction)
        } else {
          return next(new ErrorResponse('Transaction not found', 404))
        }
      } else {
        return next(new ErrorResponse('User Id not found', 404))
      }
    })
    

    【讨论】:

    • 谢谢,我喜欢这两种方法。
    • 欢迎..请不要忘记接受答案
    • 对不起老兄,另一个答案对性能更好。你的回答也有效!
    • 我同意你的看法:)
    猜你喜欢
    • 1970-01-01
    • 2020-11-29
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多