{"id":1373,"date":"2015-01-31T17:24:37","date_gmt":"2015-01-31T09:24:37","guid":{"rendered":"http:\/\/blog.turn.tw\/?page_id=1373"},"modified":"2015-01-31T17:24:37","modified_gmt":"2015-01-31T09:24:37","slug":"eloquent-crud%ef%bc%9asave","status":"publish","type":"page","link":"https:\/\/blog.turn.tw\/?page_id=1373","title":{"rendered":"Eloquent CRUD\uff1asave"},"content":{"rendered":"<p>\u66f4\u65b0\u4e00\u500bentity\uff0c\u5c31\u8ddf\u5132\u5b58\u4e00\u500b\u65b0entity\u4e00\u6a23\uff0c\u9700\u8981\u4f7f\u7528save\u65b9\u6cd5\uff1a<\/p>\n<pre>\r\n$user = User::find(1);\r\n\r\n$user->email = 'john@foo.com';\r\n\r\n$user->save();\r\n<\/pre>\n<p>\u80cc\u5f8c\u767c\u751f\u4e86\u4ec0\u9ebc\u4e8b\u5462\uff1f\u8b93\u6211\u5011\u4e00\u4e00\u4f86\u770b\u3002<\/p>\n<pre>\r\n\t\/**\r\n\t * Save the model to the database.\r\n\t *\r\n\t * @param  array  $options\r\n\t * @return bool\r\n\t *\/\r\n\tpublic function save(array $options = array())\r\n\t{\r\n\t\t$query = $this->newQueryWithoutScopes();\r\n\r\n\t\t\/\/ If the \"saving\" event returns false we'll bail out of the save and return\r\n\t\t\/\/ false, indicating that the save failed. This gives an opportunities to\r\n\t\t\/\/ listeners to cancel save operations if validations fail or whatever.\r\n\t\tif ($this->fireModelEvent('saving') === false)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t\/\/ If the model already exists in the database we can just update our record\r\n\t\t\/\/ that is already in this database using the current IDs in this \"where\"\r\n\t\t\/\/ clause to only update this model. Otherwise, we'll just insert them.\r\n\t\tif ($this->exists)\r\n\t\t{\r\n\t\t\t$saved = $this->performUpdate($query, $options);\r\n\t\t}\r\n\r\n\t\t\/\/ If the model is brand new, we'll insert it into our database and set the\r\n\t\t\/\/ ID attribute on the model to the value of the newly inserted row's ID\r\n\t\t\/\/ which is typically an auto-increment value managed by the database.\r\n\t\telse\r\n\t\t{\r\n\t\t\t$saved = $this->performInsert($query, $options);\r\n\t\t}\r\n\r\n\t\tif ($saved) $this->finishSave($options);\r\n\r\n\t\treturn $saved;\r\n\t}\r\n\r\n<\/pre>\n<p>\u5728\u524d\u4e00\u7bc7<a href=\"https:\/\/blog.turn.tw\/?page_id=1360\" title=\"Eloquent CRUD\uff1afind\">Eloquent CRUD\uff1afind<\/a>\u6211\u5011\u770b\u5230\u4e86Eloquent\\Model\u5927\u91cf\u904b\u7528\u5230Eloquent\\Builder\u548cQuery\\Builder\u985e\u5225\u3002<br \/>\nnewQueryWithoutScopes\u5f9e\u547d\u540d\u53ef\u731c\u60f3\u662f\u5728\u88fd\u4f5cQuery\\Builder\u5be6\u9ad4\u3002<br \/>\n\u6211\u5011\u628a\u91cd\u9ede\u653e\u5728performUpdate\u548cperformInsert\u5427<\/p>\n<pre>\r\n\t\/**\r\n\t * Perform a model update operation.\r\n\t *\r\n\t * @param  \\Illuminate\\Database\\Eloquent\\Builder  $query\r\n\t * @return bool|null\r\n\t *\/\r\n\tprotected function performUpdate(Builder $query, array $options)\r\n\t{\r\n\t\t$dirty = $this->getDirty();\r\n\r\n\t\tif (count($dirty) > 0)\r\n\t\t{\r\n\t\t\t\/\/ If the updating event returns false, we will cancel the update operation so\r\n\t\t\t\/\/ developers can hook Validation systems into their models and cancel this\r\n\t\t\t\/\/ operation if the model does not pass validation. Otherwise, we update.\r\n\t\t\tif ($this->fireModelEvent('updating') === false)\r\n\t\t\t{\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\r\n\t\t\t\/\/ First we need to create a fresh query instance and touch the creation and\r\n\t\t\t\/\/ update timestamp on the model which are maintained by us for developer\r\n\t\t\t\/\/ convenience. Then we will just continue saving the model instances.\r\n\t\t\tif ($this->timestamps && array_get($options, 'timestamps', true))\r\n\t\t\t{\r\n\t\t\t\t$this->updateTimestamps();\r\n\t\t\t}\r\n\r\n\t\t\t\/\/ Once we have run the update operation, we will fire the \"updated\" event for\r\n\t\t\t\/\/ this model instance. This will allow developers to hook into these after\r\n\t\t\t\/\/ models are updated, giving them a chance to do any special processing.\r\n\t\t\t$dirty = $this->getDirty();\r\n\r\n\t\t\tif (count($dirty) > 0)\r\n\t\t\t{\r\n\t\t\t\t$this->setKeysForSaveQuery($query)->update($dirty);\r\n\r\n\t\t\t\t$this->fireModelEvent('updated', false);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n<\/pre>\n<p>\u9996\u5148\u5229\u7528getDirty\u5f97\u77e5\u54ea\u4e9b\u5c6c\u6027\u88ab\u66f4\u52d5\u904e\u3001\u9700\u8981\u66f4\u65b0\uff1a<\/p>\n<pre>\r\n\t\/**\r\n\t * Get the attributes that have been changed since last sync.\r\n\t *\r\n\t * @return array\r\n\t *\/\r\n\tpublic function getDirty()\r\n\t{\r\n\t\t$dirty = array();\r\n\r\n\t\tforeach ($this->attributes as $key => $value)\r\n\t\t{\r\n\t\t\tif ( ! array_key_exists($key, $this->original))\r\n\t\t\t{\r\n\t\t\t\t$dirty[$key] = $value;\r\n\t\t\t}\r\n\t\t\telseif ($value !== $this->original[$key] &&\r\n                                 ! $this->originalIsNumericallyEquivalent($key))\r\n\t\t\t{\r\n\t\t\t\t$dirty[$key] = $value;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn $dirty;\r\n\t}\r\n<\/pre>\n<p>\u770b\u8d77\u4f86\u662f\u5728\u6bd4\u8f03attributes\u8ddforiginal\u9663\u5217\u7684\u5167\u5bb9\uff0c\u4f46\u662f\u6211\u5011\u8a2d\u5b9avalue\u6642\u4e26\u6c92\u6709\u78b0\u5230\u5b83\u5011\u5440\uff1f<\/p>\n<pre>\r\n$user->email = 'john@foo.com';\r\n<\/pre>\n<p>\u6211\u5011\u4e26\u4e0d\u662f<\/p>\n<pre>\r\n$user->attributes['email'] = 'john@foo.com';\r\n<\/pre>\n<p>getDirty\u600e\u9ebc\u6703\u6bd4\u8f03\u90a3\u5169\u500b\u9663\u5217\u5462\uff1f<br \/>\n\u539f\u4f86\u662fmagic method __set<\/p>\n<pre>\r\n\t\/**\r\n\t * Dynamically set attributes on the model.\r\n\t *\r\n\t * @param  string  $key\r\n\t * @param  mixed   $value\r\n\t * @return void\r\n\t *\/\r\n\tpublic function __set($key, $value)\r\n\t{\r\n\t\t$this->setAttribute($key, $value);\r\n\t}\r\n<\/pre>\n<p>\u9664\u6b64\u4e4b\u5916\uff0cperformUpdate\u7684\u5176\u4ed6\u90e8\u4efd\u770b\u8d77\u4f86\u90fd\u5f88\u76f4\u89c0\u3002<\/p>\n<p>\u63a5\u8457\u770bperformInsert\uff1a<\/p>\n<pre>\r\n\t\/**\r\n\t * Perform a model insert operation.\r\n\t *\r\n\t * @param  \\Illuminate\\Database\\Eloquent\\Builder  $query\r\n\t * @return bool\r\n\t *\/\r\n\tprotected function performInsert(Builder $query, array $options)\r\n\t{\r\n\t\tif ($this->fireModelEvent('creating') === false) return false;\r\n\r\n\t\t\/\/ First we'll need to create a fresh query instance and touch the creation and\r\n\t\t\/\/ update timestamps on this model, which are maintained by us for developer\r\n\t\t\/\/ convenience. After, we will just continue saving these model instances.\r\n\t\tif ($this->timestamps && array_get($options, 'timestamps', true))\r\n\t\t{\r\n\t\t\t$this->updateTimestamps();\r\n\t\t}\r\n\r\n\t\t\/\/ If the model has an incrementing key, we can use the \"insertGetId\" method on\r\n\t\t\/\/ the query builder, which will give us back the final inserted ID for this\r\n\t\t\/\/ table from the database. Not all tables have to be incrementing though.\r\n\t\t$attributes = $this->attributes;\r\n\r\n\t\tif ($this->incrementing)\r\n\t\t{\r\n\t\t\t$this->insertAndSetId($query, $attributes);\r\n\t\t}\r\n\r\n\t\t\/\/ If the table is not incrementing we'll simply insert this attributes as they\r\n\t\t\/\/ are, as this attributes arrays must contain an \"id\" column already placed\r\n\t\t\/\/ there by the developer as the manually determined key for these models.\r\n\t\telse\r\n\t\t{\r\n\t\t\t$query->insert($attributes);\r\n\t\t}\r\n\r\n\t\t\/\/ We will go ahead and set the exists property to true, so that it is set when\r\n\t\t\/\/ the created event is fired, just in case the developer tries to update it\r\n\t\t\/\/ during the event. This will allow them to do so and run an update here.\r\n\t\t$this->exists = true;\r\n\r\n\t\t$this->fireModelEvent('created', false);\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u66f4\u65b0\u4e00\u500bentity\uff0c\u5c31\u8ddf\u5132\u5b58\u4e00\u500b\u65b0entity\u4e00\u6a23\uff0c\u9700\u8981\u4f7f\u7528save\u65b9\u6cd5\uff1a $user = User::fi &hellip; <a href=\"https:\/\/blog.turn.tw\/?page_id=1373\" class=\"more-link\">\u7e7c\u7e8c\u95b1\u8b80 <span class=\"screen-reader-text\">Eloquent CRUD\uff1asave<\/span> <span class=\"meta-nav\">&rarr;<\/span> <\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"_mi_skip_tracking":false},"_links":{"self":[{"href":"https:\/\/blog.turn.tw\/index.php?rest_route=\/wp\/v2\/pages\/1373"}],"collection":[{"href":"https:\/\/blog.turn.tw\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blog.turn.tw\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blog.turn.tw\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.turn.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1373"}],"version-history":[{"count":1,"href":"https:\/\/blog.turn.tw\/index.php?rest_route=\/wp\/v2\/pages\/1373\/revisions"}],"predecessor-version":[{"id":1375,"href":"https:\/\/blog.turn.tw\/index.php?rest_route=\/wp\/v2\/pages\/1373\/revisions\/1375"}],"wp:attachment":[{"href":"https:\/\/blog.turn.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}