41

Creating a Basic ToDo Application in Laravel 5 – Part 1

Posted February 5th, 2015 (Updated 13 May 2015) in PHP

With the release of Laravel 5, there have been a bunch of backwards incompatible changes, new features added as well as the usual influx of new users so I thought I’d take the time to redo my basic to-do application with Laravel 5. The app covers a wide range of concepts, links to relevant learning material where possible and should make for a great introduction to the framework.

This tutorial is relatively long so I’ve broken it up into multiple posts.

  1. Part 1 – Installation, Database and Routes
  2. Part 2 – Listing Projects and Tasks
  3. Part 3 – Create/Edit/Delete
  4. Part 4 – Validation

The source for each part can also be found on GitHub.

Today will cover installation, configuration, artisan, migration, seeding and routes.

 

Before you Begin

Before you begin there are a few great resources you should check out.

You won’t get far in the Laravel world without hearing about Jeffrey Way. Jeffrey has perhaps done more for the Laravel community than any other non-core developer. He has produced high-quality, comprehensive video tutorials on almost every aspect of L5, many of which are free to view and aimed at beginners. I would highly recommend you check out the following pieces of his work:

  1. Laravel 5 Fundamentals – An absolute must-see series of free screencasts for new users of Laravel.
  2. What’s New in Laravel 5 – A great series by Matt Stauffer showing off some cool new stuff in Laravel.
  3. Laracasts – Mostly paid for videos of very high quality. New videos are regularly created and one a week is made free.

There are a few other places to find news and information:

  1. The Laravel Twitter feed – for the latest breaking news on L4 development.
  2. Taylor Otwell’s Twitter feed – the author of Laravel himself.
  3. Laravel.io – Weekly roundups  that gather the latest news and tutorials from around the web. They also do a weekly podcast covering their thoughts/concerns relevant to the platform.
  4. Laravel Packages Registry – good place to go to find some of the best Laravel packages
  5. Code Bright – An e-book provided free of charge by framework author Dayle Rees

If you’re coming from Laravel 4 I also recommend checking out Directory structure and namespace by Matt Stauffer.

 

Project Aim

Our to-do application will consist of one or more projects, each with its own list of tasks. You will be able to create, list, modify and delete both tasks and projects.

In this lesson we will go through:

  1. Installing and setting up Laravel
  2. Installing extra packages that will make development easier
  3. Using migrations and seeds
  4. Learning how to use resourceful controllers
  5. Learning how to use views (including the blade templating language and content layouts)
  6. Handling model relations

 

Installation

Installing Laravel is extremely quick and painless thanks to Composer. I’ll blaze through this section as it’s really been covered to death by this point.

Composer

Further Details: See Meet Composer

First you’ll need to install Composer if you haven’t already (you’ll only need to do this once):

1
2
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Laravel

Now for the laravel installer (you’ll only need to do this once):

1
composer global require "laravel/installer=~1.1"

and finally our project:

1
laravel new l5todo

Configuration

Laravel 5 uses a package called DotEnv that stores sensitive information in .env files which are loaded as PHP environment variables at runtime. Sounds complicated but it just means your sensitive credentials go into these files while the rest of your config remains in the standard config files.

Database

We need a database. Set one up for yourself in a DB of your choice then copy .env.example to .env and update accordingly:

1
2
3
4
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

Finally if you’re not using MySQL open /config/database.php and change the default line:

1
'default' => 'mysql',

Remember to add your environment files to your .gitignore by adding a .env line!

 

Taking our First Steps

As mentioned above, our to-do application will comprise of one or more projects each with their own task list. We’re going to need Project and Task models, controllers, views, migrations, seeds (optional but useful) and routes. You probably already understand what most/all of these are, however if you don’t you should check out the video M-V-Huh? and Basic Model/Controller/View Workflow.

Let’s make our way through them one at a time.

 

Migrations

Further Details: See Migrations

We want to get our table schema set up in the database. It will look like the following:

Projects
+------------+------------------+------+-----+
| Field      | Type             | Null | Key |
+------------+------------------+------+-----+
| id         | int(10) unsigned | NO   | PRI |
| name       | varchar(255)     | NO   |     |
| slug       | varchar(255)     | NO   |     |
| created_at | timestamp        | NO   |     |
| updated_at | timestamp        | NO   |     |
+------------+------------------+------+-----+
 
Tasks
+-------------+------------------+------+-----+
| Field       | Type             | Null | Key |
+-------------+------------------+------+-----+
| id          | int(10) unsigned | NO   | PRI |
| project_id  | int(10) unsigned | NO   | MUL |
| name        | varchar(255)     | NO   |     |
| slug        | varchar(255)     | NO   |     |
| completed   | tinyint(1)       | NO   |     |
| description | text             | NO   |     |
| created_at  | timestamp        | NO   |     |
| updated_at  | timestamp        | NO   |     |
+-------------+------------------+------+-----+

First a migration must be set up:

1
php artisan make:migration create_projects_and_tasks_tables --create="projects"

We’re creating both tables in the one migration so that they can be removed in reverse order to avoid an integrity constraint violation. Open /database/migrations/<date>_create_projects_and_tasks_tables.php and set it up as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreateProjectsAndTasksTables extends Migration {
 
	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('projects', function(Blueprint $table)
		{
			$table->increments('id');
			$table->string('name')->default('');			$table->string('slug')->default('');			$table->timestamps();
		});
 
		Schema::create('tasks', function(Blueprint $table) {			$table->increments('id');			$table->integer('project_id')->unsigned()->default(0);			$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');			$table->string('name')->default('');			$table->string('slug')->default('');			$table->boolean('completed')->default(false);			$table->text('description')->default('');			$table->timestamps();		});	}
 
	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('tasks');		Schema::drop('projects');
	}
 
}

Perform the migration:

1
php artisan migrate

If you check the database, your tables should now be all set up.

 

Seeds

Further details: See Database Seeding

We’ll seed some projects/tasks to have something to work with when we finally get to the browser. Create /database/seeds/ProjectsTableSeeder.php and TasksTableSeeder.php like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// /database/migrations/seeds/ProjectsTableSeeder.php
<?php
 
use Illuminate\Database\Seeder;
 
class ProjectsTableSeeder extends Seeder {
 
    public function run()
    {
        // Uncomment the below to wipe the table clean before populating
        DB::table('projects')->delete();
 
        $projects = array(
            ['id' => 1, 'name' => 'Project 1', 'slug' => 'project-1', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 2, 'name' => 'Project 2', 'slug' => 'project-2', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 3, 'name' => 'Project 3', 'slug' => 'project-3', 'created_at' => new DateTime, 'updated_at' => new DateTime],
        );
 
        // Uncomment the below to run the seeder
        DB::table('projects')->insert($projects);
    }
 
}
 
// /database/migrations/seeds/TasksTableSeeder.php
<?php
 
use Illuminate\Database\Seeder;
 
class TasksTableSeeder extends Seeder {
 
    public function run()
    {
        // Uncomment the below to wipe the table clean before populating
        DB::table('tasks')->delete();
 
        $tasks = array(
            ['id' => 1, 'name' => 'Task 1', 'slug' => 'task-1', 'project_id' => 1, 'completed' => false, 'description' => 'My first task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 2, 'name' => 'Task 2', 'slug' => 'task-2', 'project_id' => 1, 'completed' => false, 'description' => 'My first task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 3, 'name' => 'Task 3', 'slug' => 'task-3', 'project_id' => 1, 'completed' => false, 'description' => 'My first task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 4, 'name' => 'Task 4', 'slug' => 'task-4', 'project_id' => 1, 'completed' => true, 'description' => 'My second task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 5, 'name' => 'Task 5', 'slug' => 'task-5', 'project_id' => 1, 'completed' => true, 'description' => 'My third task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 6, 'name' => 'Task 6', 'slug' => 'task-6', 'project_id' => 2, 'completed' => true, 'description' => 'My fourth task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
            ['id' => 7, 'name' => 'Task 7', 'slug' => 'task-7', 'project_id' => 2, 'completed' => false, 'description' => 'My fifth task', 'created_at' => new DateTime, 'updated_at' => new DateTime],
        );
 
        //// Uncomment the below to run the seeder
        DB::table('tasks')->insert($tasks);
    }
 
}

Also don’t forget to add your seed classes to /database/seeds/DatabaseSeeder.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
 
class DatabaseSeeder extends Seeder {
 
	/**
	 * Run the database seeds.
	 *
	 * @return void
	 */
	public function run()
	{
		Model::unguard();
 
		$this->call('ProjectsTableSeeder');		$this->call('TasksTableSeeder');	}
 
}

Now we seed:

1
composer dump-autoload

then

1
2
3
php artisan db:seed
# or
php artisan migrate:refresh --seed

Your database should now be seeded!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> select * from projects;
+----+-----------+-----------+---------------------+---------------------+
| id | name      | slug      | created_at          | updated_at          |
+----+-----------+-----------+---------------------+---------------------+
|  1 | Project 1 | project-1 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  2 | Project 2 | project-2 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  3 | Project 3 | project-3 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
+----+-----------+-----------+---------------------+---------------------+
 
mysql> select * from tasks;
+----+------------+--------+--------+-----------+----------------+---------------------+---------------------+
| id | project_id | name   | slug   | completed | description    | created_at          | updated_at          |
+----+------------+--------+--------+-----------+----------------+---------------------+---------------------+
|  1 |          1 | Task 1 | task-1 |         0 | My first task  | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  2 |          1 | Task 2 | task-2 |         0 | My first task  | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  3 |          1 | Task 3 | task-3 |         0 | My first task  | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  4 |          1 | Task 4 | task-4 |         1 | My second task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  5 |          1 | Task 5 | task-5 |         1 | My third task  | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  6 |          2 | Task 6 | task-6 |         1 | My fourth task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
|  7 |          2 | Task 7 | task-7 |         0 | My fifth task  | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
+----+------------+--------+--------+-----------+----------------+---------------------+---------------------+

 

Models

To work with our projects and tasks tables we need equivalent Models so create them now:

1
2
php artisan make:model Project
php artisan make:model Task

That was easy!

 

Artisan – Tinker

Now that we have information in the database it would be a great time to learn about one of artisan’s handy features – tinker. As explained in the informative article Tinkering with Tinker Like an Artisan, tinker provides a command line for interacting with your Laravel installation. As an example, let’s use it to retrieve the number of projects currently in the database:

$ php artisan tinker
>App\Project::count();    
3
>App\Task::count();
7

As you can see tinker has the potential to be quite useful. I’ll be referencing it a few times in this tutorial.

 

Controllers

We’ve gotten to the point now where we can start hitting the browser. To do that we need to set up some Controllers and Routes to point to them. First up the controllers:

1
2
php artisan make:controller ProjectsController
php artisan make:controller TasksController

 

Nested Resources

Further Details: See Nested Resources

Begin by adding the Project and Task resources to /app/Http/routes.php:

1
2
3
4
5
6
7
8
9
10
11
Route::get('/', 'WelcomeController@index');
 
//Route::get('home', 'HomeController@index');
//
//Route::controllers([
//	'auth' => 'Auth\AuthController',
//	'password' => 'Auth\PasswordController',
//]);
 
Route::resource('projects', 'ProjectsController');Route::resource('tasks', 'TasksController');

Let’s now look at a neat little artisan feature – route:list. In your command line enter the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
php artisan route:list
+--------+----------+--------------------------+------------------+-------------------------------------------------+------------+
| Domain | Method   | URI                      | Name             | Action                                          | Middleware |
+--------+----------+--------------------------+------------------+-------------------------------------------------+------------+
|        | GET|HEAD | /                        |                  | App\Http\Controllers\WelcomeController@index    |            |
|        | GET|HEAD | projects                 | projects.index   | App\Http\Controllers\ProjectsController@index   |            |
|        | GET|HEAD | projects/create          | projects.create  | App\Http\Controllers\ProjectsController@create  |            |
|        | POST     | projects                 | projects.store   | App\Http\Controllers\ProjectsController@store   |            |
|        | GET|HEAD | projects/{projects}      | projects.show    | App\Http\Controllers\ProjectsController@show    |            |
|        | GET|HEAD | projects/{projects}/edit | projects.edit    | App\Http\Controllers\ProjectsController@edit    |            |
|        | PUT      | projects/{projects}      | projects.update  | App\Http\Controllers\ProjectsController@update  |            |
|        | PATCH    | projects/{projects}      |                  | App\Http\Controllers\ProjectsController@update  |            |
|        | DELETE   | projects/{projects}      | projects.destroy | App\Http\Controllers\ProjectsController@destroy |            |
|        | GET|HEAD | tasks                    | tasks.index      | App\Http\Controllers\TasksController@index      |            |
|        | GET|HEAD | tasks/create             | tasks.create     | App\Http\Controllers\TasksController@create     |            |
|        | POST     | tasks                    | tasks.store      | App\Http\Controllers\TasksController@store      |            |
|        | GET|HEAD | tasks/{tasks}            | tasks.show       | App\Http\Controllers\TasksController@show       |            |
|        | GET|HEAD | tasks/{tasks}/edit       | tasks.edit       | App\Http\Controllers\TasksController@edit       |            |
|        | PUT      | tasks/{tasks}            | tasks.update     | App\Http\Controllers\TasksController@update     |            |
|        | PATCH    | tasks/{tasks}            |                  | App\Http\Controllers\TasksController@update     |            |
|        | DELETE   | tasks/{tasks}            | tasks.destroy    | App\Http\Controllers\TasksController@destroy    |            |
+--------+----------+--------------------------+------------------+-------------------------------------------------+------------+

You’ll notice that both projects and tasks are top level urls. In our to-do app, tasks belong to projects though, so it makes sense for URLs to be nested more like /projects/1/tasks/3 instead of just /tasks/3. This can be accomplished using something called nested resources. As with most things in Laravel, the modification required is quick and simple. Open /app/Http/routes.php and make the following change:

1
2
// Route::resource('tasks', 'TasksController');
Route::resource('projects.tasks', 'TasksController');

That’s it. Do another php artisan route:list and see what you have now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
php artisan route:list
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
| Domain | Method   | URI                                    | Name                   | Action                                          | Middleware |
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
|        | GET|HEAD | /                                      |                        | App\Http\Controllers\WelcomeController@index    |            |
|        | GET|HEAD | projects                               | projects.index         | App\Http\Controllers\ProjectsController@index   |            |
|        | GET|HEAD | projects/create                        | projects.create        | App\Http\Controllers\ProjectsController@create  |            |
|        | POST     | projects                               | projects.store         | App\Http\Controllers\ProjectsController@store   |            |
|        | GET|HEAD | projects/{projects}                    | projects.show          | App\Http\Controllers\ProjectsController@show    |            |
|        | GET|HEAD | projects/{projects}/edit               | projects.edit          | App\Http\Controllers\ProjectsController@edit    |            |
|        | PUT      | projects/{projects}                    | projects.update        | App\Http\Controllers\ProjectsController@update  |            |
|        | PATCH    | projects/{projects}                    |                        | App\Http\Controllers\ProjectsController@update  |            |
|        | DELETE   | projects/{projects}                    | projects.destroy       | App\Http\Controllers\ProjectsController@destroy |            |
|        | GET|HEAD | projects/{projects}/tasks              | projects.tasks.index   | App\Http\Controllers\TasksController@index      |            |
|        | GET|HEAD | projects/{projects}/tasks/create       | projects.tasks.create  | App\Http\Controllers\TasksController@create     |            |
|        | POST     | projects/{projects}/tasks              | projects.tasks.store   | App\Http\Controllers\TasksController@store      |            |
|        | GET|HEAD | projects/{projects}/tasks/{tasks}      | projects.tasks.show    | App\Http\Controllers\TasksController@show       |            |
|        | GET|HEAD | projects/{projects}/tasks/{tasks}/edit | projects.tasks.edit    | App\Http\Controllers\TasksController@edit       |            |
|        | PUT      | projects/{projects}/tasks/{tasks}      | projects.tasks.update  | App\Http\Controllers\TasksController@update     |            |
|        | PATCH    | projects/{projects}/tasks/{tasks}      |                        | App\Http\Controllers\TasksController@update     |            |
|        | DELETE   | projects/{projects}/tasks/{tasks}      | projects.tasks.destroy | App\Http\Controllers\TasksController@destroy    |            |
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+

 

Setting Slug-based URLs

We’ve almost got our routes perfect however in their current state we’ll have URLs like /projects/1/tasks/2. It would be much better for our visitors if the model IDs were replaced with their respective slug fields instead. So we’d get for example /projects/my-first-project/tasks/buy-milk.

Open /app/Http/routes.php and drop the following in:

1
2
3
4
5
6
Route::bind('tasks', function($value, $route) {
	return App\Task::whereSlug($value)->first();
});
Route::bind('projects', function($value, $route) {
	return App\Project::whereSlug($value)->first();
});

the above will override the default behavior for the tasks and projects wildcards in php artisan routes.

 

Conclusion

Today we:

  • installed and configured Laravel
  • created two resources
  • set up our migrations
  • added some data seeds
  • configured our URL structure

We laid the groundwork for the next lesson by creating all the components required for the frontend to function. We now have data in our database and routes to hit. In the next lesson we’ll get started on the frontend of the site!

 

  • Ben

    Great Tutorial Thanks, one part I had issues with:

    php artisan create:controller ProjectsController;

    should be
    php artisan make:controller ProjectsController;

    • flynsarmy

      Thanks Ben. Fixed. This tutorial was an adaptation of one by the same name for Laravel 4, so there may be a few inconsistencies around. Keep letting me know and I’ll update away :)

  • Pete

    Shouldn’t you prefix static calls to Task and Project in Route::bind?:

    return AppTask::whereSlug($value)->first();

    return AppProject::whereSlug($value)->first();

    • Joonas Lieppinen

      Thanks for saving me ^_^

    • flynsarmy

      Fixed. Thanks

    • dermis

      why we use AppTask rather than AppTasks ? sorry for newbie question

  • Infacq

    where do i need to copy the files .env to?

    • flynsarmy

      Copy .env.example to .env in project root directory.

  • http://slick.pl/ slick

    Hi. Great article but you have an issue. Based on what you wrote in this article, seeding will fail and you will get ReflectionException. Before seeding you have to run composer dump-autoload and then seed (tested in L5). Anyway keep going! :)

    • flynsarmy

      Not sure if you’re seeing an older cached copy of this article but instructions to dump-autoload are already in it.


      composer dump-autoload
      php artisan db:seed
      # or
      php artisan migrate:refresh --seed

      • hannon

        [ReflectionException]
        Class DatabaseSeeder does not exist

        After php artisan dB:seed or php artisan migrate:refresh –seed

        any clue?¿
        Files exist : $

        • flynsarmy

          Have you called composer dump-autoload as per my above comment?

          • g

            It is the alternate:

            # or
            php artisan migrate:refresh –seed

            that desn’t work.

            • http://www.guddler.co.uk/ Martin White

              The article really needs to be clearer that the ‘composer dump-autoload’ is not part of the two options but must in fact be run before whichever option you choose.

              I just spent some time trying to work out why I was getting the exception and it was only when I read the comments down this far I realised that you ‘dump-autoload’ first, THEN choose to either db:seed OR migrate:refresh –seed.

              • flynsarmy

                I updated my post. Thanks for the comment

  • Jason

    Shouldn’t make:migration be migrate:make?

    • flynsarmy

      Nope.

    • UnixAgain

      L5 and L4 are different at this point.

  • kimball

    In Schema builder, why do you have
    $table->string(‘name’)->default(”)
    instead of
    $table->string(‘name’)->nullable()

    • flynsarmy

      Personal preference. I like to know my model attribute will always be a string. Null isn’t a string.

      • kimball

        Thanks. Great tutorial!

  • Jordy

    When changing to this route

    // Route::resource(‘tasks’, ‘TasksController’);
    Route::resource(‘projects.tasks’, ‘TasksController’);

    I am not able to go to /projects/ and am getting a NotFoundHttpException
    How to fix this issue

    • flynsarmy

      You still need these lines along with your ProjectsController.

      • Jordy

        Thanks alot that fixed it, I thought I had to comment projects away.

  • deepak

    when i run it at local http://127.0.0.1:84/demo/projects.

    i am getting this exception Object not found!

  • Reed

    Can anyone help me. when I try to run laravel new l5todo, I get this:
    Warning: ZipArchive::extractTo(): Invalid or uninitialized Zip object in C:User
    sreed.clarkeAppDataRoamingComposervendorlaravelinstallersrcNewCommand.p
    hp on line 99

    Warning: ZipArchive::close(): Invalid or uninitialized Zip object in C:Usersre
    ed.clarkeAppDataRoamingComposervendorlaravelinstallersrcNewCommand.php o
    n line 101

    • flynsarmy

      Sounds like a file permissions error.

  • arialleeve

    Nice.. Thanks for this.

  • Duncan Stokes

    If anyone is using PostgreSQL be aware that insertions with specific values into fields that have sequences attached do not change the last_value of the sequence. If the sequences are not correctly set you will experience key violations later in this tutorial (when you try adding Projects or Tasks).

    To fix this problem do the following.

    Add the following to the end of the run() function in database/migrations/seeds/ProjectsTableSeeder.php:

    if (DB::connection()->getName() == ‘pgsql’) {
    DB::select(‘SELECT setval(‘projects_id_seq’, ‘. DB::table(‘projects’)->select(DB::raw(‘MAX(id)’))->first()->max.’)’);
    }

    Add the following to the end of the run() function in database/migrations/seeds/TasksTableSeeder.php:

    if (DB::connection()->getName() == ‘pgsql’) {
    DB::select(‘SELECT setval(‘tasks_id_seq’, ‘. DB::table(‘tasks’)->select(DB::raw(‘MAX(id)’))->first()->max.’)’);
    }

  • up23

    For the tasks table, I got an SQL error on OSX with MySQL official install.

    I needed to change $table->text(‘description’)->default(”); to $table->text(‘description’);

    • flynsarmy

      What’s the error? I’m on OSX with MySQL. Works fine. Might have something to do with your default table engine?

      EDIT: It’s a known bug. See this comment for more details.

  • LPadmin

    Migration will not work for “tasks” table on…

    “$table->text(‘description’)->default(”);”

    Using mysql Ver 14.14 Distrib 5.6.2 the following error occurs…

    [PDOException]
    SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB/TEXT column ‘description’ can’t have a default value

    Seems to be a known bug reported on http://bugs.mysql.com/bug.php?id=21532

    Migration works if you remove “->default(”);”

    Not sure if this matters for the app, because I have just started working through the tutorial.

    • flynsarmy

      Thanks for the info! Very helpful for those experiencing similar issues. Removing ->default(”) should do the trick.

  • vacaflaca

    For the “[ReflectionException] Class DatabaseSeeder does not exist” problem.

    DatabaseSeeder.php should start with <?php

    It was not working for me without it

  • LPadmin

    The “–no-migration” tag should be added to avoid creating new migration tables when making new models. “php artisan make:model Project” and “php artisan make:model Task” will create two new migration tables without the tag, which isn’t necessary because you are making both tables in one migration prior to making the models.

    • Rick Gould

      On my version F:xamppphpphp.exe artisan -v
      Laravel Framework version 5.0.6
      The –no-migration option does not exist.
      Is there a fix?

  • Carlos Ballena

    I think it’s worth noting that when running `php artisan make:model modelName` it automatically creates the migration files for each model, i.e.: projects and tasks.

  • Thea Ganoe

    Where is the “whereSlug” function coming from? You used it in the routes:

    return AppProject::whereSlug($value)->first();

    But I can’t find this in the Laravel documentation or your git source.

    • flynsarmy

      Ahh, my bad. In part 4 I originally was making sluggable URLs but ran out of time and removed it. Guess I didn’t get everything. Will fix when I’m in front of my pc later.

      • Thea Ganoe

        ohh…I see…the Eloquent ORM, it will help if I read that. I saw in the git source where you were returning whereSlug() but I thought it was a custom function. Thanks, I get it now.

  • Sarang Bondre

    Am new to Laravel, I have follow all the tutorial except the routing
    part as i do not requite Nested resource. when I hit the URL on the
    browser still am not able to view even a blank page. but am getting 404
    Not found with the URL as localhost/projectname/public/controllername,
    can anyone please guide me what’s the problem.