ปัจจุบัน Eloquent ของ Laravel Framework ยังไม่รองรับการบันทึกข้อมูลที่มี Primary Key แบบหลาย Columns ได้ ผมได้ค้นหาจากอินเตอร์เน็ต และพบว่ามีคนที่แนะนำแนวทางแก้ไข โดยใช้วิธีการ Overide method save ของ Eloquent ขึ้นมาแทน ซึ่งผมได้ทดลองใช้แล้วสามารถทำงานได้อย่างถูกต้อง จึงขอแนะนำการนำ Method save ที่ถูกปรับปรุงมาเขียนเป็น Base Class ของ Model ดังตัวอย่าง
โดยการนำเอา BaseModel นี้ไปใช้ในรูปแบบการ Extend Model Class ดังต่อไปนี้
และสามารถเรียกใช้งานได้เป็นปกติได้เลย เช่น
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use DB; class BaseModel extends Model { public function save(array $options = []) { if( ! is_array($this->getKeyName())) { return parent::save($options); } // Fire Event for others to hook if($this->fireModelEvent('saving') === false) return false; // Prepare query for inserting or updating $query = $this->newQueryWithoutScopes(); // Perform Update if ($this->exists) { if (count($this->getDirty()) > 0) { // Fire Event for others to hook if ($this->fireModelEvent('updating') === false) { return false; } // Touch the timestamps if ($this->timestamps) { $this->updateTimestamps(); } // // START FIX // // Convert primary key into an array if it's a single value $primary = (count($this->getKeyName()) > 1) ? $this->getKeyName() : [$this->getKeyName()]; // Fetch the primary key(s) values before any changes $unique = array_intersect_key($this->original, array_flip($primary)); // Fetch the primary key(s) values after any changes $unique = !empty($unique) ? $unique : array_intersect_key($this->getAttributes(), array_flip($primary)); // Fetch the element of the array if the array contains only a single element //$unique = (count($unique) <> 1) ? $unique : reset($unique); // Apply SQL logic $query->where($unique); // // END FIX // // Update the records $query->update($this->getDirty()); // Fire an event for hooking into $this->fireModelEvent('updated', false); } } // Insert else { // Fire an event for hooking into if ($this->fireModelEvent('creating') === false) return false; // Touch the timestamps if($this->timestamps) { $this->updateTimestamps(); } // Retrieve the attributes $attributes = $this->attributes; if ($this->incrementing && !is_array($this->getKeyName())) { $this->insertAndSetId($query, $attributes); } else { $query->insert($attributes); } // Set exists to true in case someone tries to update it during an event $this->exists = true; // Fire an event for hooking into $this->fireModelEvent('created', false); } // Fires an event $this->fireModelEvent('saved', false); // Sync $this->original = $this->attributes; // Touches all relations if (array_get($options, 'touch', true)) $this->touchOwners(); return true; } } |
โดยการนำเอา BaseModel นี้ไปใช้ในรูปแบบการ Extend Model Class ดังต่อไปนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use App\Models\BaseModel; class MyTable extends BaseModel { protected $table = 'MyTable'; protected $primaryKey = ['MY_KEY_COLUMN_1', 'MY_KEY_COLUMN_2', 'MY_KEY_COLUMN_3']; public $incrementing = false; public $timestamps = false; } |
และสามารถเรียกใช้งานได้เป็นปกติได้เลย เช่น
1 2 3 4 5 6 7 | $myTable = new MyTable; $myTable->FIELD1 = 'Feild1_Value'; $myTable->FIELD2 = 'Field2_Value'; $myTable->MY_KEY_COLUMN1 = 'Key1_Value'; $myTable->MY_KEY_COLUMN2 = 'Key2_Value'; $myTable->MY_KEY_COLUMN3 = 'Key3_Value'; $myTable->save(); |
Comments
Post a Comment