├── docs ├── 0075-authorization.md ├── 0005-database.md ├── 0051-auth-component.md ├── 0039-one-to-many.md ├── 0024-deleting.md ├── 0004-controllers.md ├── 0002-routes-views.md ├── 0026-assets.md ├── 0011-views-collections-dates.md ├── 0009-models-eloquent.md ├── 0010-resource-controllers.md ├── 0006-migrations.md ├── 0028-testing.md ├── 0012-form-saving.md └── 0036-one-to-one.md ├── resources └── img │ ├── login-flow.png │ ├── middleware.png │ ├── one-to-one.png │ ├── one-to-many.png │ ├── Laravel-Routes.png │ ├── auth-components.png │ ├── 0005-create-database.gif │ ├── one-to-many-database.png │ ├── one-to-one-database.png │ ├── Laravel-Route-HTTP-Verbs.png │ ├── Laravel-Resource-Controller.png │ └── 0005-create-database.screenflow │ ├── thumbnail.jpg │ ├── version.plist │ ├── ScreenFlowDocument.dat │ └── Media │ └── C71468AF-9693-4F73-BC79-91A159D228FF_{8140FCA5-41D3-49E0-BF75-A8FC36CCF4AB}.scc └── README.md /docs/0075-authorization.md: -------------------------------------------------------------------------------- 1 | ## Authorization 2 | 3 | ### Gates 4 | 5 | 6 | 7 | ### Policies 8 | 9 | ### Authorizing -------------------------------------------------------------------------------- /resources/img/login-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/login-flow.png -------------------------------------------------------------------------------- /resources/img/middleware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/middleware.png -------------------------------------------------------------------------------- /resources/img/one-to-one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/one-to-one.png -------------------------------------------------------------------------------- /resources/img/one-to-many.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/one-to-many.png -------------------------------------------------------------------------------- /resources/img/Laravel-Routes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/Laravel-Routes.png -------------------------------------------------------------------------------- /resources/img/auth-components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/auth-components.png -------------------------------------------------------------------------------- /resources/img/0005-create-database.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/0005-create-database.gif -------------------------------------------------------------------------------- /resources/img/one-to-many-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/one-to-many-database.png -------------------------------------------------------------------------------- /resources/img/one-to-one-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/one-to-one-database.png -------------------------------------------------------------------------------- /resources/img/Laravel-Route-HTTP-Verbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/Laravel-Route-HTTP-Verbs.png -------------------------------------------------------------------------------- /resources/img/Laravel-Resource-Controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/Laravel-Resource-Controller.png -------------------------------------------------------------------------------- /resources/img/0005-create-database.screenflow/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/0005-create-database.screenflow/thumbnail.jpg -------------------------------------------------------------------------------- /resources/img/0005-create-database.screenflow/version.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/0005-create-database.screenflow/version.plist -------------------------------------------------------------------------------- /resources/img/0005-create-database.screenflow/ScreenFlowDocument.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/0005-create-database.screenflow/ScreenFlowDocument.dat -------------------------------------------------------------------------------- /resources/img/0005-create-database.screenflow/Media/C71468AF-9693-4F73-BC79-91A159D228FF_{8140FCA5-41D3-49E0-BF75-A8FC36CCF4AB}.scc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piotr-jura-udemy/laravel-cheat-sheet/HEAD/resources/img/0005-create-database.screenflow/Media/C71468AF-9693-4F73-BC79-91A159D228FF_{8140FCA5-41D3-49E0-BF75-A8FC36CCF4AB}.scc -------------------------------------------------------------------------------- /docs/0005-database.md: -------------------------------------------------------------------------------- 1 | ### Configuring database 2 | 3 | The database connection parameters are stored inside .env file (on development environment). 4 | 5 | On production environment store it in VirtualHost configuration or .htaccess file. To store variables in .htaccess file VirtualHost must contain the `AllowOverride All` directive. 6 | 7 | Reading environment variable 8 | 9 | ``` 10 | $value = env('DB_HOST', '127.0.0.1'); 11 | ``` 12 | 13 | *Where first value is the name of the variable, and second is the default value (if env variable is not defined).* 14 | 15 | ### Connecting to the database server 16 | 17 | #### Using phpMyAdmin 18 | 19 | Visit [http://localhost/phpmyadmin](http://localhost/phpmyadmin) if you are using XAMPP 20 | 21 | Create a new database 22 | 23 |  24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Cheat Sheet 2 | 3 | ## Laravel basics (routing, controllers, templates/views, forms, testing, assets) 4 | 5 | 1. [Routes, Views and Layout](./docs/0002-routes-views.md) 6 | 2. [Controllers](./docs/0004-controllers.md) 7 | 3. [Configuring Database](./docs/0005-database.md) 8 | 4. [Database Migrations](./docs/0006-migrations.md) 9 | 5. [Eloquent Models and Tinker](./docs/0009-models-eloquent.md) 10 | 6. [Resource Controllers](./docs/0010-resource-controllers.md) 11 | 7. [Blade @foreach, @if and Dates (Carbon)](./docs/0011-views-collections-dates.md) 12 | 8. [Forms, CSRF, Request, Middleware, Redirects](./docs/0012-form-saving.md) 13 | 9. [Deleting Models, Soft Deletes](./docs/0024-deleting.md) 14 | 10. [Assets, JavaScript, Styles](./docs/0026-assets.md) 15 | 11. [Testing basics](./docs/0028-testing.md) 16 | 17 | ## Database Relations 18 | 19 | 1. [One to One relations](./docs/0036-one-to-one.md) 20 | 2. [One to Many relations](./docs/0039-one-to-many.md) 21 | 22 | ## Authentication 23 | 24 | 1. [Authentication components](./docs/0051-auth-component.md) 25 | -------------------------------------------------------------------------------- /docs/0051-auth-component.md: -------------------------------------------------------------------------------- 1 | ## Authentication 2 | 3 | ### Authentication component 4 | 5 | Below is a diagram of Laravel Authentication component: 6 | 7 |  8 | 9 | The main component responsible for authenticating users is called **Guard**. 10 | 11 | **Guard** has 2 components: 12 | 13 | * Driver (how to handle user authenticated state - keep in session/read from token) 14 | * User Provider (where to find user accounts) 15 | 16 | **User Provider** is responsible for fetching users from certain storage (usually a database). 17 | 18 | **User Provider** also has a **Driver**, it can be: 19 | 20 | * Database (fetching users using raw SQL query) 21 | * Eloquent (use User model to fetch the user) 22 | 23 | Laravel has some sensible defaults configured out of the box. There are 2 guards: 24 | 25 | * **web** (for traditional web applications, using session to store currently authenticated user) 26 | * **api** (for APIs, stateless - no session is kept between request, each request needs to include a valid token to authenticate user) 27 | 28 | The default Laravel guard is **web**. 29 | 30 | ### Default login flow 31 | 32 | Below is the diagram of how logging in works by default: 33 | 34 |  -------------------------------------------------------------------------------- /docs/0039-one-to-many.md: -------------------------------------------------------------------------------- 1 | ## One-to-Many relations 2 | 3 | An example one-to-many relation diagram: 4 | 5 |  6 | 7 | ## Database design 8 | 9 |  10 | 11 | With one-to-many relation, 1 record from first table (eg. `blog_posts`) has zero or more matching records on the other table (eg. `comments`). 12 | 13 | One of the tables needs to have a column that will hold the `id` of the record on the other table. 14 | 15 | In our example, we have `blog_posts` and `comments`. `BlogPost` can be related to 1, 2, 3...n `Comment`, so the relation has to be stored inside `Comment`. 16 | 17 | In short: 18 | 19 | * has* - methods on Models that own the relation, no relation column 20 | * belongs* - methods on Models that are other side of the relation, with relation column 21 | 22 | In the example above each `BlogPost` model has zero or more `Comment`. 23 | 24 | ## Defining relations 25 | 26 | The relation on `BlogPost` model: 27 | 28 | ``` 29 | class BlogPost extends Model 30 | { 31 | public function comments() 32 | { 33 | return $this->hasMany('App\Comment'); 34 | } 35 | } 36 | ``` 37 | 38 | Relation on `Comment` model: 39 | 40 | ``` 41 | class Comment extends Model 42 | { 43 | public function blogPost() 44 | { 45 | return $this->belongsTo('App\BlogPost'); 46 | } 47 | } 48 | ``` 49 | 50 | ## Migrations 51 | 52 | `BlogPost` already exists and requires no changes. 53 | 54 | `Comment` model migration: 55 | 56 | ``` 57 | Schema::create('comments', function (Blueprint $table) { 58 | $table->increments('id'); 59 | $table->timestamps(); 60 | $table->string('content'); 61 | 62 | $table->unsignedInteger('blog_post_id')->index(); 63 | $table->foreign('blog_post_id')->references('id')->on('blog_posts'); 64 | }); 65 | ``` -------------------------------------------------------------------------------- /docs/0024-deleting.md: -------------------------------------------------------------------------------- 1 | ### Deleting models 2 | 3 | To delete a model, call the `delete` method on model instance 4 | 5 | ``` 6 | $post = BlogPost::findOrFail($id); 7 | $post->delete(); 8 | ``` 9 | 10 | Alternatively, without loading the model first 11 | 12 | ``` 13 | BlogPost::destroy($id); 14 | ``` 15 | 16 | Or to delete a collection of models at once 17 | 18 | ``` 19 | BlogPost::delete([1, 2, 3]); 20 | ``` 21 | 22 | #### Soft deleting 23 | 24 | You may optionally opt to keep the original record in database, and just mark it with `deleted_at` field. 25 | 26 | To enable it easily, use the `SoftDeletes` trait on the model 27 | 28 | ``` 29 | namespace App; 30 | 31 | use Illuminate\Database\Eloquent\Model; 32 | use Illuminate\Database\Eloquent\SoftDeletes; 33 | 34 | class BlogPost extends Model 35 | { 36 | use SoftDeletes; 37 | 38 | protected $dates = ['deleted_at']; 39 | } 40 | ``` 41 | 42 | You need to remember to add the `deleted_at` column to the Model 43 | 44 | ``` 45 | Schema::table('blog_posts', function (Blueprint $table) { 46 | $table->softDeletes(); 47 | }); 48 | ``` 49 | 50 | To determine if a particular model instance was deleted use `trashed` method. 51 | 52 | ``` 53 | $isDeleted = $post->trashed(); 54 | ``` 55 | 56 | Now when you query for models, the soft deleted models are automatically exlcuded from results. 57 | 58 | ``` 59 | // This will never include models that were "soft deleted" 60 | $posts = BlogPost::all(); 61 | ``` 62 | 63 | To include also the "soft deleted" models 64 | 65 | ``` 66 | BlogPost::withTrashed()->get(); 67 | ``` 68 | 69 | To fetch only trashed models 70 | 71 | ``` 72 | BlogPost::onlyTrashed()->get(); 73 | ``` 74 | 75 | To restore a soft deleted model 76 | 77 | ``` 78 | $post->restore(); 79 | ``` 80 | 81 | If a model is "soft deleteable" and you wish to permanently remove it 82 | 83 | ``` 84 | $post->forceDelete(); 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/0004-controllers.md: -------------------------------------------------------------------------------- 1 | ### Controllers 2 | 3 | Controllers are an alternative to Closures for defining the application logic 4 | 5 | Generating a new Controller 6 | 7 | `php artisan make:controller ControllerNameController` 8 | 9 | Controllers are stored inside the `app/Http/Controllers` folder 10 | 11 | An example controller class 12 | 13 | ```php 14 | 'value']); // With parameters 22 | ``` 23 | 24 | Route with a required parameter 25 | 26 | ```php 27 | Route::get('/page/{id}', function ($id) { 28 | return view('page', ['page' => $id]); 29 | }); 30 | 31 | // Using Arrow Functions (Since PHP 7.4) 32 | Route::get('/page/{id}', fn ($id) => view('page', ['page' => $id])); 33 | ``` 34 | 35 | Route with an optional parameter 36 | 37 | ```php 38 | Route::get('/hello/{name?}', function ($name = 'Guest') { 39 | return view('hello', ['name' => $name]); 40 | }); 41 | 42 | // Using Arrow Functions (Since PHP 7.4) 43 | // For optional route parameter {name}, the Closure argument has to have a default value provided 44 | Route::get('/hello/{name?}', fn ($name = 'Guest') => view('hello', ['name' => $name])); 45 | ``` 46 | 47 | Named route (to give the route a name, you would chain a `name()` method call) 48 | 49 | ```php 50 | Route::view('/home')->name('home'); 51 | ``` 52 | 53 | Generating URI of the named route (generating links) 54 | 55 | ```php 56 | // Without parameters 57 | $url = route('home'); // Generates /home 58 | 59 | // With parameters 60 | $blogPostUrl = route('blog-post', ['id' => 1]); // Generates /blog-post/1 61 | ``` 62 | 63 | ### Inside Blade template 64 | Defining a section 65 | 66 | ```blade 67 | @section('content') 68 |
No blog posts
18 | @endforelse 19 | ``` 20 | 21 | Including a sub-view (included views inherit the data of parent view) 22 | 23 | ```blade 24 | @include('post') 25 | ``` 26 | Passing additional data to included view 27 | 28 | ```blade 29 | @include('post', ['some' => 'data']) 30 | ``` 31 | 32 | Including multiple views at once for a collection 33 | 34 | ```blade 35 | @each('post', $posts, 'post') 36 | ``` 37 | 38 | The first argument is the partial view template name, second the collection, third the variable name that would be available inside included view 39 | 40 | ### Conditional rendering 41 | 42 | The @if directive 43 | 44 | ```blade 45 | @if ($post->id === 1) 46 | Post one! 47 | @elseif ($post->id === 2) 48 | Post two! 49 | @else 50 | Something else 51 | @endif 52 | ``` 53 | 54 | The @unless directive 55 | 56 | ```blade 57 | @unless ($post->id === 1) 58 | Post one! 59 | @endunless 60 | ``` 61 | 62 | 63 | ### Dates 64 | 65 | #### Date mutators 66 | 67 | [https://laravel.com/docs/7.x/eloquent-mutators#date-mutators](https://laravel.com/docs/7.x/eloquent-mutators#date-mutators) 68 | 69 | By default the `created_at` and `updated_at` will be converted to Carbon date objects 70 | 71 | It can be configured using `dates` field of the model 72 | 73 | ```php 74 | class BlogPost extends Model 75 | { 76 | protected $dates = [ 77 | 'created_at', 78 | 'updated_at', 79 | 'deleted_at' 80 | ]; 81 | } 82 | ``` 83 | 84 | #### Date format 85 | 86 | By default date columns are stored as `Y-m-d H:i:s` format 87 | 88 | It can be customized using `dateFormat` field of the model. 89 | 90 | **Warning!** This will change how date is stored inside the database and how it is being formatted by default! 91 | 92 | ```php 93 | class BlogPost extends Model 94 | { 95 | protected $dateFormat = 'Y-m-d'; 96 | } 97 | ``` 98 | 99 | #### Carbon 100 | 101 | Carbon is a PHP library that extends the base `\DateTime` class. It's extensively used in Laravel. 102 | 103 | Full API documentation [https://carbon.nesbot.com/docs/](https://carbon.nesbot.com/docs/) 104 | 105 | Formatting the date in the "time ago" format (in Blade template) 106 | 107 | ```blade 108 | {{ $post->created_at->diffForHumans() }} 109 | ``` 110 | 111 | Checking for time difference (https://carbon.nesbot.com/docs/#api-difference) 112 | 113 | In the below example we check if the time passed between now, and the post created_at date is less than 5 minutes. Only then we render the "New!" badge. 114 | 115 | ```blade 116 | @unless (now()->diffInMinutes($post->created_at) < 5) 117 | New! 118 | @endunless 119 | ``` 120 | -------------------------------------------------------------------------------- /docs/0009-models-eloquent.md: -------------------------------------------------------------------------------- 1 | ### Laravel Tinker 2 | 3 | Tinker is a console program that allows you to play around with Laravel models and execute arbitraty PHP command directly from your command line 4 | 5 | Starting the console 6 | 7 | ``` 8 | php artisan tinker 9 | ``` 10 | 11 | #### Solving a problem with Tinker (for PHP 7.3 or newer) when it quits after every command 12 | 13 | Modify the php.ini by adding this option 14 | 15 | ``` 16 | pcre.jit=0 17 | ``` 18 | 19 | On Mac php.ini can be usually found in `/Applications/XAMPP/xamppfiles/etc/php.ini` 20 | 21 | To be sure where it is, run `php -i | grep 'php.ini'` in Terminal 22 | 23 | On Windows it's in your XAMPP folder `C:\xampp\php\php.ini` or `C:\xampp\etc\php.ini`, depending on location of XAMPP itself 24 | 25 | 26 | ### Eloquent Model 27 | 28 | Generating a new model 29 | 30 | ``` 31 | php artisan make:model BlogPost 32 | ``` 33 | 34 | Generating a new model with migration 35 | 36 | ``` 37 | php artisan make:model BlogPost --migration 38 | // or 39 | php artisan make:model BlogPost -m 40 | ``` 41 | 42 | By convention, Laravel assumes the table name is "snake case" plural model name. For example: 43 | 44 | | Model name | Table name | 45 | | -------- |------------- | 46 | | BlogPost | `blog_posts` | 47 | | Blogpost | `blogposts` | 48 | | VeryLongTrain | `very_long_trains` | 49 | 50 | To define a custom name, add (override) the protected `$table` model property 51 | 52 | ``` 53 | class BlogPost extends Model 54 | { 55 | protected $table = 'blogposts'; 56 | } 57 | ``` 58 | 59 | By default, all models are stored inside the `App` namespace, eg. `App\BlogPost` 60 | 61 | #### Acessing and modifying properties 62 | 63 | You can read and modify model properties (row columns) using properties 64 | 65 | ``` 66 | $post = App\BlogPost::find(1); 67 | $title = $post->title; 68 | $content = $post->content; 69 | 70 | $post->title = 'New title'; 71 | $post->content = 'New content'; 72 | // Always call save() to create the record and UPDATE the existing one 73 | $post->save(); 74 | ``` 75 | 76 | Property name corresponds 1:1 to the column name of the table 77 | 78 | ### Querying 79 | 80 | Retrieving all models as *collection* 81 | 82 | ``` 83 | $posts = App\BlogPost::all(); 84 | ``` 85 | 86 | Retrieving single model by primary key (usually, by `id` property/column) 87 | 88 | ``` 89 | // Fetch BlogPost with id 10 90 | $post = App\BlogPost::find(10); 91 | ``` 92 | 93 | Fetching *collection* of models by id 94 | 95 | ``` 96 | $posts = App\BlogPost::find([1, 2, 3]); 97 | ``` 98 | 99 | Collections are iterable (eg. using foreach) 100 | 101 | ``` 102 | $posts = App\BlogPost::all(); 103 | 104 | foreach ($posts as $post) { 105 | echo $post->title; 106 | } 107 | ``` 108 | 109 | Getting first element of the collection of models 110 | 111 | ``` 112 | $posts = App\BlogPost::all(); 113 | $post = $posts->first(); 114 | ``` 115 | 116 | Creating and saving (creating a database row) a new model 117 | 118 | ``` 119 | $post = new App\BlogPost(); 120 | $post->title = 'Title'; 121 | $post->content = 'Content'; 122 | $post->save(); 123 | ``` -------------------------------------------------------------------------------- /docs/0010-resource-controllers.md: -------------------------------------------------------------------------------- 1 | ## Resource controllers 2 | 3 | You can import the model class in your controller 4 | 5 | ```php 6 | use App\BlogPost 7 | 8 | // Now it can be used like this 9 | BlogPost::all(); 10 | // Instead of 11 | \App\BlogPost::all(); 12 | ``` 13 | 14 | ### Resource controllers overview (diagram) 15 | 16 |  17 | 18 | ### Resource controllers 19 | 20 | If you think about a single resource, like photo - resource controllers let you organize all controller logic around that resource easily 21 | 22 | Using resource controllers 23 | 24 | ```php 25 | Route::resource('posts', 'PostController'); 26 | ``` 27 | 28 | Instead of manually specifying routes 29 | 30 | ```php 31 | Route::get('/posts', 'PostController@index')->name('blog.index'); 32 | Route::get('/posts/{id}', 'PostController@show')->name('blog.show'); 33 | ``` 34 | 35 | Generating a new resource controller with all the resource methods 36 | 37 | `php artisan make:controller PostController --resource` 38 | 39 | Resource methods table 40 | 41 | |Verb | URI |Action |Route Name | 42 | |-------- |-------- |-------- |-------- | 43 | |GET |/posts |index |posts.index | 44 | |GET |/posts/create |create | posts.create | 45 | |POST |/posts |store |posts.store | 46 | |GET |/posts/{photo} |show |posts.show | 47 | |GET |/posts/{photo}/edit |edit |posts.edit | 48 | |PUT/PATCH |/posts/{photo} |update |posts.update | 49 | |DELETE |/posts/{photo} |destroy |posts.destroy | 50 | 51 | To enable only certain routes 52 | 53 | ```php 54 | Route::resource('posts', 'PostController')->only(['index', 'show']); 55 | ``` 56 | 57 | To disable specific routes 58 | 59 | ```php 60 | Route::resource('posts', 'PostController')->except(['create', 'store', 'edit', 'update', 'destroy]); 61 | ``` 62 | 63 | *Both examples above will result in the same routes - posts.index and posts.show* 64 | 65 | ### Fetching a single model 66 | 67 | Model can be fetched using `BlogPost::find($id)` 68 | 69 | To display a 404 Not Found page when model cannot be found, use `BlogPost::findOrFail($id)` 70 | 71 | ### Route Model Binding 72 | 73 | Those 2 examples are equivalent 74 | 75 | ```php 76 | PostController extends Controller { 77 | public function show($post) { 78 | return view('post.show', ['post' => BlogPost::findOrFail($id)]); 79 | } 80 | } 81 | ``` 82 | Above, we manually try to fetch the BlogPost model. `findOrFail` will show a 404 page if model is not found. 83 | 84 | ```php 85 | PostController extends Controller { 86 | public function show(BlogPost $post) { 87 | return view('post.show', ['post' => $post]); 88 | } 89 | } 90 | ``` 91 | Above we use **Route Model Binding**. If the method parameter name matches the route segment, eg. route is `/posts/{post}` the variable name has to be `$post`. Then `type hinting` (specyfying the argument type) as the Eloquent model `BlogPost`, tells Laravel to try and fetch this object by `id`. 92 | 93 | To customize the property by which the model is fetched (using **Route Model Binding**!), add the `getRouteKeyName()` method to the model. 94 | 95 | ```php 96 | public function getRouteKeyName() 97 | { 98 | return 'slug'; 99 | } 100 | ``` 101 | 102 | With the example above, Laravel would try to find a `BlogPost` model by `slug` property. 103 | -------------------------------------------------------------------------------- /docs/0006-migrations.md: -------------------------------------------------------------------------------- 1 | ### Migrations problems 2 | 3 | The limit for keys is 767 bytes. 4 | 5 | In the `utf-8` encoding, the single character is 3 bytes, so key on `VARCHAR(255)` length won't exceed 767 (3 * 255 = 765). 6 | 7 | In you are using `utf8mb4`, which we are, the single character is 4 bytes. Thus the maximum length for `VARCHAR` which has key on it (like `UNIQUE`) is 191. 8 | 9 | When you encounter this: 10 | 11 | ``` 12 | Migration table created successfully. 13 | Migrating: 2014_10_12_000000_create_users_table 14 | 15 | Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`)) 16 | ``` 17 | 18 | Change the email field length to 191. 19 | 20 | ### Running migrations 21 | 22 | To run the most recent, not executed yet migrations 23 | 24 | ``` 25 | php artisan migrate 26 | ``` 27 | 28 | To rollback the most recent migration 29 | 30 | ``` 31 | php artisan migrate:rollback 32 | ``` 33 | 34 | Setting the length of the field 35 | 36 | ``` 37 | $table->string('email', 191); 38 | ``` 39 | 40 | ### Writing migrations 41 | 42 | Creating a new migration 43 | 44 | ``` 45 | php artisan make:migration create_blogposts_table 46 | ``` 47 | 48 | To prefill the migration with stub code that creates a new table 49 | 50 | ``` 51 | php artisan make:migration create_blogposts_table --create=blogposts 52 | ``` 53 | 54 | To prefill the migration with stub code that modifies an existing table 55 | 56 | 57 | ``` 58 | php artisan make:migration add_date_to_blogposts_table --table=blogposts 59 | ``` 60 | 61 | ### The migration file 62 | 63 | Migration file containts a class with 2 methods, `up()` and `down()` 64 | 65 | The `up()` methods creates new table, modifies the existing one. Generally, it specifies how your database schema should change from now on - this might include deleting fields or tables. 66 | 67 | The `down()` method specifies how to revert changes made my migration. 68 | 69 | `up()` method is called when you run `php artisan migrate` 70 | 71 | `down()` method is called when you run `php artisan migrate:rollback` 72 | 73 | Creating a new table 74 | 75 | ``` 76 | Schema::create('blogposts', function (Blueprint $table) { 77 | $table->increments('id'); 78 | }); 79 | ``` 80 | 81 | Renaming an existing table 82 | 83 | ``` 84 | Schema::rename('blogposts', 'posts'); 85 | 86 | ``` 87 | 88 | Creating columns 89 | 90 | ``` 91 | Schema::table('blogposts', function (Blueprint $table) { 92 | $table->string('title'); 93 | }); 94 | ``` 95 | 96 | Available column types 97 | 98 | Refer to this link [https://laravel.com/docs/5.7/migrations#columns](https://laravel.com/docs/5.7/migrations#columns) 99 | 100 | Typical columns types 101 | 102 | | Command | Description | 103 | | -------- |------------- | 104 | | `$table->increments('id');` | Auto-incrementing UNSIGNED INTEGER | 105 | | `$table->string('title', 100);` | VARCHAR with optional length | 106 | | `$table->timestamps();` | Nullable TIMESTAMP `created_at` and `updated_at` columns | 107 | | `$table->text('content');` | TEXT | 108 | 109 | Column modifiers 110 | 111 | `->default('value')` - the default column value 112 | 113 | `->nullable()` - column can be NULL 114 | 115 | `->unsigned()` - integer is unsigned (no negative values) -------------------------------------------------------------------------------- /docs/0028-testing.md: -------------------------------------------------------------------------------- 1 | ### Testing 2 | 3 | You are already set up with Laravel to test your application. 4 | 5 | By default, tests are stored inside `tests` directory. 6 | 7 | It contains two further ones: 8 | 9 | * `Unit` - for testing small isolated parts of your code, like one class functionality or a single method 10 | * `Feature` - as name suggests, testing features of your app, often through making HTTP requests to your running application 11 | 12 | The configuration file `phpunit.xml` is already included. 13 | 14 | #### Testing in a separate environment 15 | 16 | Tests usually run in a separate `environment`. By `environment` I mean different set of settings for your application. 17 | 18 | As you normally store your environment variables inside `.env` file for local development, you would configure this variables inside `phpunit.xml` file instead. 19 | 20 | By default, Laravel runs tests in `testing` environment. 21 | 22 | If your tests involve database, you would not like to perform any changes on your local database. 23 | 24 | You might create a new MySQL database for testing, or use SQLite (an in-memory version of it). 25 | 26 | To specify a different database connection for testing environment, add 27 | 28 | ```xml 29 |