2012-02-14 9 views
0

我正在爲小型應用程序提供自定義產品的報價。這是我第一個CakePHP應用程序。在cakePHP應用程序中自動運行不相關的動作

當添加或保存產品時,會自動計算產品的許多字段。計算使用存儲在「費率」表中的valuse來執行操作。這些'價格'也可以由管理員更新,並擁有自己的模型,視圖和控制器。但是,當費率更新時,我需要重新計算所有現有產品,就好像用戶已經/產品/編輯並單擊保存。

我真的不知道該怎麼當率保存到數據庫

這裏是我的ProductsController編輯功能觸發此:

public function edit($id = null) { 
    $this->Product->id = $id; 
    if (!$this->Product->exists()) { 
     throw new NotFoundException(__('Invalid product')); 
    } 
    if ($this->request->is('post') || $this->request->is('put')) { 
     $this->loadModel('Rate', '1'); 

     $Od = $this->request->data['Product']['material_od']/2; 
     $materialMass = $this->Rate->field('steel_mass') * $this->request->data['Product']['material_length'] * (pi() * $Od * $Od); 
     $this->Product->saveField('material_mass', $materialMass); 

     $materialCost = $materialMass * $this->Product->Material->field('cost', array('Material.id' => $this->request->data['Product']['material_id'])); 
     $this->Product->saveField('material_cost', $materialCost); 

     $materialMarkupRate = $this->Rate->field('material_markup') + 1; 
     $wasteMarkupRate = $this->Rate->field('waste_markup') + 1; 

     $materialMarkupCost = $materialCost * $materialMarkupRate * $wasteMarkupRate; 
     $this->Product->saveField('material_markup_cost', $materialMarkupCost); 

     $setupCost = $this->request->data['Product']['number_tools'] * $this->Rate->field('tool_time') * $this->Rate->field('setup_rate'); 
     $this->Product->saveField('setup_cost', $setupCost); 

     $cuttingCost = $this->request->data['Product']['cutting_time'] * $this->Rate->field('cutting_rate'); 
     $this->Product->saveField('cutting_cost', $cuttingCost); 

     $machiningCost = $this->request->data['Product']['machining_time'] * $this->Rate->field('machining_rate'); 
     $this->Product->saveField('machining_cost', $machiningCost); 

     $polishingCost = $this->request->data['Product']['polishing_time'] * $this->Rate->field('polishing_rate'); 
     $this->Product->saveField('polishing_cost', $polishingCost); 

     if ($this->Product->save($this->request->data)) { 
      $this->Session->setFlash(__('The product has been saved')); 
      $this->redirect(array('action' => 'index')); 
     } else { 
      $this->Session->setFlash(__('The product could not be saved. Please, try again.')); 
     } 
    } else { 
     $this->request->data = $this->Product->read(null, $id); 
    } 
    $materials = $this->Product->Material->find('list'); 
    $this->set(compact('materials')); 
} 

和我RatesController編輯功能:

public function edit($id = null) { 
    $this->Rate->id = $id; 
    if (!$this->Rate->exists()) { 
     throw new NotFoundException(__('Invalid rate')); 
    } 
    if ($this->request->is('post') || $this->request->is('put')) { 
     if ($this->Rate->save($this->request->data)) { 
      $this->Session->setFlash(__('The settings have been saved. Please update your products.')); 
      $this->redirect(array('controller' => 'products', 'action' => 'index')); 
     } else { 
      $this->Session->setFlash(__('The rate could not be saved. Please, try again.')); 
     } 
    } else { 
     $this->request->data = $this->Rate->read(null, $id); 
    } 
} 

我怎樣才能觸發第一個來回第二個?

我對此很新,所以所有的提示建議和批評都非常歡迎!

非常感謝, 拉爾夫

回答

0

有幾個問題,這將有助於你不僅清理你正在嘗試做的,但做一個更有效的方式。目前,您每次撥打電話$this->Product->saveField時都會觸碰數據庫。如果這是少數人使用的小型應用程序,則不會有太大影響。但是,您應該養成編寫乾淨的代碼的習慣。你的變量名稱非常棒!容易明白。我首先建議計算所有的值,然後打這樣的數據庫:

... 
    $this->loadModel('Rate', '1'); 
    $materialMarkupRate = $this->Rate->field('material_markup') + 1; 
    $wasteMarkupRate = $this->Rate->field('waste_markup') + 1; 

    $Od = $this->request->data['Product']['material_od']/2; 
    // make sure you have a hidden id form in the view, otherwise you will need to set it here 
    $this->request->data['Product']['material_mass'] = $this->Rate->field('steel_mass') * $this->request->data['Product']['material_length'] * (pi() * $Od * $Od); 
    $this->request->data['Product']['material_cost'] = $materialMass * $this->Product->Material->field('cost', array('Material.id' => $this->request->data['Product']['material_id'])); 
    $this->request->data['Product']['material_markup_cost'] = $materialCost * $materialMarkupRate * $wasteMarkupRate; 
    $this->request->data['Product']['setup_cost'] = $this->request->data['Product']['number_tools'] * $this->Rate->field('tool_time') * $this->Rate->field('setup_rate'); 
    $this->request->data['Product']['cutting_cost'] = $this->request->data['Product']['cutting_time'] * $this->Rate->field('cutting_rate'); 
    $this->request->data['Product']['machining_cost'] = $this->request->data['Product']['machining_time'] * $this->Rate->field('machining_rate'); 
    $this->request->data['Product']['polishing_cost'] = $this->request->data['Product']['polishing_time'] * $this->Rate->field('polishing_rate'); 

    if ($this->Product->save($this->request->data)) { 
... 

第二,如果你需要調用從其他地方這種方法,那就是你需要將它移到一個標誌。因爲這是數據,您應該將其移至模型。

但是,如果您說每次費率發生變化,數據庫中的每個產品都需要更新,這仍然是一個問題。也許不是現在,但後來在路上。想想擁有100MM記錄。您在費率上改變了一件事情,並且您在長時間內攪動數據庫。這是很多資源。

我的建議是改變這一點,並將其移動到ProductModel中的onFind回調。它的工作方式是每次你記錄一條記錄,它會在返回到視圖之前對這些值進行數學運算。通常最好不要將計算值存儲在數據庫中。在某些情況下,你會想要,但在這種情況下,似乎你可以在飛行中計算它們。這也將防止每次費率變化時都需要重新計算每個產品。它也將使代碼更清晰。

+0

感謝您的詳細回覆:)說實話,我已經開始考慮大部分關於即時計算以及在發佈後不久將其移至模型的說法。感謝您的建議,這將有助於我改進代碼。 – Ralphonz 2012-02-15 08:54:16

+0

我已經設法使用afterFind回調將其移至產品模型,並且我可以收到計算結果,但是我收到錯誤未定義索引:產品[APP/Model/Product。php,line 120],即使索引必須被定義,因爲php正在計算中使用該值並顯示正確的計算量......在foreach中,第120行看起來像這樣($ result爲$ key => $ val)循環 - $ results [$ key] ['Product'] ['material_mass'] = $ rate ['Rate'] ['steel_mass'] * $ val ['Product'] ['material_length'] *(pi()* $ Od * $ Od); – Ralphonz 2012-02-15 10:42:57

+0

好吧,我做到了!這是所有的工作方式,你建議,我覺得整個事情更好:)爲了將來的參考:爲了避免在索引頁上的未定義索引錯誤,你必須使用if(isset($ val ['Model'] ['field' ]))在foreach循環中 – Ralphonz 2012-02-15 11:32:50

相關問題