Database Testing

Introduction
Laravel provides a variety of helpful tools to make it easier to test your database driven applications. First, you may use the assertDatabaseHas helper to assert that data exists in the database matching a given set of criteria. For example, if you would like to verify that there is a record in the users table with the email value of sally@example.com, you can do the following:

public function testDatabase()
{
    // Make call to application...

    $this->assertDatabaseHas('users', [
        'email' => 'sally@example.com'
    ]);
}

You can also use the assertDatabaseMissing helper to assert that data does not exist in the database.

Of course, the assertDatabaseHas method and other helpers like it are for convenience. You are free to use any of PHPUnit’s built-in assertion methods to supplement your tests.

Generating Factories
To create a factory, use the make:factory Artisan command:
php artisan make:factory PostFactory
The new factory will be placed in your database/factories directory.
The –model option may be used to indicate the name of the model created by the factory. This option will pre-fill the generated factory file with the given model:
php artisan make:factory PostFactory –model=Post

Resetting The Database After Each Test
It is often useful to reset your database after each test so that data from a previous test does not interfere with subsequent tests. The RefreshDatabase trait takes the most optimal approach to migrating your test database depending on if you are using an in-memory database or a traditional database. Use the trait on your test class and everything will be handled for you:

Browser Tests (Laravel Dusk)

Introduction
Laravel Dusk provides an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK or Selenium on your machine. Instead, Dusk uses a standalone ChromeDriver installation. However, you are free to utilize any other Selenium compatible driver you wish.

Seleniumはwebのuiテスト自動化。
Installation
To get started, you should add the laravel/dusk Composer dependency to your project:
composer require –dev laravel/dusk

If you are manually registering Dusk’s service provider, you should never register it in your production environment, as doing so could lead to arbitrary users being able to authenticate with your application.

After installing the Dusk package, run the dusk:install Artisan command:
php artisan dusk:install

A Browser directory will be created within your tests directory and will contain an example test. Next, set the APP_URL environment variable in your .env file. This value should match the URL you use to access your application in a browser.

To run your tests, use the dusk Artisan command. The dusk command accepts any argument that is also accepted by the phpunit command:

php artisan dusk
If you had test failures the last time you ran the dusk command, you may save time by re-running the failing tests first using the dusk:fails command:
php artisan dusk:fails

Using Other Browsers
By default, Dusk uses Google Chrome and a standalone ChromeDriver installation to run your browser tests. However, you may start your own Selenium server and run your tests against any browser you wish.

To get started, open your tests/DuskTestCase.php file, which is the base Dusk test case for your application. Within this file, you can remove the call to the startChromeDriver method. This will stop Dusk from automatically starting the ChromeDriver:

public static function prepare()
{
    // static::startChromeDriver();
}

Next, you may modify the driver method to connect to the URL and port of your choice. In addition, you may modify the “desired capabilities” that should be passed to the WebDriver:

protected function driver()
{
    return RemoteWebDriver::create(
        'http://localhost:4444/wd/hub', DesiredCapabilities::phantomjs()
    );
}

php artisan dusk
If you had test failures the last time you ran the dusk command, you may save time by re-running the failing tests first using the dusk:fails command:

php artisan dusk:fails
The dusk command accepts any argument that is normally accepted by the PHPUnit test runner, allowing you to only run the tests for a given group, etc:

php artisan dusk –group=foo

protected function driver()
{
    return RemoteWebDriver::create(
        'http://localhost:9515', DesiredCapabilities::chrome()
    );
}

Environment Handling
To force Dusk to use its own environment file when running tests, create a .env.dusk.{environment} file in the root of your project. For example, if you will be initiating the dusk command from your local environment, you should create a .env.dusk.local file.

When running tests, Dusk will back-up your .env file and rename your Dusk environment to .env. Once the tests have completed, your .env file will be restored.

$this->browse(function ($first, $second) {
    $first->loginAs(User::find(1))
          ->visit('/home')
          ->waitForText('Message');

    $second->loginAs(User::find(2))
           ->visit('/home')
           ->waitForText('Message')
           ->type('message', 'Hey Taylor')
           ->press('Send');

    $first->waitForText('Hey Taylor')
          ->assertSee('Jeffrey Way');
});

Resizing Browser Windows
You may use the resize method to adjust the size of the browser window:

$browser->resize(1920, 1080);
The maximize method may be used to maximize the browser window:

$browser->maximize();

Authentication
Often, you will be testing pages that require authentication. You can use Dusk’s loginAs method in order to avoid interacting with the login screen during every test. The loginAs method accepts a user ID or user model instance:

$this->browse(function ($first, $second) {
    $first->loginAs(User::find(1))
          ->visit('/home');
});

Database Migrations
When your test requires migrations, like the authentication example above, you should never use the RefreshDatabase trait. The RefreshDatabase trait leverages database transactions which will not be applicable across HTTP requests. Instead, use the DatabaseMigrations trait:

namespace Tests\Browser;

use App\User;
use Tests\DuskTestCase;
use Laravel\Dusk\Chrome;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
}

Text, Values, & Attributes
Retrieving & Setting Values
Dusk provides several methods for interacting with the current display text, value, and attributes of elements on the page. For example, to get the “value” of an element that matches a given selector, use the value method:

Retrieving Text
The text method may be used to retrieve the display text of an element that matches the given selector:
$text = $browser->text(‘selector’);

Retrieving Attributes
Finally, the attribute method may be used to retrieve an attribute of an element matching the given selector:
$attribute = $browser->attribute(‘selector’, ‘value’);

Using Forms
Typing Values
Dusk provides a variety of methods for interacting with forms and input elements. First, let’s take a look at an example of typing text into an input field:

$browser->type(’email’, ‘taylor@laravel.com’);
Note that, although the method accepts one if necessary, we are not required to pass a CSS selector into the type method. If a CSS selector is not provided, Dusk will search for an input field with the given name attribute. Finally, Dusk will attempt to find a textarea with the given name attribute.

To append text to a field without clearing its content, you may use the append method:
$browser->type(‘tags’, ‘foo’)
->append(‘tags’, ‘, bar, baz’);
You may clear the value of an input using the clear method:
$browser->clear(’email’);

Laravel Console Tests

Laravelのドキュメント見てて思ったが、framework以外でもソースコード使用する場合、githubのdocumentやreadme.mdなどは見ておいた方が良さそうだ。

Expecting Input / Output
Laravel allows you to easily “mock” user input for your console commands using the expectsQuestion method. In addition, you may specify the exit code and text that you expect to be output by the console command using the assertExitCode and expectsOutput methods. For example, consider the following console command:

Artisan::command('question', function () {
    $name = $this->ask('What is your name?');

    $language = $this->choice('Which language do you program in?', [
        'PHP',
        'Ruby',
        'Python',
    ]);

    $this->line('Your name is '.$name.' and you program in '.$language.'.');
});
public function test_console_command()
{
    $this->artisan('question')
         ->expectsQuestion('What is your name?', 'Taylor Otwell')
         ->expectsQuestion('Which language do you program in?', 'PHP')
         ->expectsOutput('Your name is Taylor Otwell and you program in PHP.')
         ->assertExitCode(0);
}

Laravel HTTP Tests

Laravel provides a very fluent API for making HTTP requests to your application and examining the output. For example, take a look at the test defined below:

namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');
        $response->assertStatus(200);
    }
}

The get method makes a GET request into the application, while the assertStatus method asserts that the returned response should have the given HTTP status code. In addition to this simple assertion, Laravel also contains a variety of assertions for inspecting the response headers, content, JSON structure, and more.

You may use the withHeaders method to customize the request’s headers before it is sent to the application. This allows you to add any custom headers you would like to the request:

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->json('POST', '/user', ['name' => 'Sally']);
        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}

Session / Authentication
Laravel provides several helpers for working with the session during HTTP testing. First, you may set the session data to a given array using the withSession method. This is useful for loading the session with data before issuing a request to your application:

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $response = $this->withSession(['foo' => 'bar'])
                         ->get('/');
    }
}

Of course, one common use of the session is for maintaining state for the authenticated user. The actingAs helper method provides a simple way to authenticate a given user as the current user. For example, we may use a model factory to generate and authenticate a user:

use App\User;

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $user = factory(User::class)->create();

        $response = $this->actingAs($user)
                         ->withSession(['foo' => 'bar'])
                         ->get('/');
    }
}

Laravel also provides several helpers for testing JSON APIs and their responses. For example, the json, get, post, put, patch, and delete methods may be used to issue requests with various HTTP verbs. You may also easily pass data and headers to these methods. To get started, let’s write a test to make a POST request to /user and assert that the expected data was returned:

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}

The assertJson method converts the response to an array and utilizes PHPUnit::assertArraySubset to verify that the given array exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.

Verifying An Exact JSON Match
If you would like to verify that the given array is an exact match for the JSON returned by the application, you should use the assertExactJson method:

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertExactJson([
                'created' => true,
            ]);
    }

Testing File Uploads
The Illuminate\Http\UploadedFile class provides a fake method which may be used to generate dummy files or images for testing. This, combined with the Storage facade’s fake method greatly simplifies the testing of file uploads. For example, you may combine these two features to easily test an avatar upload form:

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    public function testAvatarUpload()
    {
        Storage::fake('avatars');

        $file = UploadedFile::fake()->image('avatar.jpg');

        $response = $this->json('POST', '/avatar', [
            'avatar' => $file,
        ]);

        // Assert the file was stored...
        Storage::disk('avatars')->assertExists($file->hashName());

        // Assert a file does not exist...
        Storage::disk('avatars')->assertMissing('missing.jpg');
    }
}

Fake File Customization
When creating files using the fake method, you may specify the width, height, and size of the image in order to better test your validation rules:

UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

Response Assertions
Laravel provides a variety of custom assertion methods for your PHPUnit tests. These assertions may be accessed on the response that is returned from the json, get, post, put, and delete test methods:
assertCookieassertCookieExpiredassertCookieNotExpiredassertCookieMissingassertDontSeeassertDontSeeTextassertExactJsonassertForbiddenassertHeaderassertHeaderMissingassertJsonassertJsonCountassertJsonFragmentassertJsonMissingassertJsonMissingExactassertJsonStructureassertJsonValidationErrorsassertLocationassertNotFoundassertOkassertPlainCookieassertRedirectassertSeeassertSeeInOrderassertSeeTextassertSeeTextInOrderassertSessionHasassertSessionHasAllassertSessionHasErrorsassertSessionHasErrorsInassertSessionHasNoErrorsassertSessionMissingassertStatusassertSuccessfulassertViewHasassertViewHasAllassertViewIs

Authentication Assertions
Laravel also provides a variety of authentication related assertions for your PHPUnit tests:

Method Description
$this->assertAuthenticated($guard = null); Assert that the user is authenticated.
$this->assertGuest($guard = null); Assert that the user is not authenticated.
$this->assertAuthenticatedAs($user, $guard = null); Assert that the given user is authenticated.
$this->assertCredentials(array $credentials, $guard = null); Assert that the given credentials are valid.
$this->assertInvalidCredentials(array $credentials, $guard = null); Assert that the given credentials are invalid.

Laravel Testing: Getting Started

Laravel is built with testing in mind. In fact, support for testing with PHPUnit is included out of the box and a phpunit.xml file is already set up for your application. The framework also ships with convenient helper methods that allow you to expressively test your applications.

By default, your application’s tests directory contains two directories: Feature and Unit. Unit tests are tests that focus on a very small, isolated portion of your code. In fact, most unit tests probably focus on a single method. Feature tests may test a larger portion of your code, including how several objects interact with each other or even a full HTTP request to a JSON endpoint.

An ExampleTest.php file is provided in both the Feature and Unit test directories. After installing a new Laravel application, run phpunit on the command line to run your tests.

When running tests via phpunit, Laravel will automatically set the configuration environment to testing because of the environment variables defined in the phpunit.xml file. Laravel also automatically configures the session and cache to the array driver while testing, meaning no session or cache data will be persisted while testing.

You are free to define other testing environment configuration values as necessary. The testing environment variables may be configured in the phpunit.xml file, but make sure to clear your configuration cache using the config:clear Artisan command before running your tests!

In addition, you may create a .env.testing file in the root of your project. This file will override the .env file when running PHPUnit tests or executing Artisan commands with the --env=testing option.

To create a new test case, use the make:test Artisan command:

// Create a test in the Feature directory…
php artisan make:test UserTest

// Create a test in the Unit directory…
php artisan make:test UserTest –unit
Once the test has been generated, you may define test methods as you normally would using PHPUnit. To run your tests, execute the phpunit command from your terminal:

namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $this->assertTrue(true);
    }
}

Eloquent: Serialization

Eloquent: Serializationを学んでいきます。
Serializing Models & Collections
Serializing To Arrays

To convert a model and its loaded relationships to an array, you should use the toArray method. This method is recursive, so all attributes and all relations (including the relations of relations) will be converted to arrays:

$user = App\User::with('roles')->first();
return $user->toArray();
$users = App\User::all();
return $users->toArray();
$user = App\User::find(1);
return $user->toJson();
return $user->toJson(JSON_PRETTY_PRINT);

Hiding Attributes From JSON
Sometimes you may wish to limit the attributes, such as passwords, that are included in your model’s array or JSON representation. To do so, add a $hidden property to your model:

namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = ['password'];
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    /**
     * The attributes that should be visible in arrays.
     *
     * @var array
     */
    protected $visible = ['first_name', 'last_name'];
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    /**
     * Get the administrator flag for the user.
     *
     * @return bool
     */
    public function getIsAdminAttribute()
    {
        return $this->attributes['admin'] == 'yes';
    }
}
namespace App\Providers;
use Illuminate\Support\Carbon;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Carbon::serializeUsing(function ($carbon) {
            return $carbon->format('U');
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Laravel Eloquent: API Resources

Introduction
When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application’s users. Laravel’s resource classes allow you to expressively and easily transform your models and model collections into JSON.

Generating Resources
To generate a resource class, you may use the make:resource Artisan command. By default, resources will be placed in the app/Http/Resources directory of your application. Resources extend the Illuminate\Http\Resources\Json\JsonResource class:

php artisan make:resource User

php artisan make:resource Users –collection
php artisan make:resource UserCollection

Concept Overview
Tip!! This is a high-level overview of resources and resource collections. You are highly encouraged to read the other sections of this documentation to gain a deeper understanding of the customization and power offered to you by resources.

Before diving into all of the options available to you when writing resources, let’s first take a high-level look at how resources are used within Laravel. A resource class represents a single model that needs to be transformed into a JSON structure. For example, here is a simple User resource class:

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class User extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

Every resource class defines a toArray method which returns the array of attributes that should be converted to JSON when sending the response. Notice that we can access model properties directly from the $this variable. This is because a resource class will automatically proxy property and method access down to the underlying model for convenient access. Once the resource is defined, it may be returned from a route or controller:

use App\User;
use App\Http\Resources\User as UserResource;

Route::get('/user', function () {
    return new UserResource(User::find(1));
});

Resource Collections
If you are returning a collection of resources or a paginated response, you may use the collection method when creating the resource instance in your route or controller:

use App\User;
use App\Http\Resources\User as UserResource;

Route::get('/user', function () {
    return UserResource::collection(User::all());
});

Of course, this does not allow any addition of meta data that may need to be returned with the collection. If you would like to customize the resource collection response, you may create a dedicated resource to represent the collection:

Once the resource collection class has been generated, you may easily define any meta data that should be included with the response:

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

After defining your resource collection, it may be returned from a route or controller:

use App\User;
use App\Http\Resources\UserCollection;
Route::get('/users', function () {
    return new UserCollection(User::all());
});

Customizing The Underlying Resource Class
Typically, the $this->collection property of a resource collection is automatically populated with the result of mapping each item of the collection to its singular resource class. The singular resource class is assumed to be the collection’s class name without the trailing Collection string.

For example, UserCollection will attempt to map the given user instances into the User resource. To customize this behavior, you may override the $collects property of your resource collection:

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserCollection extends ResourceCollection
{
    /**
     * The resource that this resource collects.
     *
     * @var string
     */
    public $collects = 'App\Http\Resources\Member';
}

Writing Resources
Tip!! If you have not read the concept overview, you are highly encouraged to do so before proceeding with this documentation.
In essence, resources are simple. They only need to transform a given model into an array. So, each resource contains a toArray method which translates your model’s attributes into an API friendly array that can be returned to your users:

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class User extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

use App\User;
use App\Http\Resources\User as UserResource;

Route::get('/user', function () {
    return new UserResource(User::find(1));
});

Relationships
If you would like to include related resources in your response, you may add them to the array returned by your toArray method. In this example, we will use the Post resource’s collection method to add the user’s blog posts to the resource response:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'posts' => PostResource::collection($this->posts),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

Resource Collections
While resources translate a single model into an array, resource collections translate a collection of models into an array. It is not absolutely necessary to define a resource collection class for each one of your model types since all resources provide a collection method to generate an “ad-hoc” resource collection on the fly:

use App\User;
use App\Http\Resources\User as UserResource;

Route::get('/user', function () {
    return UserResource::collection(User::all());
});
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}
{
    "data": [
        {
            "id": 1,
            "name": "Eladio Schroeder Sr.",
            "email": "therese28@example.com",
        },
        {
            "id": 2,
            "name": "Liliana Mayert",
            "email": "evandervort@example.com",
        }
    ]
}

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Http\Resources\Json\Resource;

class AppServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Resource::withoutWrapping();
}

/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}

Conditional Attributes
Sometimes you may wish to only include an attribute in a resource response if a given condition is met. For example, you may wish to only include a value if the current user is an “administrator”. Laravel provides a variety of helper methods to assist you in this situation. The when method may be used to conditionally add an attribute to a resource response:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'secret' => $this->when(Auth::user()->isAdmin(), 'secret-value'),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

Conditional Relationships
In addition to conditionally loading attributes, you may conditionally include relationships on your resource responses based on if the relationship has already been loaded on the model. This allows your controller to decide which relationships should be loaded on the model and your resource can easily include them only when they have actually been loaded.

Ultimately, this makes it easier to avoid “N+1” query problems within your resources. The whenLoaded method may be used to conditionally load a relationship. In order to avoid unnecessarily loading relationships, this method accepts the name of the relationship instead of the relationship itself:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'posts' => PostResource::collection($this->whenLoaded('posts')),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

Eloquent: Mutators

Introduction
Accessors and mutators allow you to format Eloquent attribute values when you retrieve or set them on model instances. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.

In addition to custom accessors and mutators, Eloquent can also automatically cast date fields to Carbon instances or even cast text fields to JSON.

Accessors & Mutators

Defining An Accessor
To define an accessor, create a getFooAttribute method on your model where Foo is the “studly” cased name of the column you wish to access. In this example, we’ll define an accessor for the first_name attribute. The accessor will automatically be called by Eloquent when attempting to retrieve the value of the first_name attribute:

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
/**
* Get the user’s first name.
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
As you can see, the original value of the column is passed to the accessor, allowing you to manipulate and return the value. To access the value of the accessor, you may access the first_name attribute on a model instance:

$user = App\User::find(1);

$firstName = $user->first_name;
Of course, you may also use accessors to return new, computed values from existing attributes:

/**
* Get the user’s full name.
*
* @return string
*/
public function getFullNameAttribute()
{
return “{$this->first_name} {$this->last_name}”;
}
Defining A Mutator
To define a mutator, define a setFooAttribute method on your model where Foo is the “studly” cased name of the column you wish to access. So, again, let’s define a mutator for the first_name attribute. This mutator will be automatically called when we attempt to set the value of the first_name attribute on the model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
/**
* Set the user’s first name.
*
* @param string $value
* @return void
*/
public function setFirstNameAttribute($value)
{
$this->attributes[‘first_name’] = strtolower($value);
}
}
The mutator will receive the value that is being set on the attribute, allowing you to manipulate the value and set the manipulated value on the Eloquent model’s internal $attributes property. So, for example, if we attempt to set the first_name attribute to Sally:

$user = App\User::find(1);

$user->first_name = ‘Sally’;
In this example, the setFirstNameAttribute function will be called with the value Sally. The mutator will then apply the strtolower function to the name and set its resulting value in the internal $attributes array.

Date Mutators
By default, Eloquent will convert the created_at and updated_at columns to instances of Carbon, which extends the PHP DateTime class to provide an assortment of helpful methods. You may customize which dates are automatically mutated, and even completely disable this mutation, by overriding the $dates property of your model:

namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = [
‘created_at’,
‘updated_at’,
‘deleted_at’
];
}
When 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, and the date’s value will automatically be correctly stored in your database:

$user = App\User::find(1);

$user->deleted_at = now();

$user->save();
As noted above, when retrieving attributes that are listed in your $dates property, they will automatically be cast to Carbon instances, allowing you to use any of Carbon’s methods on your attributes:

$user = App\User::find(1);

return $user->deleted_at->getTimestamp();
Date Formats
By default, timestamps are formatted as ‘Y-m-d H:i:s’. If you need to customize the timestamp format, set the $dateFormat property on your model. This property determines how date attributes are stored in the database, as well as their format when the model is serialized to an array or JSON:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
/**
* The storage format of the model’s date columns.
*
* @var string
*/
protected $dateFormat = ‘U’;
}
Attribute Casting
The $casts property on your model provides a convenient method of converting attributes to common data types. The $casts property should be an array where the key is the name of the attribute being cast and the value is the type you wish to cast the column to. The supported cast types are: integer, real, float, double, decimal:, string, boolean, object, array, collection, date, datetime, and timestamp. When casting to decimal, you should define the number of digits, eg. decimal:2

For example, let’s cast the is_admin attribute, which is stored in our database as an integer (0 or 1) to a boolean value:

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
‘is_admin’ => ‘boolean’,
];
}
Now the is_admin attribute will always be cast to a boolean when you access it, even if the underlying value is stored in the database as an integer:

$user = App\User::find(1);

if ($user->is_admin) {
//
}
Array & JSON Casting
The array cast type is particularly useful when working with columns that are stored as serialized JSON. For example, if your database has a JSON or TEXT field type that contains serialized JSON, adding the array cast to that attribute will automatically deserialize the attribute to a PHP array when you access it on your Eloquent model:

‘array’,
];
}
Once the cast is defined, you may access the options attribute and it will automatically be deserialized from JSON into a PHP array. When you set the value of the options attribute, the given array will automatically be serialized back into JSON for storage:

$user = App\User::find(1);

$options = $user->options;

$options[‘key’] = ‘value’;

$user->options = $options;

$user->save();
Date Casting
When using the date or datetime cast type, you may specify the date’s format. This format will be used when the model is serialized to an array or JSON:

/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
‘created_at’ => ‘datetime:Y-m-d’,
];

collections

Introduction
All multi-result sets returned by Eloquent are instances of the Illuminate\Database\Eloquent\Collection object, including results retrieved via the get method or accessed via a relationship. The Eloquent collection object extends the Laravel base collection, so it naturally inherits dozens of methods used to fluently work with the underlying array of Eloquent models.

Of course, all collections also serve as iterators, allowing you to loop over them as if they were simple PHP arrays:

$users = App\User::where('active', 1)->get();

foreach ($users as $user) {
    echo $user->name;
}

However, collections are much more powerful than arrays and expose a variety of map / reduce operations that may be chained using an intuitive interface. For example, let’s remove all inactive models and gather the first name for each remaining user:

$users = App\User::all();

$names = $users->reject(function ($user) {
    return $user->active === false;
})
->map(function ($user) {
    return $user->name;
});

Available Methods
The Base Collection
All Eloquent collections extend the base Laravel collection object; therefore, they inherit all of the powerful methods provided by the base collection class:
allaverageavgchunkcollapsecombineconcatcontainscontainsStrictcountcrossJoindddiffdiffKeysdumpeacheachSpreadeveryexceptfilterfirstflatMapflattenflipforgetforPagegetgroupByhasimplodeintersectisEmptyisNotEmptykeyBykeyslastmapmapIntomapSpreadmapToGroupsmapWithKeysmaxmedianmergeminmodenthonlypadpartitionpipepluckpopprependpullpushputrandomreducerejectreversesearchshiftshuffleslicesortsortBysortByDescsplicesplitsumtaketaptoArraytoJsontransformunionuniqueuniqueStrictunlessvalueswhenwherewhereStrictwhereInwhereInStrictwhereNotInwhereNotInStrictzip

Custom Collections
If you need to use a custom Collection object with your own extension methods, you may override the newCollection method on your model:

namespace App;
use App\CustomCollection;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    /**
     * Create a new Eloquent Collection instance.
     *
     * @param  array  $models
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function newCollection(array $models = [])
    {
        return new CustomCollection($models);
    }
}

Once you have defined a newCollection method, you will receive an instance of your custom collection anytime Eloquent returns a Collection instance of that model. If you would like to use a custom collection for every model in your application, you should override the newCollection method on a base model class that is extended by all of your models.

laravel relationships

Introduction
Database tables are often 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. Eloquent makes managing and working with these relationships easy, and supports several different types of relationships:

One To One
One To Many
Many To Many
Has Many Through
Polymorphic Relations
Many To Many Polymorphic Relations

Eloquent relationships are defined as methods on your Eloquent model classes. Since, like Eloquent models themselves, relationships also serve as powerful query builders, defining relationships as methods provides powerful method chaining and querying capabilities. For example, we may chain additional constraints on this posts relationship:

$user->posts()->where(‘active’, 1)->get();
But, before diving too deep into using relationships, let’s learn how to define each type.

One To One
A one-to-one relationship is a very basic relation. For example, a User model might be associated with one Phone. To define this relationship, we place a phone method on the User model. The phone method should call the hasOne method and return its result:

namespace App;

use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    /**
     * Get the phone record associated with the user.
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

The first argument passed to the hasOne method is the name of the related model. Once the relationship is defined, we may retrieve the related record using Eloquent’s dynamic properties. Dynamic properties allow you to access relationship methods as if they were properties defined on the model:

$phone = User::find(1)->phone;
Eloquent determines the foreign key of the relationship based on the model name. In this case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method:

return $this->hasOne(‘App\Phone’, ‘foreign_key’);
Additionally, Eloquent assumes that the foreign key should have a value matching the id (or the custom $primaryKey) column of the parent. In other words, Eloquent will look for the value of the user’s id column in the user_id column of the Phone record. If you would like the relationship to use a value other than id, you may pass a third argument to the hasOne method specifying your custom key:

return $this->hasOne(‘App\Phone’, ‘foreign_key’, ‘local_key’);

Defining The Inverse Of The Relationship
So, we can access the Phone model from our User. Now, let’s define a relationship on the Phone model that will let us access the User that owns the phone. We can define the inverse of a hasOne relationship using the belongsTo method:

namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
    /**
     * Get the user that owns the phone.
     */
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

In the example above, Eloquent will try to match the user_id from the Phone model to an id on the User model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id. However, if the foreign key on the Phone model is not user_id, you may pass a custom key name as the second argument to the belongsTo method:

public function user()
{
    return $this->belongsTo('App\User', 'foreign_key');
}

If your parent model does not use id as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the belongsTo method specifying your parent table’s custom key:

public function user()
{
    return $this->belongsTo('App\User', 'foreign_key', 'other_key');
}

One To Many
A “one-to-many” relationship is used to define relationships where a single model owns any amount of other models. For example, a blog post may have an infinite number of comments. Like all other Eloquent relationships, one-to-many relationships are defined by placing a function on your Eloquent model:

namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
    /**
     * Get the comments for the blog post.
     */
    public function comments()
    {
        return $this->hasMany('App\Comment');
    }
}

Remember, Eloquent will automatically determine the proper foreign key column on the Comment model. By convention, Eloquent will take the “snake case” name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Comment model is post_id.

Once the relationship has been defined, we can access the collection of comments by accessing the comments property. Remember, since Eloquent provides “dynamic properties”, we can access relationship methods as if they were defined as properties on the model:

$comments = App\Post::find(1)->comments;
foreach ($comments as $comment) {
    //
}

Of course, since all relationships also serve as query builders, you can add further constraints to which comments are retrieved by calling the comments method and continuing to chain conditions onto the query:

$comment = App\Post::find(1)->comments()->where('title', 'foo')->first();

One To Many (Inverse)
Now that we can access all of a post’s comments, let’s define a relationship to allow a comment to access its parent post. To define the inverse of a hasMany relationship, define a relationship function on the child model which calls the belongsTo method:

namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }
}

In the example above, Eloquent will try to match the post_id from the Comment model to an id on the Post model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with a _ followed by the name of the primary key column. However, if the foreign key on the Comment model is not post_id, you may pass a custom key name as the second argument to the belongsTo method:

public function post()
{
    return $this->belongsTo('App\Post', 'foreign_key');
}
public function post()
{
    return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
}

Many-to-many relations are slightly more complicated than hasOne and hasMany relationships. 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”. To define this relationship, three database tables are needed: users, roles, and role_user. The role_user table is derived from the alphabetical order of the related model names, and contains the user_id and role_id columns.

Many-to-many relationships are defined by writing a method that returns the result of the belongsToMany method. For example, let’s define the roles method on our User model:

Defining The Inverse Of The Relationship
To define the inverse of a many-to-many relationship, you place another call to belongsToMany on your related model. To continue our user roles example, let’s define the users method on the Role model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    /**
     * The users that belong to the role.
     */
    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

Retrieving Intermediate Table Columns
As you have already learned, working with many-to-many relations requires the presence of an intermediate table. Eloquent 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 intermediate table using the pivot attribute on the models:

$user = App\User::find(1);
foreach ($user->roles as $role) {
    echo $role->pivot->created_at;
}

Customizing The pivot Attribute Name
As noted earlier, attributes from the intermediate table may be accessed on models using the pivot attribute. However, you are free to customize the name of this attribute to better reflect its purpose within your application.

For example, if your application contains users that may subscribe to podcasts, you probably have a many-to-many relationship between users and podcasts. If this is the case, you may wish to rename your intermediate table accessor to subscription instead of pivot. This can be done using the as method when defining the relationship:

Filtering Relationships Via Intermediate Table Columns
You can also filter the results returned by belongsToMany using the wherePivot and wherePivotIn methods when defining the relationship:
return $this->belongsToMany(‘App\Role’)->wherePivot(‘approved’, 1);

return $this->belongsToMany(‘App\Role’)->wherePivotIn(‘priority’, [1, 2]);

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    /**
     * The users that belong to the role.
     */
    public function users()
    {
        return $this->belongsToMany('App\User')->using('App\UserRole');
    }
}

The first argument passed to the hasManyThrough method is the name of the final model we wish to access, while the second argument is the name of the intermediate model.

Typical Eloquent foreign key conventions will be used when performing the relationship’s queries. If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the hasManyThrough method. The third argument is the name of the foreign key on the intermediate model. The fourth argument is the name of the foreign key on the final model. The fifth argument is the local key, while the sixth argument is the local key of the intermediate model:

class Country extends Model
{
    public function posts()
    {
        return $this->hasManyThrough(
            'App\Post',
            'App\User',
            'country_id', // Foreign key on users table...
            'user_id', // Foreign key on posts table...
            'id', // Local key on countries table...
            'id' // Local key on users table...
        );
    }
}
use Illuminate\Database\Eloquent\Relations\Relation;

Relation::morphMap([
    'posts' => 'App\Post',
    'videos' => 'App\Video',
]);
namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * Get all of the tags for the post.
     */
    public function tags()
    {
        return $this->morphToMany('App\Tag', 'taggable');
    }
}
namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get all of the posts for the user.
     */
    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}
$user = App\User::find(1);

foreach ($user->posts as $post) {
    //
}
$posts = App\Post::has('comments')->get();
$posts = App\Post::has('comments', '>=', 3)->get();
$posts = App\Post::has('comments.votes')->get();
$posts = App\Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();

Querying Relationship Absence
When accessing the records for a model, you may wish to limit your results based on the absence of a relationship. For example, imagine you want to retrieve all blog posts that don’t have any comments. To do so, you may pass the name of the relationship to the doesntHave and orDoesntHave methods:
Counting Related Models
If you want to count the number of results from a relationship without actually loading them you may use the withCount method, which will place a {relation}_count column on your resulting models. For example:

$posts = App\Post::withCount('comments')->get();

foreach ($posts as $post) {
    echo $post->comments_count;
}
$posts = App\Post::withCount(['votes', 'comments' => function ($query) {
    $query->where('content', 'like', 'foo%');
}])->get();

echo $posts[0]->votes_count;
echo $posts[0]->comments_count;
namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * Get the author that wrote the book.
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

Constraining Eager Loads
Sometimes you may wish to eager load a relationship, but also specify additional query constraints for the eager loading query. Here’s an example:

namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    /**
     * All of the relationships to be touched.
     *
     * @var array
     */
    protected $touches = ['post'];

    /**
     * Get the post that the comment belongs to.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }
}