程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> CakePHP 2.x CookBook 中文版 第七章 模型 之 保存數據

CakePHP 2.x CookBook 中文版 第七章 模型 之 保存數據

編輯:關於PHP編程

保存數據 CakePHP 會為保存模型數據制作快照。准備保存的數據使用如下基本格式傳遞給模型的 save() 方法:   1 Array 2 ( 3     [ModelName] => Array 4     ( 5         [fieldname1] => 'value' 6         [fieldname2] => 'value' 7     ) 8 ) 多數時候你無需擔心這種格式: CakePHP 的 FormHelper 和模型的 find 方法都用這種格式打包所有數據。如果使用其它的助手,數據也能方便地以 $this->request->data 形式使用。   下面是使用 CakePHP 模型向數據庫表存入數據的控制器動作的示例:    1 public function edit($id) {  2     // 有表單數據被 POST?  3     if ($this->request->is('post')) {  4         // 如果表單數據能夠通過校驗並保存...  5         if ($this->Recipe->save($this->request->data)) {  6             // 設置 session 跳轉信息並跳轉  7             $this->Session->setFlash('Recipe Saved!');  8             $this->redirect('/recipes');  9         } 10     } 11  12     // 如果沒有表單數據,查找被編輯的 recipe 並將其賦值給視圖。 13     $this->set('recipe', $this->Recipe->findById($id)); 14 } 在 save 方法被調用時,在第一個參數中傳遞給它的數據,被 CakePHP 校驗機制校驗(更多信息請參見 數據校驗 一節)。 如果因為某些原因,數據沒有被保存,檢查一下是不是沒有符合某些校驗規則。 可以通過輸出Model::$validationErrors 來 debug 這種情況。   1 if ($this->Recipe->save($this->request->data)) { 2     // "保存" 成功後的處理邏輯 3 } 4 debug($this->Recipe->validationErrors); 其它一些與保存相關的有用的模型方法:   Model::set($one, $two = null) Model::set() 能夠用於將數據的一個或多個列放入模型的 data 數組。當使用帶有由 Model 提供的 ActiveRecord 特性的模型時很有用:   1 $this->Post->read(null, 1); 2 $this->Post->set('title', 'New title for the article'); 3 $this->Post->save(); 此例展示了如何使用 ActiveRecord 的 set() 方法更新和保存單個列。還可以使用 set() 給多個列賦新值:   1 $this->Post->read(null, 1); 2 $this->Post->set(array( 3     'title' => 'New title', 4     'published' => false 5 )); 6 $this->Post->save(); 上例將更新 thitle 和 published 列並保存到數據庫中。   Model::save(array $data = null, boolean $validate =true, array $fieldList = array())   這個方法保存數組格式的數據。第二個參數允許跳過校驗,第三個參數允許提供要保存的模型的列的列表。為了提高安全性,可以使用 $fieldList 限制要保存的列。   注解   如果不提供 $fieldList,惡意用戶能夠向表單數據中添加附加的列(在你沒有使用 SecurityComponent 的情況下),並通過這種方法來改變原本不可以被改變的列。   save 方法還有一個替代語法:   1 save(array $data = null, array $params = array()) $params 數組可以用如下選項作為其鍵:   validate 設置為 true/false 能夠 允許/禁止 校驗。 fieldList 允許保存的列構成的數組。 callbacks 設置為 false 將禁止回調。使用 ‘before’ 或 ‘after’ 將僅允許指定的回調。 關於模型回調的更多信息請參見 這裡   小技巧   如果你不想更新列在保存某些數據時被更新,在 $data 數組中添加 'updated' => false。   一旦保存完成,可以使用模型對象的 $id 屬性獲得對象的 ID - 在創建新對象時可能會非常有用。   1 $this->Ingredient->save($newData); 2 $newIngredientId = $this->Ingredient->id; 創建或更新是通過模型的 id 列來控制的。如果設置了 $Model->id,帶有這個主鍵的記錄將被更新。 其它情況下,一條新記錄被創建:   1 // 創建新記錄: id 沒有設置或設置為 null 2 $this->Recipe->create(); 3 $this->Recipe->save($this->request->data); 4  5 // 更新記錄: id 被設置為一個數字值 6 $this->Recipe->id = 2; 7 $this->Recipe->save($this->request->data); 小技巧   在循環中調用 save 時,不要忘記調用 create() 。   如果想更新一個值,而不是創建一條新記錄,必須確保向數據數組傳遞了主鍵列:   1 $data = array('id' => 10, 'title' => 'My new title'); 2 // 將更新 id 為 10 的 Recipe 記錄 3 $this->Recipe->save($data); Model::create(array $data = array()) 這個方法為保存新信息重置模型的狀態。 實際上它並不在數據庫中創建新記錄,而是清除預先設置的 Model::$id,並在 Model::$data 中設置基於數據庫列默認的默認值。   如果傳遞了 $data 參數(使用上面描述的數組格式),模型實例將准備保存這些數據(使用 $this->data)。   如果用 false 代替一個數組傳遞給此方法,模型實際將不根據之前沒有設置的模型結構來初始化列,而僅僅重置已經設置的列, 並且保留未設置的列。 這麼做是為了避免更新數據庫中已經設置的列的值。   小技巧   如果想要用插入一個新行來代替更新已經存在的一行,必須先調用 create()。這樣能夠避免與回調或者其它位置中曾調用過的 save 發生沖突。   Model::saveField(string $fieldName, string$fieldValue, $validate = false)   用於保存單個列的值。在使用 saveField() 之前要先設置模型的 ID ($this->ModelName->id = $id)。在使用這個方法時,$fieldName 僅需要包含列名,不需要模型名和列。   例如,更新一條博客的標題,可以用如下方式在控制器中調用 saveField:   1 $this->Post->saveField('title', 'A New Title for a New Day'); 警告   在使用這個方法更新時不能停止更新列,你需要使用 save() 方法。   saveField 方法也有一個替代語法:   1 saveField(string $fieldName, string $fieldValue, array $params = array()) $params 數組可以用如下選項作為其鍵:   validate 設置為 true/false 能夠 允許/禁止 校驗。 callbacks 設置為 false 將禁止回調。使用 ‘before’ 或 ‘after’ 將僅允許指定的回調。 Model::updateAll(array $fields, array $conditions)   一次調用更新一條或多條記錄。被更新的記錄通過 $conditions 數組標識,$fields 參數指定的列和值被更新。   例如,批准所有成為會員超過一年的面包師,調用如下的更新語句:   1 $this_year = date('Y-m-d h:i:s', strtotime('-1 year')); 2  3 $this->Baker->updateAll( 4     array('Baker.approved' => true), 5     array('Baker.created <=' => $this_year) 6 ); 小技巧   $fields 數組接受 SQL 表達式。字面值使用 Sanitize::escape() 手動引用。   注解   即使列中存在的編輯列被更新,它也不會通過 ORM 自動更新。必須手動將其加入到你想更新的數組中。   例如,關閉所有屬於指定客戶的所有門票:   1 $this->Ticket->updateAll( 2     array('Ticket.status' => "'closed'"), 3     array('Ticket.customer_id' => 453) 4 ); 默認情況下,updateAll() 將自動連接支持 join 的數據庫的 belongsTo 關聯。通過臨時綁定關聯能夠防止這種連接。   Model::saveMany(array $data = null, array $options= array())   此方法用於同時保存同一模型的多行。可以帶有如下選項:   validate: 設置為 false 將禁止校驗,設置為 true 將在保存前校驗每條記錄,設置為 ‘first’(此為默認值) 將在任意一條被保存前檢查 全部 記錄。 atomic: 如果為 true(默認),將在單個指令中保存所有記錄,如果 數據庫/表 不支持單指令需要設置為 false。 fieldList: 與 Model::save() 方法的 $fieldList 參數相同。 deep: (自 2.1 版開始)如果設置為 true,關聯數據也被保存,參見 saveAssociated。 為單個模型保存多條記錄,$data 需要是數字索引的記錄數組:   1 $data = array( 2     array('title' => 'title 1'), 3     array('title' => 'title 2'), 4 ); 注解   我們傳遞了數字索引代替了通常情況下 $data 包含的 Article 鍵。在保存同一模型的多條記錄時,記錄數組需要使用數字索引,而不是模型的鍵。   它也可以接受如下格式的數據:   1 $data = array( 2     array('Article' => array('title' => 'title 1')), 3     array('Article' => array('title' => 'title 2')), 4 ); 如果還要保存帶有 $options['deep'] = true 的關聯數據,上面的兩個例子將類似於下面的代碼:   1 $data = array( 2     array('title' => 'title 1', 'Assoc' => array('field' => 'value')), 3     array('title' => 'title 2'), 4 ); 5 $data = array( 6     array('Article' => array('title' => 'title 1'), 'Assoc' => array('field' => 'value')), 7     array('Article' => array('title' => 'title 2')), 8 ); 9 $Model->saveMany($data, array('deep' => true)); 切記,如果想用更新記錄代替創建新記錄,需要向數據行添加主鍵索引:   1 $data = array( 2     array('Article' => array('title' => 'New article')), // 創建新記錄 3     array('Article' => array('id' => 2, 'title' => 'title 2')), // 更新存在的記錄 4 ); Model::saveAssociated(array $data = null, array$options = array())     此方法用於一次保存多個模型關聯。可以帶有如下選項:   validate: 設置為 false 將禁止校驗,設置為 true 將在保存前校驗每條記錄,設置為 ‘first’(此為默認值) 將在任意一條被保存前檢查 全部 記錄。 atomic: 如果為 true(默認),將在單個指令中保存所有記錄,如果 數據庫/表 不支持單指令需要設置為 false。 fieldList: 與 Model::save() 方法的 $fieldList 參數相同。 deep:(自 2.1 版開始)如果設置為 true,關聯數據也被保存,參見 saveAssociated。 為了保存記錄的同時保存與其有著 hasOne 或者 belongsTo 關聯的記錄,data 數組看起來就像下面這樣:   1 $data = array( 2     'User' => array('username' => 'billy'), 3     'Profile' => array('sex' => 'Male', 'occupation' => 'Programmer'), 4 ); 為了保存記錄的同時,保存與其有著 hasMany 關聯的記錄,data 數組看起來就像下面這樣:   1 $data = array( 2     'Article' => array('title' => 'My first article'), 3     'Comment' => array( 4         array('body' => 'Comment 1', 'user_id' => 1), 5         array('body' => 'Comment 2', 'user_id' => 12), 6         array('body' => 'Comment 3', 'user_id' => 40), 7     ), 8 ); 為了保存記錄的同時保存與其有著超過兩層深度的 hasMany 關聯的記錄,data 數組看起來就像下面這樣:    1 $data = array(  2     'User' => array('email' => '[email protected]'),  3     'Cart' => array(  4         array(  5             'payment_status_id' => 2,  6             'total_cost' => 250,  7             'CartItem' => array(  8                 array(  9                     'cart_product_id' => 3, 10                     'quantity' => 1, 11                     'cost' => 100, 12                 ), 13                 array( 14                     'cart_product_id' => 5, 15                     'quantity' => 1, 16                     'cost' => 150, 17                 ) 18             ) 19         ) 20     ) 21 ); 注解   如果保存成功,主模型的外鍵將被存儲在相關模型的 id 列中,例如 $this->RelatedModel->id。   警告   在調用 atomic 選項設置為 false 的 saveAssociated 方法時要小心的進行檢查,它返回的是一個數組,而不是邏輯值。   在 2.1 版更改: 現在你可以保存深層關聯的數據(用 $options['deep'] = true 設置)。   為了保存記錄的同時,保存與其有 hasMany 關聯的相關記錄及深層關聯的 Comment belongsTo User 數據,data 數組看起來就像下面這樣::   1 $data = array( 2     'Article' => array('title' => 'My first article'), 3     'Comment' => array( 4         array('body' => 'Comment 1', 'user_id' => 1), 5         array('body' => 'Save a new user as well', 'User' => array('first' => 'mad', 'last' => 'coder')), 6     ), 7 ); 並用如下語句進行保存:   1 $Article->saveAssociated($data, array('deep' => true)); 在 2.1 版更改: Model::saveAll() 和同族方法現在支持為多個模型傳遞 fieldList。   為多個模型傳遞 fieldList 的例子:   1 $this->SomeModel->saveAll($data, array( 2     'fieldList' => array( 3         'SomeModel' => array('field_1'), 4         'AssociatedModel' => array('field_2', 'field_3') 5     ) 6 )); fieldList 是一個以模型別名為鍵,以列構成的數組作為值的數組。 模型名如同在被保存的數據中那樣,不能嵌套。   Model::saveAll(array $data = null, array $options =array())   saveAll 函數只是 savaMany 和 saveAssociated 方法的包裝器。它檢查數據並且決定執行哪種數據保存類型。它查看數據並決定執行哪種類型的保存。如果數據是數字索引數組,saveMany 被調用,否則 saveAssociated 被調用。   此函數的選項與前面的兩個函數相同,並向後兼容。推薦根據實際情況使用 saveMany 或 saveAssociated。   保存相關模型的數據(hasOne, hasMany, belongsTo)   在與關聯模型一起工作時,When working with associated models, 一定要意識到模型數據的保存總是由相應有 CakePHP 模型來完成。如果保存一條新的 Post 和它關聯的 Comment,就需要在保存操作的過程中同時使用 Post 和 Comment 模型。   如果系統中還不存在關聯模型記錄(例如,想要保存新的 User,同時保存相關的 Profile 記錄),需要先保存主模型或者父模型。   為了了解這是如何工作的,想像一下我們在處理保存新用 User 和相關 Profile 的控制器中有一個動作。下面的示例動作假設已經為創建單個 User 和單個 Profile,POST 了足夠的數據(使用 FormHelper):    1 public function add() {  2     if (!empty($this->request->data)) {  3         // 我們能保存 User 數據:  4         // 它放在 $this->request->data['User'] 中  5   6         $user = $this->User->save($this->request->data);  7   8         // 如果用戶被保存,添加這條信息到數據並保存 Profile。  9  10         if (!empty($user)) { 11             // 新創建的 User ID 已經被賦值給 $this->User->id. 12             $this->request->data['Profile']['user_id'] = $this->User->id; 13  14             // 由於 User hasOne Profile,因此可以通過 User 模型訪問 Profile 模型: 15             $this->User->Profile->save($this->request->data); 16         } 17     } 18 } 作為一條規則,當帶有 hasOne、hasMany、belongsTo 關聯時,全部與鍵有關。基本思路是從一個模型中獲取鍵,並將其放入另一個模型的外鍵列中。有時需要涉及使用保存後的模型類的 $id 屬性,但是其它情況下只涉及從 POST 給控制器動作的表單的隱藏域(hidden input)中得到的 ID。   作為上述基本方法的補充,CakePHP 還提供了一個非常有用的方法 saveAssociated(),它允許你用一個簡短的方式校驗和保存多個模型。另外,saveAssociated() 還提供了事務支持以確保數據庫中的數據的完整(例如,一個模型保存失敗,另一個模型也就不保存了)。   注解   為使事務工作在 MySQL 中正常工作,表必須使用 InnoDB 引擎。記住,MyISAM 表不支持事務。   來看看如何使用 saveAssociated() 同時保存 Company 和 Account 模型吧。   首先,需要同時為 Company 和 Account 創建表單(假設 Company hasMany Account):    1 echo $this->Form->create('Company', array('action' => 'add'));  2 echo $this->Form->input('Company.name', array('label' => 'Company name'));  3 echo $this->Form->input('Company.description');  4 echo $this->Form->input('Company.location');  5   6 echo $this->Form->input('Account.0.name', array('label' => 'Account name'));  7 echo $this->Form->input('Account.0.username');  8 echo $this->Form->input('Account.0.email');  9  10 echo $this->Form->end('Add'); 看看為 Acount 模型命名表單列的方法。如果 Company 是主模型,saveAssociated() 期望相關模型(Account)數據以指定的格式放進數組。並且擁有我們需要的 Account.0.fieldName。   注解   上面的列命名對於 hasMany 關聯是必須的。如果關聯是 hasOne,你就得為關聯模型使用 ModelName.fieldName 了。   現在,可以在 CompaniesController 中創建 add() 動作了:   1 public function add() { 2     if (!empty($this->request->data)) { 3         // 使用如下方式避免校驗錯誤: 4         unset($this->Company->Account->validate['company_id']); 5         $this->Company->saveAssociated($this->request->data); 6     } 7 } 這就是全部的步驟了。現在 Company 和 Account 模型將同時被校驗和保存。默認情況下,saveAssociated 將檢驗傳遞過來的全部值,然後嘗試執行每一個保存。   通過數據保存 hasMany 讓我們來看看存在在 join 表裡的兩個模型的數據是如何保存的。就像 hasMany 貫穿 (連接模型) 一節展示的那樣,join 表是用 hasMany 類型的關系關聯到每個模型的。 我們的例子包括 Cake 學校的負責人要求我們寫一個程序允許它記錄一個學生在某門課上出勤的天數和等級。下面是示例代碼:    1 // Controller/CourseMembershipController.php  2 class CourseMembershipsController extends AppController {  3     public $uses = array('CourseMembership');  4   5     public function index() {  6         $this->set('courseMembershipsList', $this->CourseMembership->find('all'));  7     }  8   9     public function add() { 10         if ($this->request->is('post')) { 11             if ($this->CourseMembership->saveAssociated($this->request->data)) { 12                 $this->redirect(array('action' => 'index')); 13             } 14         } 15     } 16 } 17  18 // View/CourseMemberships/add.ctp 19  20 <?php echo $this->Form->create('CourseMembership'); ?> 21 <?php echo $this->Form->input('Student.first_name'); ?> 22 <?php echo $this->Form->input('Student.last_name'); ?> 23 <?php echo $this->Form->input('Course.name'); ?> 24 <?php echo $this->Form->input('CourseMembership.days_attended'); ?> 25 <?php echo $this->Form->input('CourseMembership.grade'); ?> 26     <button type="submit">Save</button> 27 <?php echo  $this->Form->end(); ?> 提交的數據數組如下:    1 Array  2 (  3     [Student] => Array  4     (  5         [first_name] => Joe  6         [last_name] => Bloggs  7     )  8   9     [Course] => Array 10     ( 11         [name] => Cake 12     ) 13  14     [CourseMembership] => Array 15     ( 16         [days_attended] => 5 17         [grade] => A 18     ) 19  20 ) Cake 會很樂意使用一個帶有這種數據結構的 saveAssociated 調用就能同時保存很多,並將 Student 和 Course 的外鍵賦予 CouseMembership. 如果我們運行 CourseMembershipsController 上的 index 動作,從 find(‘all’) 中獲取的數據結構如下:    1 Array  2 (  3     [0] => Array  4     (  5         [CourseMembership] => Array  6         (  7             [id] => 1  8             [student_id] => 1  9             [course_id] => 1 10             [days_attended] => 5 11             [grade] => A 12         ) 13  14         [Student] => Array 15         ( 16             [id] => 1 17             [first_name] => Joe 18             [last_name] => Bloggs 19         ) 20  21         [Course] => Array 22         ( 23             [id] => 1 24             [name] => Cake 25         ) 26     ) 27 ) 當然,還有很多帶有連接模型的工作的方法。上面的版本假定你想要立刻保存每樣東西。 還有這樣的情況:你想獨立地創建 Student 和 Course,稍後再指定兩者與 CourseMembership 的關聯。 因此你可能有一個允許利用列表或ID選擇存在的學生和課程及兩個 CourseMembership 元列的表單,例如:   1 // View/CourseMemberships/add.ctp 2  3 <?php echo $this->Form->create('CourseMembership'); ?> 4 <?php echo $this->Form->input('Student.id', array('type' => 'text', 'label' => 'Student ID', 'default' => 1)); ?> 5 <?php echo $this->Form->input('Course.id', array('type' => 'text', 'label' => 'Course ID', 'default' => 1)); ?> 6 <?php echo $this->Form->input('CourseMembership.days_attended'); ?> 7 <?php echo $this->Form->input('CourseMembership.grade'); ?> 8     <button type="submit">Save</button> 9 <?php echo $this->Form->end(); ?> 所得到的 POST 數據:    1 Array  2 (  3     [Student] => Array  4     (  5         [id] => 1  6     )  7   8     [Course] => Array  9     ( 10         [id] => 1 11     ) 12  13     [CourseMembership] => Array 14     ( 15         [days_attended] => 10 16         [grade] => 5 17     ) 18 ) Cake 利用 saveAssociated 將 Student id 和 Course id 推入 CourseMembership。   保存相關模型數據 (HABTM) 通過 hasOne、belongsTo、hasMany 保存有關聯的模型是非常簡單的: 只需要將關聯模型的 ID 填入外鍵列。 填完之後,只要調用模型上的 save() 方法,一切就都被正確的串連起來了。 下面是准備傳遞給 Tag 模型的 save() 方法的數據數組格式的示例:    1 Array  2 (  3     [Recipe] => Array  4         (  5             [id] => 42  6         )  7     [Tag] => Array  8         (  9             [name] => Italian 10         ) 11 ) 也可以在 saveAll() 中使用這種格式保存多條記錄和與它們有 HABTM 關聯的的模型,格式如下:    1 Array  2 (  3     [0] => Array  4         (  5             [Recipe] => Array  6                 (  7                     [id] => 42  8                 )  9             [Tag] => Array 10                 ( 11                     [name] => Italian 12                 ) 13         ) 14     [1] => Array 15         ( 16             [Recipe] => Array 17                 ( 18                     [id] => 42 19                 ) 20             [Tag] => Array 21                 ( 22                     [name] => Pasta 23                 ) 24         ) 25     [2] => Array 26         ( 27             [Recipe] => Array 28                 ( 29                     [id] => 51 30                 ) 31             [Tag] => Array 32                 ( 33                     [name] => Mexican 34                 ) 35         ) 36     [3] => Array 37         ( 38             [Recipe] => Array 39                 ( 40                     [id] => 17 41                 ) 42             [Tag] => Array 43                 ( 44                     [name] => American (new) 45                 ) 46         ) 47 ) 將上面的數組傳遞給 saveAll() 將創建所包含的 tag ,每個都與它們各自的 recipe 關聯。   作為示例,我們建立了創建新 tag 和運行期間生成與 recipe 關聯的正確數據數組的表單。   這個簡單的表單如下:(我們假定 $recipe_id 已經設置了):   1 <?php echo $this->Form->create('Tag'); ?> 2 <?php echo $this->Form->input( 3         'Recipe.id', 4         array('type' => 'hidden', 'value' => $recipe_id) 5     ); ?> 6 <?php echo $this->Form->input('Tag.name'); ?> 7 <?php echo $this->Form->end('Add Tag'); ?> 在這個例子中,你能看到 Recipe.id hidden 域,其值被設置為我們的 tag 想要連接的 recipe 的 ID。   當在控制器中調用 save() 方法,它將自動將 HABTM 數據保存到數據庫:   1 public function add() { 2     // 保存關聯 3     if ($this->Tag->save($this->request->data)) { 4         // 保存成功後要做的事情 5     } 6 } 這段代碼將創建一個新的 Tag 並與 Recipe 相關聯,其 ID 由 $this->request->data['Recipe']['id'] 設置。   某些情況下,我們可能希望呈現的關聯數據能夠包含下拉 select 列表。數據可能使用 find('list') 從模型中取出並且賦給用模型名命名的視圖變量。 同名的 input 將自動把數據放進 <select> :   1 // 控制器中的代碼: 2 $this->set('tags', $this->Recipe->Tag->find('list')); 1 // 視圖中的代碼: 2 $this->Form->input('tags'); 更可能的情形是一個 HABTM 關系包含一個允許多選的 <select>。例如,一個 Recipe 可能被賦了多個 Tag。在這種情況下,數據以相同的方式從模型中取出,但是表單 input 定義稍有不同。tag 的命名使用 ModelName 約定:   1 // 控制器中的代碼: 2 $this->set('tags', $this->Recipe->Tag->find('list')); 1 // 視圖中的代碼: 2 $this->Form->input('Tag'); 使用上面這段代碼,將建立可多選的下拉列表(select),允許多選自動被保存到已添加或已保存到數據庫中的 Recipe。   當 HABTM 變得復雜時怎麼辦? 默認情況下,Cake 在保存 HABTM 關系時,會先刪除連接表中的所有行。 例如,有一個擁有10個 Children 關聯的 Club。帶著2個 children 更新 Club。Club 將只有2個 Children,而不是12個。   要注意,如果想要向帶有 HABTM 的連接表添加更多的列(建立時間或者元數據)是可能的,重要的是要明白你有一個簡單的選項。   兩個模型間的 HasAndBelongsToMany 關聯實際上是同時擁有 hasMany 和 belongsTo 關聯的三個模型關系的簡寫。   考慮下面的例子:   Child hasAndBelongsToMany Club 另一個方法是添加一個 Membership 模型:   Child hasMany Membership Membership belongsTo Child, Club Club hasMany Membership. 這兩個例子幾乎是相同的。它們在數據庫中使用了命名相同的 amount 列,模型中的 amount 也是相同的。最重要的不同是 “join” 表命名不同,並且其行為更具可預知性。   小技巧   當連接表包含外鍵以外的擴展列時,通過將數組的 'unique' 設置為 “‘keepExisting’”,能夠防止丟失擴展列的值。同樣,可以認為設置 ‘unique’ => true,在保存操作過程中不會丟失擴展列的數據。參見 HABTM association arrays。   不過,更多情況下,為連接表建立一個模型,並像上面的例子那樣設置 hasMany、belongsTo 關聯,代替使用 HABTM 關聯,會更簡單。   數據表 雖然 CakePHP 可以有非數據庫驅動的數據源,但多數時候,都是有數據庫驅動的。 CakePHP 被設計成可以與 MySQL、MSSQL、Oracle、PostgreSQL 和其它數據庫一起工作。 你可以創建你平時所用的數據庫系統的表。在創建模型類時,模型將自動映射到已經建立的表上。表名被轉換為復數小寫,多個單詞的表名的單詞用下劃線間隔。例如,名為 Ingredient 的模型對應的表名為 ingredients。名為 EventRegistration 的模型對應的表名為 event_registrations。CakePHP 將檢查表來決定每個列的數據類型,並使用這些信息自動化各種特性,比如視圖中輸出的表單域。列名被轉換為小寫並用下劃線間隔。   使用 created 和 modified 列 通過在數據庫表中定義 created 和 modified 列作為 datetime 列,CakePHP 能夠識別這些域並自動在其中填入記錄在數據庫中創建的時間和保存的時間(除非被保存的數據中已經包含了這些域的值)。   在記錄最初添加時,created 和 modified 列將被設置為當前日期和時間。當已經存在的記錄被保存時,modified 列將被更新至當前日期和時間。   如果在 Model::save() 之前 $this->data 中包含了 updated、created、modified 數據(例如 Model::read 或者 Model::set),那麼這些值將從 $this->data 中獲取,並且不自動更新。 或者使用 unset($this->data['Model']['modified']) 等方法。總是可以覆蓋 Model::save() 方法來做這件事:    1 class AppModel extends Model {  2   3     public function save($data = null, $validate = true, $fieldList = array()) {  4         // 在每個保存操作前清除 modified 域值:  5         $this->set($data);  6         if (isset($this->data[$this->alias]['modified'])) {  7             unset($this->data[$this->alias]['modified']);  8         }  9         return parent::save($this->data, $validate, $fieldList); 10     } 11  12 }  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved