{"action":"created","issue":{"url":"https://api.github.com/repos/nova-framework/framework/issues/890","repository_url":"https://api.github.com/repos/nova-framework/framework","labels_url":"https://api.github.com/repos/nova-framework/framework/issues/890/labels{/name}","comments_url":"https://api.github.com/repos/nova-framework/framework/issues/890/comments","events_url":"https://api.github.com/repos/nova-framework/framework/issues/890/events","html_url":"https://github.com/nova-framework/framework/pull/890","id":157167236,"number":890,"title":"An improved Legacy Rendering System, Database API with Object Relational Models and a simple but powerful Mailing System on the New Style APIs","user":{"login":"LuckyCyborg","id":13488485,"avatar_url":"https://avatars.githubusercontent.com/u/13488485?v=3","gravatar_id":"","url":"https://api.github.com/users/LuckyCyborg","html_url":"https://github.com/LuckyCyborg","followers_url":"https://api.github.com/users/LuckyCyborg/followers","following_url":"https://api.github.com/users/LuckyCyborg/following{/other_user}","gists_url":"https://api.github.com/users/LuckyCyborg/gists{/gist_id}","starred_url":"https://api.github.com/users/LuckyCyborg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LuckyCyborg/subscriptions","organizations_url":"https://api.github.com/users/LuckyCyborg/orgs","repos_url":"https://api.github.com/users/LuckyCyborg/repos","events_url":"https://api.github.com/users/LuckyCyborg/events{/privacy}","received_events_url":"https://api.github.com/users/LuckyCyborg/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":37,"created_at":"2016-05-27T09:34:25Z","updated_at":"2016-05-27T22:00:24Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/nova-framework/framework/pulls/890","html_url":"https://github.com/nova-framework/framework/pull/890","diff_url":"https://github.com/nova-framework/framework/pull/890.diff","patch_url":"https://github.com/nova-framework/framework/pull/890.patch"},"body":"# An improved Legacy Rendering System\r\n\r\n- [Introduction](#legacy-introduction)\r\n- [Basic Usage](#legacy-basic-usage)\r\n\r\n<a name=\"legacy-introduction\"></a>\r\n\r\n## Introduction\r\n\r\nThe improved **Legacy Rendering System** will **queue** the generated View and Template instances, along with the developer's calling of the **Legacy View Calls**.\r\n\r\nThey will be processed on the Controller's **Middleware**, when the current Action returns **NULL**, together with the given **Legacy Header Calls**, and there will be generated a **Response** instance and it will be sent according.\r\n\r\nThis Design permit **a faster page / response generation** and an improved compatibility and interchangeability between the **Classic and New Style APIs**.\r\n\r\n<a name=\"legacy-basic-usage\"></a>\r\n## Basic Usage\r\n\r\n#### There are **no changes** on the user-exposed \\*\\*Legacy Rendering API\\*\\*.\r\n\r\n# Database API - Object Relational Models\r\n\r\n- [Introduction](#introduction)\r\n- [Basic Usage](#basic-usage)\r\n- [Mass Assignment](#mass-assignment)\r\n- [Insert, Update, Delete](#insert-update-delete)\r\n- [Soft Deleting](#soft-deleting)\r\n- [Timestamps](#timestamps)\r\n- [Query Scopes](#query-scopes)\r\n- [Relationships](#relationships)\r\n- [Querying Relations](#querying-relations)\r\n- [Eager Loading](#eager-loading)\r\n- [Inserting Related Models](#inserting-related-models)\r\n- [Touching Parent Timestamps](#touching-parent-timestamps)\r\n- [Working With Pivot Tables](#working-with-pivot-tables)\r\n- [Collections](#collections)\r\n- [Accessors & Mutators](#accessors-and-mutators)\r\n- [Date Mutators](#date-mutators)\r\n- [Model Events](#model-events)\r\n- [Model Observers](#model-observers)\r\n- [Converting To Arrays / JSON](#converting-to-arrays-or-json)\r\n\r\n<a name=\"introduction\"></a>\r\n## Introduction\r\n\r\nThe Database ORM included with Nova Framework provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding \"Model\" which is used to interact with that table.\r\n\r\nBefore getting started, be sure to configure a database connection in `app/Config/Database.php`.\r\n\r\n<a name=\"basic-usage\"></a>\r\n## Basic Usage\r\n\r\nTo get started, create an ORM model. Models typically live in the `app/Models` directory, but you are free to place them anywhere that can be auto-loaded according to your `composer.json` file.\r\n\r\n#### Defining An ORM Model\r\n\r\n    class User extends \\Database\\ORM\\Model {}\r\n\r\nNote that we did not tell ORM which table to use for our `User` model. The lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, ORM will assume the `User` model stores records in the `users` table. You may specify a custom table by defining a `table` property on your model:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $table = 'my_users';\r\n\r\n    }\r\n\r\n> **Note:** ORM will also assume that each table has a primary key column named `id`. You may define a `primaryKey` property to override this convention. Likewise, you may define a `connection` property to override the name of the database connection that should be used when utilizing the model.\r\n\r\nOnce a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to `false`.\r\n\r\n#### Retrieving All Models\r\n\r\n    $users = User::all();\r\n\r\n#### Retrieving A Record By Primary Key\r\n\r\n    $user = User::find(1);\r\n\r\n    var_dump($user->name);\r\n\r\n> **Note:** All methods available on the QueryBuilder are also available when querying ORM models.\r\n\r\n#### Retrieving A Model By Primary Key Or Throw An Exception\r\n\r\nSometimes you may wish to throw an exception if a model is not found, allowing you to catch the exceptions using an `App::error` handler and display a 404 page.\r\n\r\n    $model = User::findOrFail(1);\r\n\r\n    $model = User::where('votes', '>', 100)->firstOrFail();\r\n\r\nTo register the error handler, listen for the `ModelNotFoundException`\r\n\r\n    use Database\\ORM\\ModelNotFoundException;\r\n\r\n    App::error(function(ModelNotFoundException $e)\r\n    {\r\n        return Response::make('Not Found', 404);\r\n    });\r\n\r\n#### Querying Using ORM Models\r\n\r\n    $users = User::where('votes', '>', 100)->take(10)->get();\r\n\r\n    foreach ($users as $user)\r\n    {\r\n        var_dump($user->name);\r\n    }\r\n\r\n#### ORM Aggregates\r\n\r\nOf course, you may also use the query builder aggregate functions.\r\n\r\n    $count = User::where('votes', '>', 100)->count();\r\n\r\nIf you are unable to generate the query you need via the fluent interface, feel free to use `whereRaw`:\r\n\r\n    $users = User::whereRaw('age > ? and votes = 100', array(25))->get();\r\n\r\n#### Chunking Results\r\n\r\nIf you need to process a lot (thousands) of ORM records, using the `chunk` command will allow you to do without eating all of your RAM:\r\n\r\n    User::chunk(200, function($users)\r\n    {\r\n        foreach ($users as $user)\r\n        {\r\n            //\r\n        }\r\n    });\r\n\r\nThe first argument passed to the method is the number of records you wish to receive per \"chunk\". The Closure passed as the second argument will be called for each chunk that is pulled from the database.\r\n\r\n#### Specifying The Query Connection\r\n\r\nYou may also specify which database connection should be used when running an ORM query. Simply use the `on` method:\r\n\r\n    $user = User::on('connection-name')->find(1);\r\n\r\n<a name=\"mass-assignment\"></a>\r\n## Mass Assignment\r\n\r\nWhen creating a new model, you pass an array of attributes to the model constructor. These attributes are then assigned to the model via mass-assignment. This is convenient; however, can be a **serious** security concern when blindly passing user input into a model. If user input is blindly passed into a model, the user is free to modify **any** and **all** of the model's attributes. For this reason, all ORM models protect against mass-assignment by default.\r\n\r\nTo get started, set the `fillable` or `guarded` properties on your model.\r\n\r\n#### Defining Fillable Attributes On A Model\r\n\r\nThe `fillable` property specifies which attributes should be mass-assignable. This can be set at the class or instance level.\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $fillable = array('first_name', 'last_name', 'email');\r\n\r\n    }\r\n\r\nIn this example, only the three listed attributes will be mass-assignable.\r\n\r\n#### Defining Guarded Attributes On A Model\r\n\r\nThe inverse of `fillable` is `guarded`, and serves as a \"black-list\" instead of a \"white-list\":\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $guarded = array('id', 'password');\r\n\r\n    }\r\n\r\n> **Note:** When using `guarded`, you should still never pass `Input::get()` or any raw array of user controlled input into a `save` or `update` method, as any column that is not guarded may be updated.\r\n\r\n#### Blocking All Attributes From Mass Assignment\r\n\r\nIn the example above, the `id` and `password` attributes may **not** be mass assigned. All other attributes will be mass assignable. You may also block **all** attributes from mass assignment using the guard property:\r\n\r\n    protected $guarded = array('*');\r\n\r\n<a name=\"insert-update-delete\"></a>\r\n## Insert, Update, Delete\r\n\r\nTo create a new record in the database from a model, simply create a new model instance and call the `save` method.\r\n\r\n#### Saving A New Model\r\n\r\n    $user = new User;\r\n\r\n    $user->name = 'John';\r\n\r\n    $user->save();\r\n\r\n> **Note:** Typically, your ORM models will have auto-incrementing keys. However, if you wish to specify your own keys, set the `incrementing` property on your model to `false`.\r\n\r\nYou may also use the `create` method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a `fillable` or `guarded` attribute on the model, as all ORM models protect against mass-assignment.\r\n\r\nAfter saving or creating a new model that uses auto-incrementing IDs, you may retrieve the ID by accessing the object's `id` attribute:\r\n\r\n    $insertedId = $user->id;\r\n\r\n#### Setting The Guarded Attributes On The Model\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $guarded = array('id', 'account_id');\r\n\r\n    }\r\n\r\n#### Using The Model Create Method\r\n\r\n    // Create a new user in the database...\r\n    $user = User::create(array('name' => 'John'));\r\n\r\n    // Retrieve the user by the attributes, or create it if it doesn't exist...\r\n    $user = User::firstOrCreate(array('name' => 'John'));\r\n\r\n    // Retrieve the user by the attributes, or instantiate a new instance...\r\n    $user = User::firstOrNew(array('name' => 'John'));\r\n\r\n#### Updating A Retrieved Model\r\n\r\nTo update a model, you may retrieve it, change an attribute, and use the `save` method:\r\n\r\n    $user = User::find(1);\r\n\r\n    $user->email = 'john@foo.com';\r\n\r\n    $user->save();\r\n\r\n#### Saving A Model And Relationships\r\n\r\nSometimes you may wish to save not only a model, but also all of its relationships. To do so, you may use the `push` method:\r\n\r\n    $user->push();\r\n\r\nYou may also run updates as queries against a set of models:\r\n\r\n    $affectedRows = User::where('votes', '>', 100)->update(array('status' => 2));\r\n\r\n#### Deleting An Existing Model\r\n\r\nTo delete a model, simply call the `delete` method on the instance:\r\n\r\n    $user = User::find(1);\r\n\r\n    $user->delete();\r\n\r\n#### Deleting An Existing Model By Key\r\n\r\n    User::destroy(1);\r\n\r\n    User::destroy(array(1, 2, 3));\r\n\r\n    User::destroy(1, 2, 3);\r\n\r\nOf course, you may also run a delete query on a set of models:\r\n\r\n    $affectedRows = User::where('votes', '>', 100)->delete();\r\n\r\n#### Updating Only The Model's Timestamps\r\n\r\nIf you wish to simply update the timestamps on a model, you may use the `touch` method:\r\n\r\n    $user->touch();\r\n\r\n<a name=\"soft-deleting\"></a>\r\n## Soft Deleting\r\n\r\nWhen soft deleting a model, it is not actually removed from your database. Instead, a `deleted_at` timestamp is set on the record. To enable soft deletes for a model, specify the `softDelete` property on the model:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $softDelete = true;\r\n\r\n    }\r\n\r\nTo add a `deleted_at` column to your table, you may use the `softDeletes` method from a migration:\r\n\r\n    $table->softDeletes();\r\n\r\nNow, when you call the `delete` method on the model, the `deleted_at` column will be set to the current timestamp. When querying a model that uses soft deletes, the \"deleted\" models will not be included in query results.\r\n\r\n#### Forcing Soft Deleted Models Into Results\r\n\r\nTo force soft deleted models to appear in a result set, use the `withTrashed` method on the query:\r\n\r\n    $users = User::withTrashed()->where('account_id', 1)->get();\r\n\r\nThe `withTrashed` method may be used on a defined relationship:\r\n\r\n    $user->posts()->withTrashed()->get();\r\n\r\nIf you wish to **only** receive soft deleted models in your results, you may use the `onlyTrashed` method:\r\n\r\n    $users = User::onlyTrashed()->where('account_id', 1)->get();\r\n\r\nTo restore a soft deleted model into an active state, use the `restore` method:\r\n\r\n    $user->restore();\r\n\r\nYou may also use the `restore` method on a query:\r\n\r\n    User::withTrashed()->where('account_id', 1)->restore();\r\n\r\nLike with `withTrashed`, the `restore` method may also be used on relationships:\r\n\r\n    $user->posts()->restore();\r\n\r\nIf you wish to truly remove a model from the database, you may use the `forceDelete` method:\r\n\r\n    $user->forceDelete();\r\n\r\nThe `forceDelete` method also works on relationships:\r\n\r\n    $user->posts()->forceDelete();\r\n\r\nTo determine if a given model instance has been soft deleted, you may use the `trashed` method:\r\n\r\n    if ($user->trashed())\r\n    {\r\n        //\r\n    }\r\n\r\n<a name=\"timestamps\"></a>\r\n## Timestamps\r\n\r\nBy default, ORM will maintain the `created_at` and `updated_at` columns on your database table automatically. Simply add these `timestamp` columns to your table and ORM will take care of the rest. If you do not wish for ORM to maintain these columns, add the following property to your model:\r\n\r\n#### Disabling Auto Timestamps\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $table = 'users';\r\n\r\n        public $timestamps = false;\r\n\r\n    }\r\n\r\n#### Providing A Custom Timestamp Format\r\n\r\nIf you wish to customize the format of your timestamps, you may override the `getDateFormat` method in your model:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected function getDateFormat()\r\n        {\r\n            return 'U';\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"query-scopes\"></a>\r\n## Query Scopes\r\n\r\n#### Defining A Query Scope\r\n\r\nScopes allow you to easily re-use query logic in your models. To define a scope, simply prefix a model method with `scope`:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function scopePopular($query)\r\n        {\r\n            return $query->where('votes', '>', 100);\r\n        }\r\n\r\n        public function scopeWomen($query)\r\n        {\r\n            return $query->whereGender('W');\r\n        }\r\n\r\n    }\r\n\r\n#### Utilizing A Query Scope\r\n\r\n    $users = User::popular()->women()->orderBy('created_at')->get();\r\n\r\n#### Dynamic Scopes\r\n\r\nSometimes You may wish to define a scope that accepts parameters. Just add your parameters to your scope function:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function scopeOfType($query, $type)\r\n        {\r\n            return $query->whereType($type);\r\n        }\r\n\r\n    }\r\n\r\nThen pass the parameter into the scope call:\r\n\r\n    $users = User::ofType('member')->get();\r\n\r\n<a name=\"relationships\"></a>\r\n## Relationships\r\n\r\nOf course, your database tables are probably related to one another. For example, a blog post may have many comments, or an order could be related to the user who placed it. ORM makes managing and working with these relationships easy. Nova Framework supports many types of relationships:\r\n\r\n- [One To One](#one-to-one)\r\n- [One To Many](#one-to-many)\r\n- [Many To Many](#many-to-many)\r\n- [Has Many Through](#has-many-through)\r\n- [Polymorphic Relations](#polymorphic-relations)\r\n- [Many To Many Polymorphic Relations](#many-to-many-polymorphic-relations)\r\n\r\n<a name=\"one-to-one\"></a>\r\n### One To One\r\n\r\n#### Defining A One To One Relation\r\n\r\nA one-to-one relationship is a very basic relation. For example, a `User` model might have one `Phone`. We can define this relation in ORM:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function phone()\r\n        {\r\n            return $this->hasOne('Phone');\r\n        }\r\n\r\n    }\r\n\r\nThe first argument passed to the `hasOne` method is the name of the related model. Once the relationship is defined, we may retrieve it using ORM's [dynamic properties](#dynamic-properties):\r\n\r\n    $phone = User::find(1)->phone;\r\n\r\nThe SQL performed by this statement will be as follows:\r\n\r\n    select * from users where id = 1\r\n\r\n    select * from phones where user_id = 1\r\n\r\nTake note that ORM assumes the foreign key of the relationship based on the model name. In this case, `Phone` model is assumed to use a `user_id` foreign key. If you wish to override this convention, you may pass a second argument to the `hasOne` method. Furthermore, you may pass a third argument to the method to specify which local column that should be used for the association:\r\n\r\n    return $this->hasOne('Phone', 'foreign_key');\r\n\r\n    return $this->hasOne('Phone', 'foreign_key', 'local_key');\r\n\r\n#### Defining The Inverse Of A Relation\r\n\r\nTo define the inverse of the relationship on the `Phone` model, we use the `belongsTo` method:\r\n\r\n    class Phone extends \\Database\\ORM\\Model {\r\n\r\n        public function user()\r\n        {\r\n            return $this->belongsTo('User');\r\n        }\r\n\r\n    }\r\n\r\nIn the example above, ORM will look for a `user_id` column on the `phones` table. If you would like to define a different foreign key column, you may pass it as the second argument to the `belongsTo` method:\r\n\r\n    class Phone extends \\Database\\ORM\\Model {\r\n\r\n        public function user()\r\n        {\r\n            return $this->belongsTo('User', 'local_key');\r\n        }\r\n\r\n    }\r\n\r\nAdditionally, you pass a third parameter which specifies the name of the associated column on the parent table:\r\n\r\n    class Phone extends \\Database\\ORM\\Model {\r\n\r\n        public function user()\r\n        {\r\n            return $this->belongsTo('User', 'local_key', 'parent_key');\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"one-to-many\"></a>\r\n### One To Many\r\n\r\nAn example of a one-to-many relation is a blog post that \"has many\" comments. We can model this relation like so:\r\n\r\n    class Post extends \\Database\\ORM\\Model {\r\n\r\n        public function comments()\r\n        {\r\n            return $this->hasMany('Comment');\r\n        }\r\n\r\n    }\r\n\r\nNow we can access the post's comments through the [dynamic property](#dynamic-properties):\r\n\r\n    $comments = Post::find(1)->comments;\r\n\r\nIf you need to add further constraints to which comments are retrieved, you may call the `comments` method and continue chaining conditions:\r\n\r\n    $comments = Post::find(1)->comments()->where('title', '=', 'foo')->first();\r\n\r\nAgain, you may override the conventional foreign key by passing a second argument to the `hasMany` method. And, like the `hasOne` relation, the local column may also be specified:\r\n\r\n    return $this->hasMany('Comment', 'foreign_key');\r\n\r\n    return $this->hasMany('Comment', 'foreign_key', 'local_key');\r\n\r\n#### Defining The Inverse Of A Relation\r\n\r\nTo define the inverse of the relationship on the `Comment` model, we use the `belongsTo` method:\r\n\r\n    class Comment extends \\Database\\ORM\\Model {\r\n\r\n        public function post()\r\n        {\r\n            return $this->belongsTo('Post');\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"many-to-many\"></a>\r\n### Many To Many\r\n\r\nMany-to-many relations are a more complicated relationship type. An example of such a relationship is a user with many roles, where the roles are also shared by other users. For example, many users may have the role of \"Admin\". Three database tables are needed for this relationship: `users`, `roles`, and `role_user`. The `role_user` table is derived from the alphabetical order of the related model names, and should have `user_id` and `role_id` columns.\r\n\r\nWe can define a many-to-many relation using the `belongsToMany` method:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function roles()\r\n        {\r\n            return $this->belongsToMany('Role');\r\n        }\r\n\r\n    }\r\n\r\nNow, we can retrieve the roles through the `User` model:\r\n\r\n    $roles = User::find(1)->roles;\r\n\r\nIf you would like to use an unconventional table name for your pivot table, you may pass it as the second argument to the `belongsToMany` method:\r\n\r\n    return $this->belongsToMany('Role', 'user_roles');\r\n\r\nYou may also override the conventional associated keys:\r\n\r\n    return $this->belongsToMany('Role', 'user_roles', 'user_id', 'foo_id');\r\n\r\nOf course, you may also define the inverse of the relationship on the `Role` model:\r\n\r\n    class Role extends \\Database\\ORM\\Model {\r\n\r\n        public function users()\r\n        {\r\n            return $this->belongsToMany('User');\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"has-many-through\"></a>\r\n### Has Many Through\r\n\r\nThe \"has many through\" relation provides a convenient short-cut for accessing distant relations via an intermediate relation. For example, a `Country` model might have many `Posts` through a `Users` model. The tables for this relationship would look like this:\r\n\r\n    countries\r\n        id - integer\r\n        name - string\r\n\r\n    users\r\n        id - integer\r\n        country_id - integer\r\n        name - string\r\n\r\n    posts\r\n        id - integer\r\n        user_id - integer\r\n        title - string\r\n\r\nEven though the `posts` table does not contain a `country_id` column, the `hasManyThrough` relation will allow us to access a country's posts via `$country->posts`. Let's define the relationship:\r\n\r\n    class Country extends \\Database\\ORM\\Model {\r\n\r\n        public function posts()\r\n        {\r\n            return $this->hasManyThrough('Post', 'User');\r\n        }\r\n\r\n    }\r\n\r\nIf you would like to manually specify the keys of the relationship, you may pass them as the third and fourth arguments to the method:\r\n\r\n    class Country extends \\Database\\ORM\\Model {\r\n\r\n        public function posts()\r\n        {\r\n            return $this->hasManyThrough('Post', 'User', 'country_id', 'user_id');\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"polymorphic-relations\"></a>\r\n### Polymorphic Relations\r\n\r\nPolymorphic relations allow a model to belong to more than one other model, on a single association. For example, you might have a photo model that belongs to either a staff model or an order model. We would define this relation like so:\r\n\r\n    class Photo extends \\Database\\ORM\\Model {\r\n\r\n        public function imageable()\r\n        {\r\n            return $this->morphTo();\r\n        }\r\n\r\n    }\r\n\r\n    class Staff extends \\Database\\ORM\\Model {\r\n\r\n        public function photos()\r\n        {\r\n            return $this->morphMany('Photo', 'imageable');\r\n        }\r\n\r\n    }\r\n\r\n    class Order extends \\Database\\ORM\\Model {\r\n\r\n        public function photos()\r\n        {\r\n            return $this->morphMany('Photo', 'imageable');\r\n        }\r\n\r\n    }\r\n\r\n#### Retrieving A Polymorphic Relation\r\n\r\nNow, we can retrieve the photos for either a staff member or an order:\r\n\r\n    $staff = Staff::find(1);\r\n\r\n    foreach ($staff->photos as $photo)\r\n    {\r\n        //\r\n    }\r\n\r\n#### Retrieving The Owner Of A Polymorphic Relation\r\n\r\nHowever, the true \"polymorphic\" magic is when you access the staff or order from the `Photo` model:\r\n\r\n    $photo = Photo::find(1);\r\n\r\n    $imageable = $photo->imageable;\r\n\r\nThe `imageable` relation on the `Photo` model will return either a `Staff` or `Order` instance, depending on which type of model owns the photo.\r\n\r\n#### Polymorphic Relation Table Structure\r\n\r\nTo help understand how this works, let's explore the database structure for a polymorphic relation:\r\n\r\n    staff\r\n        id - integer\r\n        name - string\r\n\r\n    orders\r\n        id - integer\r\n        price - integer\r\n\r\n    photos\r\n        id - integer\r\n        path - string\r\n        imageable_id - integer\r\n        imageable_type - string\r\n\r\nThe key fields to notice here are the `imageable_id` and `imageable_type` on the `photos` table. The ID will contain the ID value of, in this example, the owning staff or order, while the type will contain the class name of the owning model. This is what allows the ORM to determine which type of owning model to return when accessing the `imageable` relation.\r\n\r\n<a name=\"many-to-many-polymorphic-relations\"></a>\r\n### Many To Many Polymorphic Relations\r\n\r\n#### Polymorphic Many To Many Relation Table Structure\r\n\r\nIn addition to traditional polymorphic relations, you may also specify many-to-many polymorphic relations. For example, a blog `Post` and `Video` model could share a polymorphic relation to a `Tag` model. First, let's examine the table structure:\r\n\r\n    posts\r\n        id - integer\r\n        name - string\r\n\r\n    videos\r\n        id - integer\r\n        name - string\r\n\r\n    tags\r\n        id - integer\r\n        name - string\r\n\r\n    taggables\r\n        tag_id - integer\r\n        taggable_id - integer\r\n        taggable_type - string\r\n\r\nNext, we're ready to setup the relationships on the model. The `Post` and `Video` model will both have a `morphToMany` relationship via a `tags` method:\r\n\r\n    class Post extends \\Database\\ORM\\Model {\r\n\r\n        public function tags()\r\n        {\r\n            return $this->morphToMany('Tag', 'taggable');\r\n        }\r\n\r\n    }\r\n\r\nThe `Tag` model may define a method for each of its relationships:\r\n\r\n    class Tag extends \\Database\\ORM\\Model {\r\n\r\n        public function posts()\r\n        {\r\n            return $this->morphedByMany('Post', 'taggable');\r\n        }\r\n\r\n        public function videos()\r\n        {\r\n            return $this->morphedByMany('Video', 'taggable');\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"querying-relations\"></a>\r\n## Querying Relations\r\n\r\n#### Querying Relations When Selecting\r\n\r\nWhen accessing the records for a model, you may wish to limit your results based on the existence of a relationship. For example, you wish to pull all blog posts that have at least one comment. To do so, you may use the `has` method:\r\n\r\n    $posts = Post::has('comments')->get();\r\n\r\nYou may also specify an operator and a count:\r\n\r\n    $posts = Post::has('comments', '>=', 3)->get();\r\n\r\nIf you need even more power, you may use the `whereHas` and `orWhereHas` methods to put \"where\" conditions on your `has` queries:\r\n\r\n    $posts = Post::whereHas('comments', function($q)\r\n    {\r\n        $q->where('content', 'like', 'foo%');\r\n\r\n    })->get();\r\n\r\n<a name=\"dynamic-properties\"></a>\r\n### Dynamic Properties\r\n\r\nORM allows you to access your relations via dynamic properties. ORM will automatically load the relationship for you, and is even smart enough to know whether to call the `get` (for one-to-many relationships) or `first` (for one-to-one relationships) method.  It will then be accessible via a dynamic property by the same name as the relation. For example, with the following model `$phone`:\r\n\r\n    class Phone extends \\Database\\ORM\\Model {\r\n\r\n        public function user()\r\n        {\r\n            return $this->belongsTo('User');\r\n        }\r\n\r\n    }\r\n\r\n    $phone = Phone::find(1);\r\n\r\nInstead of echoing the user's email like this:\r\n\r\n    echo $phone->user()->first()->email;\r\n\r\nIt may be shortened to simply:\r\n\r\n    echo $phone->user->email;\r\n\r\n> **Note:** Relationships that return many results will return an instance of the `Database\\ORM\\Collection` class.\r\n\r\n<a name=\"eager-loading\"></a>\r\n## Eager Loading\r\n\r\nEager loading exists to alleviate the N + 1 query problem. For example, consider a `Book` model that is related to `Author`. The relationship is defined like so:\r\n\r\n    class Book extends \\Database\\ORM\\Model {\r\n\r\n        public function author()\r\n        {\r\n            return $this->belongsTo('Author');\r\n        }\r\n\r\n    }\r\n\r\nNow, consider the following code:\r\n\r\n    foreach (Book::all() as $book)\r\n    {\r\n        echo $book->author->name;\r\n    }\r\n\r\nThis loop will execute 1 query to retrieve all of the books on the table, then another query for each book to retrieve the author. So, if we have 25 books, this loop would run 26 queries.\r\n\r\nThankfully, we can use eager loading to drastically reduce the number of queries. The relationships that should be eager loaded may be specified via the `with` method:\r\n\r\n    foreach (Book::with('author')->get() as $book)\r\n    {\r\n        echo $book->author->name;\r\n    }\r\n\r\nIn the loop above, only two queries will be executed:\r\n\r\n    select * from books\r\n\r\n    select * from authors where id in (1, 2, 3, 4, 5, ...)\r\n\r\nWise use of eager loading can drastically increase the performance of your application.\r\n\r\nOf course, you may eager load multiple relationships at one time:\r\n\r\n    $books = Book::with('author', 'publisher')->get();\r\n\r\nYou may even eager load nested relationships:\r\n\r\n    $books = Book::with('author.contacts')->get();\r\n\r\nIn the example above, the `author` relationship will be eager loaded, and the author's `contacts` relation will also be loaded.\r\n\r\n### Eager Load Constraints\r\n\r\nSometimes you may wish to eager load a relationship, but also specify a condition for the eager load. Here's an example:\r\n\r\n    $users = User::with(array('posts' => function($query)\r\n    {\r\n        $query->where('title', 'like', '%first%');\r\n\r\n    }))->get();\r\n\r\nIn this example, we're eager loading the user's posts, but only if the post's title column contains the word \"first\".\r\n\r\nOf course, eager loading Closures aren't limited to \"constraints\". You may also apply orders:\r\n\r\n    $users = User::with(array('posts' => function($query)\r\n    {\r\n        $query->orderBy('created_at', 'desc');\r\n\r\n    }))->get();\r\n\r\n### Lazy Eager Loading\r\n\r\nIt is also possible to eagerly load related models directly from an already existing model collection. This may be useful when dynamically deciding whether to load related models or not, or in combination with caching.\r\n\r\n    $books = Book::all();\r\n\r\n    $books->load('author', 'publisher');\r\n\r\n<a name=\"inserting-related-models\"></a>\r\n## Inserting Related Models\r\n\r\n#### Attaching A Related Model\r\n\r\nYou will often need to insert new related models. For example, you may wish to insert a new comment for a post. Instead of manually setting the `post_id` foreign key on the model, you may insert the new comment from its parent `Post` model directly:\r\n\r\n    $comment = new Comment(array('message' => 'A new comment.'));\r\n\r\n    $post = Post::find(1);\r\n\r\n    $comment = $post->comments()->save($comment);\r\n\r\nIn this example, the `post_id` field will automatically be set on the inserted comment.\r\n\r\n### Associating Models (Belongs To)\r\n\r\nWhen updating a `belongsTo` relationship, you may use the `associate` method. This method will set the foreign key on the child model:\r\n\r\n    $account = Account::find(10);\r\n\r\n    $user->account()->associate($account);\r\n\r\n    $user->save();\r\n\r\n### Inserting Related Models (Many To Many)\r\n\r\nYou may also insert related models when working with many-to-many relations. Let's continue using our `User` and `Role` models as examples. We can easily attach new roles to a user using the `attach` method:\r\n\r\n#### Attaching Many To Many Models\r\n\r\n    $user = User::find(1);\r\n\r\n    $user->roles()->attach(1);\r\n\r\nYou may also pass an array of attributes that should be stored on the pivot table for the relation:\r\n\r\n    $user->roles()->attach(1, array('expires' => $expires));\r\n\r\nOf course, the opposite of `attach` is `detach`:\r\n\r\n    $user->roles()->detach(1);\r\n\r\n#### Using Sync To Attach Many To Many Models\r\n\r\nYou may also use the `sync` method to attach related models. The `sync` method accepts an array of IDs to place on the pivot table. After this operation is complete, only the IDs in the array will be on the intermediate table for the model:\r\n\r\n    $user->roles()->sync(array(1, 2, 3));\r\n\r\n#### Adding Pivot Data When Syncing\r\n\r\nYou may also associate other pivot table values with the given IDs:\r\n\r\n    $user->roles()->sync(array(1 => array('expires' => true)));\r\n\r\nSometimes you may wish to create a new related model and attach it in a single command. For this operation, you may use the `save` method:\r\n\r\n    $role = new Role(array('name' => 'Editor'));\r\n\r\n    User::find(1)->roles()->save($role);\r\n\r\nIn this example, the new `Role` model will be saved and attached to the user model. You may also pass an array of attributes to place on the joining table for this operation:\r\n\r\n    User::find(1)->roles()->save($role, array('expires' => $expires));\r\n\r\n<a name=\"touching-parent-timestamps\"></a>\r\n## Touching Parent Timestamps\r\n\r\nWhen a model `belongsTo` another model, such as a `Comment` which belongs to a `Post`, it is often helpful to update the parent's timestamp when the child model is updated. For example, when a `Comment` model is updated, you may want to automatically touch the `updated_at` timestamp of the owning `Post`. ORM makes it easy. Just add a `touches` property containing the names of the relationships to the child model:\r\n\r\n    class Comment extends \\Database\\ORM\\Model {\r\n\r\n        protected $touches = array('post');\r\n\r\n        public function post()\r\n        {\r\n            return $this->belongsTo('Post');\r\n        }\r\n\r\n    }\r\n\r\nNow, when you update a `Comment`, the owning `Post` will have its `updated_at` column updated:\r\n\r\n    $comment = Comment::find(1);\r\n\r\n    $comment->text = 'Edit to this comment!';\r\n\r\n    $comment->save();\r\n\r\n<a name=\"working-with-pivot-tables\"></a>\r\n## Working With Pivot Tables\r\n\r\nAs you have already learned, working with many-to-many relations requires the presence of an intermediate table. ORM provides some very helpful ways of interacting with this table. For example, let's assume our `User` object has many `Role` objects that it is related to. After accessing this relationship, we may access the `pivot` table on the models:\r\n\r\n    $user = User::find(1);\r\n\r\n    foreach ($user->roles as $role)\r\n    {\r\n        echo $role->pivot->created_at;\r\n    }\r\n\r\nNotice that each `Role` model we retrieve is automatically assigned a `pivot` attribute. This attribute contains a model representing the intermediate table, and may be used as any other ORM model.\r\n\r\nBy default, only the keys will be present on the `pivot` object. If your pivot table contains extra attributes, you must specify them when defining the relationship:\r\n\r\n    return $this->belongsToMany('Role')->withPivot('foo', 'bar');\r\n\r\nNow the `foo` and `bar` attributes will be accessible on our `pivot` object for the `Role` model.\r\n\r\nIf you want your pivot table to have automatically maintained `created_at` and `updated_at` timestamps, use the `withTimestamps` method on the relationship definition:\r\n\r\n    return $this->belongsToMany('Role')->withTimestamps();\r\n\r\n#### Deleting Records On A Pivot Table\r\n\r\nTo delete all records on the pivot table for a model, you may use the `detach` method:\r\n\r\n    User::find(1)->roles()->detach();\r\n\r\nNote that this operation does not delete records from the `roles` table, but only from the pivot table.\r\n\r\n#### Defining A Custom Pivot Model\r\n\r\nNova Framework also allows you to define a custom Pivot model. To define a custom model, first create your own \"Base\" model class that extends `ORM`. In your other ORM models, extend this custom base model instead of the default `ORM` base. In your base model, add the following function that returns an instance of your custom Pivot model:\r\n\r\n    public function newPivot(Model $parent, array $attributes, $table, $exists)\r\n    {\r\n        return new YourCustomPivot($parent, $attributes, $table, $exists);\r\n    }\r\n\r\n<a name=\"collections\"></a>\r\n## Collections\r\n\r\nAll multi-result sets returned by ORM, either via the `get` method or a `relationship`, will return a collection object. This object implements the `IteratorAggregate` PHP interface so it can be iterated over like an array. However, this object also has a variety of other helpful methods for working with result sets.\r\n\r\n#### Checking If A Collection Contains A Key\r\n\r\nFor example, we may determine if a result set contains a given primary key using the `contains` method:\r\n\r\n    $roles = User::find(1)->roles;\r\n\r\n    if ($roles->contains(2))\r\n    {\r\n        //\r\n    }\r\n\r\nCollections may also be converted to an array or JSON:\r\n\r\n    $roles = User::find(1)->roles->toArray();\r\n\r\n    $roles = User::find(1)->roles->toJson();\r\n\r\nIf a collection is cast to a string, it will be returned as JSON:\r\n\r\n    $roles = (string) User::find(1)->roles;\r\n\r\n#### Iterating Collections\r\n\r\nORM collections also contain a few helpful methods for looping and filtering the items they contain:\r\n\r\n    $roles = $user->roles->each(function($role)\r\n    {\r\n        //\r\n    });\r\n\r\n#### Filtering Collections\r\n\r\nWhen filtering collections, the callback provided will be used as callback for [array_filter](http://php.net/manual/en/function.array-filter.php).\r\n\r\n    $users = $users->filter(function($user)\r\n    {\r\n        return $user->isAdmin();\r\n    });\r\n\r\n> **Note:** When filtering a collection and converting it to JSON, try calling the `values` function first to reset the array's keys.\r\n\r\n#### Applying A Callback To Each Collection Object\r\n\r\n    $roles = User::find(1)->roles;\r\n\r\n    $roles->each(function($role)\r\n    {\r\n        //\r\n    });\r\n\r\n#### Sorting A Collection By A Value\r\n\r\n    $roles = $roles->sortBy(function($role)\r\n    {\r\n        return $role->created_at;\r\n    });\r\n\r\n#### Sorting A Collection By A Value\r\n\r\n    $roles = $roles->sortBy('created_at');\r\n\r\n#### Returning A Custom Collection Type\r\n\r\nSometimes, you may wish to return a custom Collection object with your own added methods. You may specify this on your ORM model by overriding the `newCollection` method:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function newCollection(array $models = array())\r\n        {\r\n            return new CustomCollection($models);\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"accessors-and-mutators\"></a>\r\n## Accessors & Mutators\r\n\r\n#### Defining An Accessor\r\n\r\nORM provides a convenient way to transform your model attributes when getting or setting them. Simply define a `getFooAttribute` method on your model to declare an accessor. Keep in mind that the methods should follow camel-casing, even though your database columns are snake-case:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function getFirstNameAttribute($value)\r\n        {\r\n            return ucfirst($value);\r\n        }\r\n\r\n    }\r\n\r\nIn the example above, the `first_name` column has an accessor. Note that the value of the attribute is passed to the accessor.\r\n\r\n#### Defining A Mutator\r\n\r\nMutators are declared in a similar fashion:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        public function setFirstNameAttribute($value)\r\n        {\r\n            $this->attributes['first_name'] = strtolower($value);\r\n        }\r\n\r\n    }\r\n\r\n<a name=\"date-mutators\"></a>\r\n## Date Mutators\r\n\r\nBy default, ORM will convert the `created_at`, `updated_at`, and `deleted_at` columns to instances of [Carbon](https://github.com/briannesbitt/Carbon), which provides an assortment of helpful methods, and extends the native PHP `DateTime` class.\r\n\r\nYou may customize which fields are automatically mutated, and even completely disable this mutation, by overriding the `getDates` method of the model:\r\n\r\n    public function getDates()\r\n    {\r\n        return array('created_at');\r\n    }\r\n\r\nWhen a column is considered a date, you may set its value to a UNIX timestamp, date string (`Y-m-d`), date-time string, and of course a `DateTime` / `Carbon` instance.\r\n\r\nTo totally disable date mutations, simply return an empty array from the `getDates` method:\r\n\r\n    public function getDates()\r\n    {\r\n        return array();\r\n    }\r\n\r\n<a name=\"model-events\"></a>\r\n## Model Events\r\n\r\nEloquent models fire several events, allowing you to hook into various points in the model's lifecycle using the following methods: `creating`, `created`, `updating`, `updated`, `saving`, `saved`, `deleting`, `deleted`, `restoring`, `restored`.\r\n\r\nWhenever a new item is saved for the first time, the `creating` and `created` events will fire. If an item is not new and the `save` method is called, the `updating` / `updated` events will fire. In both cases, the `saving` / `saved` events will fire.\r\n\r\n#### Cancelling Save Operations Via Events\r\n\r\nIf `false` is returned from the `creating`, `updating`, `saving`, or `deleting` events, the action will be cancelled:\r\n\r\n\tUser::creating(function($user)\r\n\t{\r\n\t\tif ( ! $user->isValid()) return false;\r\n\t});\r\n\r\n#### Setting A Model Boot Method\r\n\r\nEloquent models also contain a static `boot` method, which may provide a convenient place to register your event bindings.\r\n\r\n\tclass User extends Eloquent {\r\n\r\n\t\tpublic static function boot()\r\n\t\t{\r\n\t\t\tparent::boot();\r\n\r\n\t\t\t// Setup event bindings...\r\n\t\t}\r\n\r\n\t}\r\n\r\n<a name=\"model-observers\"></a>\r\n## Model Observers\r\n\r\nTo consolidate the handling of model events, you may register a model observer. An observer class may have methods that correspond to the various model events. For example, `creating`, `updating`, `saving` methods may be on an observer, in addition to any other model event name.\r\n\r\nSo, for example, a model observer might look like this:\r\n\r\n\tclass UserObserver {\r\n\r\n\t\tpublic function saving($model)\r\n\t\t{\r\n\t\t\t//\r\n\t\t}\r\n\r\n\t\tpublic function saved($model)\r\n\t\t{\r\n\t\t\t//\r\n\t\t}\r\n\r\n\t}\r\n\r\nYou may register an observer instance using the `observe` method:\r\n\r\n\tUser::observe(new UserObserver);\r\n\r\n<a name=\"converting-to-arrays-or-json\"></a>\r\n## Converting To Arrays / JSON\r\n\r\n#### Converting A Model To An Array\r\n\r\nWhen building JSON APIs, you may often need to convert your models and relationships to arrays or JSON. So, ORM includes methods for doing so. To convert a model and its loaded relationship to an array, you may use the `toArray` method:\r\n\r\n    $user = User::with('roles')->first();\r\n\r\n    return $user->toArray();\r\n\r\nNote that entire collections of models may also be converted to arrays:\r\n\r\n    return User::all()->toArray();\r\n\r\n#### Converting A Model To JSON\r\n\r\nTo convert a model to JSON, you may use the `toJson` method:\r\n\r\n    return User::find(1)->toJson();\r\n\r\n#### Returning A Model From A Route\r\n\r\nNote that when a model or collection is cast to a string, it will be converted to JSON, meaning you can return ORM objects directly from your application's routes!\r\n\r\n    Route::get('users', function()\r\n    {\r\n        return User::all();\r\n    });\r\n\r\n#### Hiding Attributes From Array Or JSON Conversion\r\n\r\nSometimes you may wish to limit the attributes that are included in your model's array or JSON form, such as passwords. To do so, add a `hidden` property definition to your model:\r\n\r\n    class User extends \\Database\\ORM\\Model {\r\n\r\n        protected $hidden = array('password');\r\n\r\n    }\r\n\r\n> **Note:** When hiding relationships, use the relationship's **method** name, not the dynamic accessor name.\r\n\r\nAlternatively, you may use the `visible` property to define a white-list:\r\n\r\n    protected $visible = array('first_name', 'last_name');\r\n\r\n<a name=\"array-appends\"></a>\r\nOccasionally, you may need to add array attributes that do not have a corresponding column in your database. To do so, simply define an accessor for the value:\r\n\r\n    public function getIsAdminAttribute()\r\n    {\r\n        return $this->attributes['admin'] == 'yes';\r\n    }\r\n\r\nOnce you have created the accessor, just add the value to the `appends` property on the model:\r\n\r\n    protected $appends = array('is_admin');\r\n\r\nOnce the attribute has been added to the `appends` list, it will be included in both the model's array and JSON forms.\r\n\r\n\r\n# Mailing API\r\n\r\n- [Configuration](#mailer-configuration)\r\n- [Basic Usage](#mailer-basic-usage)\r\n- [Embedding Inline Attachments](#embedding-inline-attachments)\r\n- [Mail & Local Development](#mailer-and-local-development)\r\n- [Working along with the classic Mailer Helper](#mailer-and-classic-helper)\r\n\r\n<a name=\"mailer-configuration\"></a>\r\n## Configuration\r\n\r\nThe new **Mailing API** provides a clean, simple API over the popular [SwiftMailer](http://swiftmailer.org) library. The mail configuration file is `app/Config/Mail.php`, and contains options allowing you to change your SMTP host, port, and credentials, as well as set a global `from` address for all messages delivered by the library. You may use any SMTP server you wish. If you wish to use the PHP `mail` function to send mail, you may change the `driver` to `mail` in the configuration file. A `sendmail` driver is also available.\r\n\r\n<a name=\"mailer-basic-usage\"></a>\r\n## Basic Usage\r\n\r\nThe `Mailer::send` method may be used to send an e-mail message:\r\n\r\n    Mailer::send('Emails/Welcome', $data, function($message)\r\n    {\r\n        $message->to('foo@example.com', 'John Smith')->subject('Welcome!');\r\n    });\r\n\r\nThe first argument passed to the `send` method is the name of the view that should be used as the e-mail body. The second is the `$data` that should be passed to the view, and the third is a Closure allowing you to specify various options on the e-mail message.\r\n\r\n> **Note:** A `$message` variable is always passed to e-mail views, and allows the inline embedding of attachments. So, it is best to avoid passing a `message` variable in your view payload.\r\n\r\nYou may also specify a plain text view to use in addition to an HTML view:\r\n\r\n    Mailer::send(array('html.view', 'text.view'), $data, $callback);\r\n\r\nOr, you may specify only one type of view using the `html` or `text` keys:\r\n\r\n    Mailer::send(array('text' => 'view'), $data, $callback);\r\n\r\nYou may specify other options on the e-mail message such as any carbon copies or attachments as well:\r\n\r\n    Mailer::send('Emails/Welcome', $data, function($message)\r\n    {\r\n        $message->from('us@example.com', 'Nova Framework');\r\n\r\n        $message->to('foo@example.com')->cc('bar@example.com');\r\n\r\n        $message->attach($pathToFile);\r\n    });\r\n\r\nWhen attaching files to a message, you may also specify a MIME type and / or a display name:\r\n\r\n    $message->attach($pathToFile, array('as' => $display, 'mime' => $mime));\r\n\r\n> **Note:** The message instance passed to a `Mail::send` Closure extends the SwiftMailer message class, allowing you to call any method on that class to build your e-mail messages.\r\n\r\n<a name=\"embedding-inline-attachments\"></a>\r\n## Embedding Inline Attachments\r\n\r\nEmbedding inline images into your e-mails is typically cumbersome; however, Nova Framework provides a convenient way to attach images to your e-mails and retrieving the appropriate CID.\r\n\r\n#### Embedding An Image In An E-Mail View\r\n\r\n    <body>\r\n        Here is an image:\r\n\r\n        <img src=\"<?php echo $message->embed($pathToFile); ?>\">\r\n    </body>\r\n\r\n#### Embedding Raw Data In An E-Mail View\r\n\r\n    <body>\r\n        Here is an image from raw data:\r\n\r\n        <img src=\"<?php echo $message->embedData($data, $name); ?>\">\r\n    </body>\r\n\r\nNote that the `$message` variable is always passed to e-mail views by the `Mail` class.\r\n\r\n<a name=\"mail-and-local-development\"></a>\r\n## Mail & Local Development\r\n\r\nWhen developing an application that sends e-mail, it's usually desirable to disable the sending of messages from your local or development environment. To do so, you may either call the `Mailer::pretend` method, or set the `pretend` option in the `app/Config/Mail.php` configuration file to `true`. When the mailer is in `pretend` mode, messages will be written to your application's log files instead of being sent to the recipient.\r\n\r\n#### Enabling Pretend Mail Mode\r\n\r\n    Mailer::pretend();\r\n\r\n<a name=\"mailer-and-classic-helper\"></a>\r\n## API preservation - Working along with the classic Mailer Helper\r\n\r\nThe Mailing API, being designed for the **New Style APIs**, will **work along** with the classic Mailer Helper, with **no conflict** between, they being absolutely independent. Then there will be **no API break**.\r\n\r\nAlso, it is possible to use the **Mailing API** while using the **Classic Style APIs**."},"comment":{"url":"https://api.github.com/repos/nova-framework/framework/issues/comments/222262680","html_url":"https://github.com/nova-framework/framework/pull/890#issuecomment-222262680","issue_url":"https://api.github.com/repos/nova-framework/framework/issues/890","id":222262680,"user":{"login":"LuckyCyborg","id":13488485,"avatar_url":"https://avatars.githubusercontent.com/u/13488485?v=3","gravatar_id":"","url":"https://api.github.com/users/LuckyCyborg","html_url":"https://github.com/LuckyCyborg","followers_url":"https://api.github.com/users/LuckyCyborg/followers","following_url":"https://api.github.com/users/LuckyCyborg/following{/other_user}","gists_url":"https://api.github.com/users/LuckyCyborg/gists{/gist_id}","starred_url":"https://api.github.com/users/LuckyCyborg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LuckyCyborg/subscriptions","organizations_url":"https://api.github.com/users/LuckyCyborg/orgs","repos_url":"https://api.github.com/users/LuckyCyborg/repos","events_url":"https://api.github.com/users/LuckyCyborg/events{/privacy}","received_events_url":"https://api.github.com/users/LuckyCyborg/received_events","type":"User","site_admin":false},"created_at":"2016-05-27T22:00:24Z","updated_at":"2016-05-27T22:00:24Z","body":"Of course it worked. :smirk: "}}
{"actor":{"display_login":"LuckyCyborg"}}