【问题标题】:Cakephp 3 - Subtracting a value from the databaseCakephp 3 - 从数据库中减去一个值
【发布时间】:2017-05-04 04:31:08
【问题描述】:

您好,我是 cakephp 新手,并试图弄清楚事情是如何运作的。

所以我有两张表,一张是客户 Payments,另一张是客户 Charges。当我向 Payments 表添加一个值时,如何从 Charges 中减去一个值?

例如 - 客户 X 的费用为 100。当我从付款中选择客户 X 并选择 20 的付款时。费用表中的答案应为 80。并且应该在 Payments 表中记录客户 X 也已付款。

我正在提交表单中的值。并将其发送给支付控制器。

 public function addPaymentsCustomer()
 {
     $this->viewBuilder()->layout(false);
     $payment = $this->Payments->newEntity();
         if ($this->request->is('post')) {
             $payment = $this->Payments->patchEntity($payment, $this->request->data);

             if ($this->Payments->save($payment)) {
                 $this->Flash->success(__('The payment has been saved.'));
                return $this->redirect( '/payments' );
             } else {
                $this->Flash->error(__('The payment could not be saved. Please, try again.'));
                return $this->redirect( '/payments' );
             }
             $this->Flash->error(__('Error.. Please, try again.'));
            return $this->redirect( '/payments' );
         }
 }

我该如何做同样的事情并从 Charges 表中减去该值?

我在哪里可以进行计算以及如何计算?

这是我向控制器发送值的表单。

<form role="form" method="post" accept-charset="utf-8" action="/add-payments-customer">
      <div style="display:none;"><input type="hidden" name="_method" value="POST"/></div>
      <br style="clear:both">
      <div class="form-group">
        <div class="input-group col-md-5 col-lg-5 col-sm-5 col-xs-12">
          <select class="form-control" style="background-color: #F9F9F9;" name="customer_id" id="customer_id" onchange="this.form.submit()">
            <option style="padding-top: 20px;">Select a Customer</option>
            <?php
            if (!empty($CustomerInfo)) { 
              foreach ($CustomerInfo as $Customers):        
                ?> 
              <option value="<?= h($Customers->id)?>"><?= h($Customers->name)?></option>
            <?php endforeach;  } ?> 
          </select>
        </div>
      </div>
      <div class="form-group">
        <input type="text" class="form-control secondlead" id="description" name="description" placeholder="Description" required>
      </div>
      <div class="form-group">
        <input type="number" id="amount" name="amount" class="form-control secondlead" placeholder="Amount">
      </div>
      <div class="pull-left">
        <button type="submit" id="submit" name="submit" class="btn btn-primary greenbtn">Send</button>
      </div>
      <div style="margin-top: 10px" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
        <p class="text-center"><?= $this->Flash->render() ?></p>
      </div>
    </form>

表格 Payments & Charges 都有一个 Customer_id 的 FK。

【问题讨论】:

  • 您的意思是客户的收费金额已经存储在表格中,您需要在付款完成时减少该收费金额吗?
  • 是的,完全正确,并且在提交完成后,付款记录会与客户 ID 一起添加,同时会减去该特定客户的费用。
  • 好吧,如果你添加你的表格会更清楚!还要提到两个表是否有关系!
  • 您可以通过在 mysql 中创建触发器来完成,或者您可以在成功后执行另一个查询来更新 Charges 表的数量。检查此链接stackoverflow.com/questions/21848149/…
  • @ManoharKhadka 嗨,我添加了用于向 PaymentsController 发送数据的表单。

标签: php mysql cakephp cakephp-2.0 cakephp-3.0


【解决方案1】:

您可以简单地添加一些逻辑:

在支付控制器处:

public function addPaymentsCustomer()
{
    $this->viewBuilder()->layout(false);
    $payment = $this->Payments->newEntity();
    if ($this->request->is('post')) {
     $payment = $this->Payments->patchEntity($payment, $this->request->data);
     $this->loadModel('Charges');
     $data['amount'] = $this->request->data['amount'];
     $data['customer_id'] = $this->request->data['customer_id'];
     if ($this->Payments->save($payment)) {
         $this->Flash->success(__('The payment has been saved.'));
         $this->Charges->updateCharge($data); // update charges
        return $this->redirect( '/payments' );
     } else {
        $this->Flash->error(__('The payment could not be saved. Please, try again.'));
        return $this->redirect( '/payments' );
     }
     $this->Flash->error(__('Error.. Please, try again.'));
    return $this->redirect( '/payments' );
    }
}

收费表:

public function updateCharge($data = []) {
    $customer_id = $data['customer_id'];
    $charge = $this->find()
                    ->where(['Charges.customer_id' => $customer_id])
                    ->first();

    $previousAmount = $charge->amount;
    $newAmount = $previousAmount - $data['amount'];

    $charge->customer_id = $customer_id;
    $charge->amount = $newAmount;
    if($this->save($charge)) {
        // updated
    }
}

我只是假设您在费用表中也有“金额”字段!

【讨论】:

  • 欢迎朋友..!
  • @ManoharKhadka 将此放入事务中,因为一个失败整个过程可以回滚
  • 正如@AmanRawat 所提到的,不仅当第二次保存失败时事情会中断,这通常也容易出现竞争条件。我不想听起来刻薄,但如果我会雇人建立一个处理金钱的系统,当你想出这样的事情时,我会立即解雇你。
  • @KasunWijesekara 我指的是这个答案中的代码,Aman Rawats 代码可能“更安全”(虽然它也可能有问题),但只是将事物包装在事务中是不一定“足够安全”。例如,您是否知道您正在使用什么事务隔离级别?如果你不能回答这个问题,或者甚至不知道隔离级别是什么,那么如果你处理真钱,你就会遇到麻烦。我可能听起来有点歇斯底里,但这是一个敏感的话题,当这样的代码传播时很危险。
  • @ndm 不,我不知道。我正在尝试一些示例,以便熟悉所有内容。不,这不是一个真实世界的例子。如果您能提供一些资源,我将非常感谢您了解该主题!
【解决方案2】:

这样做

use Cake\Datasource\ConnectionManager;// At the top of file



$conn = ConnectionManager::get('default');
$conn->begin(); // Start transaction

if ($this->Payments->save($payment)) {
    $this->loadModel('Customers');
    $customer = $this->Customers->get($payment->customer_id);
    $customer->amount = $customer->amount + $payment->amount;
    if($this->Customers->save($customer)){
        $conn->commit(); // Commit transaction
        $this->Flash->success(__('The payment has been saved.'));
    } else {
        $conn->rollback();// Rollback transaction
        $this->Flash->error(__(json_encode($customer->errors()))); // Shows what get wrong
    }
    return $this->redirect('/payments');
} else {
    $conn->rollback();// Rollback transaction
    $this->Flash->error(__(json_encode($payment->errors()))); // Shows what get wrong
    return $this->redirect('/payments');
}

【讨论】:

  • 它不起作用,出现“出了点问题!请重试”错误,并且费用不会被扣除。
  • amount 是字段名还是其他?如果您也可以提供表结构,将更有帮助
  • 我尝试了此选项,但付款没有保存。并且价值也不会被扣除。
  • 是的,它是一样的。我还添加了 $this->loadModel('Charges'); if($this->Charges->updateAll(['amount'=>'amount + '.$payment->amount],['id'=>$payment->customer_id])){ 因为模型应该是charges ,但问题仍然存在。
  • 谢谢兄弟的帮助。 Manohar 的回答对我有用。我对这个主题真的很陌生,我很感激我得到的所有帮助。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多