{"action":"created","issue":{"url":"https://api.github.com/repos/laravel/framework/issues/13706","repository_url":"https://api.github.com/repos/laravel/framework","labels_url":"https://api.github.com/repos/laravel/framework/issues/13706/labels{/name}","comments_url":"https://api.github.com/repos/laravel/framework/issues/13706/comments","events_url":"https://api.github.com/repos/laravel/framework/issues/13706/events","html_url":"https://github.com/laravel/framework/pull/13706","id":156859778,"number":13706,"title":"implement value object casting","user":{"login":"taylorotwell","id":463230,"avatar_url":"https://avatars.githubusercontent.com/u/463230?v=3","gravatar_id":"","url":"https://api.github.com/users/taylorotwell","html_url":"https://github.com/taylorotwell","followers_url":"https://api.github.com/users/taylorotwell/followers","following_url":"https://api.github.com/users/taylorotwell/following{/other_user}","gists_url":"https://api.github.com/users/taylorotwell/gists{/gist_id}","starred_url":"https://api.github.com/users/taylorotwell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/taylorotwell/subscriptions","organizations_url":"https://api.github.com/users/taylorotwell/orgs","repos_url":"https://api.github.com/users/taylorotwell/repos","events_url":"https://api.github.com/users/taylorotwell/events{/privacy}","received_events_url":"https://api.github.com/users/taylorotwell/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-05-25T21:57:55Z","updated_at":"2016-05-25T22:06:42Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/laravel/framework/pulls/13706","html_url":"https://github.com/laravel/framework/pull/13706","diff_url":"https://github.com/laravel/framework/pull/13706.diff","patch_url":"https://github.com/laravel/framework/pull/13706.patch"},"body":"This PR implements the ability to cast Eloquent values to arbitrary value objects. You may also cast an \"attribute\" that doesn't actually exist in the database which will allow you to create aggregate value objects that consist of multiple actual fields. Modifying the value object will affect the base model's attributes as you access them, so the model will always \"feel\" updated.\r\n\r\nValue objects MUST implement two methods:\r\n\r\n```php\r\nclass User extends Eloquent\r\n{\r\n    protected $casts = ['address' => Address::class];\r\n}\r\n\r\n\r\nclass Address\r\n{\r\n    public $lineOne, $lineTwo;\r\n\r\n    public function __construct($lineOne, $lineTwo)\r\n    {\r\n        $this->lineOne = $lineOne;\r\n        $this->lineTwo = $lineTwo;\r\n    }\r\n\r\n    public static function fromModelAttributes($model, $attributes)\r\n    {\r\n        return new static($attributes['line_one'], $attributes['line_two']);\r\n    }\r\n\r\n    public function toModelAttributes()\r\n    {\r\n        return [\r\n            'line_one' => $this->lineOne,\r\n            'line_two' => $this->lineTwo,\r\n        ];\r\n    }\r\n}\r\n```\r\n\r\nThe `fromModelAttributes` will be called when Eloquent needs to create an instance of the value object. The model instance and raw attribute array will be passed to the method and you may construct the value object however you wish. You have total freedom here.\r\n\r\nThe `toModelAttributes` method will be called by Eloquent when it needs to persist the value object's state back into the model. In this method you should return an array that maps back onto the Eloquent object's actual attributes that are stored in the database.\r\n\r\nUsing the example value object above, the following is perfectly valid:\r\n\r\n```php\r\n$user->address->lineOne = 'New Line 1';\r\n$user->save();\r\n```\r\n\r\nEloquent will sync the value object's state back into its attributes using the `toModelAttributes` automatically before saving.\r\n\r\nIf a value object is set to `null`, all of the attributes returned by `toModelAttributes` will be set to `null`:\r\n\r\n```php\r\n$user->address = null;\r\n$user->save();\r\n\r\n$user->line_one; // null\r\n$user->line_two; // null\r\n```\r\n\r\nWhen a value object cast object is resolved, the same instance will be returned each time you access it:\r\n\r\n```php\r\n$user->address\r\n$user->address // same instance\r\n```"},"comment":{"url":"https://api.github.com/repos/laravel/framework/issues/comments/221722384","html_url":"https://github.com/laravel/framework/pull/13706#issuecomment-221722384","issue_url":"https://api.github.com/repos/laravel/framework/issues/13706","id":221722384,"user":{"login":"pstephan1187","id":5191902,"avatar_url":"https://avatars.githubusercontent.com/u/5191902?v=3","gravatar_id":"","url":"https://api.github.com/users/pstephan1187","html_url":"https://github.com/pstephan1187","followers_url":"https://api.github.com/users/pstephan1187/followers","following_url":"https://api.github.com/users/pstephan1187/following{/other_user}","gists_url":"https://api.github.com/users/pstephan1187/gists{/gist_id}","starred_url":"https://api.github.com/users/pstephan1187/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pstephan1187/subscriptions","organizations_url":"https://api.github.com/users/pstephan1187/orgs","repos_url":"https://api.github.com/users/pstephan1187/repos","events_url":"https://api.github.com/users/pstephan1187/events{/privacy}","received_events_url":"https://api.github.com/users/pstephan1187/received_events","type":"User","site_admin":false},"created_at":"2016-05-25T22:06:42Z","updated_at":"2016-05-25T22:06:42Z","body":"Assuming this behaves as expected when casting the object to JSON, I think it's great!"}}
{"actor":{"display_login":"pstephan1187"}}