1

I am creating a to do list using laravel, and I have a table with the columns below:

'title', 'description', 'completed', 'id'

The 'completed' column is set automatically whenever I add a new task to my table, its default value is 0 and it's being coded like this:

$table->boolean('completed')->default(0);

This column works perfectly fine, but when I try to give 'description' a default value (by leaving an empty input for description), it gives me a 'Integrity constraint violation: 1048 Column 'description' cannot be null' error.

The code I have written for 'description' column is the code below:

$table->string('description')->default('-');

I tried the text() data type, but it gives me the same error.

I also tried using nullable() for this column, but the default value, '-' , doesn't get added to the column and it returns a emtpy value.

The form I'm using to add the values looks like this:

<form action="/create" class="panel" method="post">
    @csrf
    <input name="title" type="text" class="title">
    <textarea name="description" class="title"></textarea>
    <input type="submit" class="submit">
</form>

My controller store method:

public function createTask(validation $request){
        $userId = auth()->id();
        $request['user_id'] = $userId;
        Task::create($request->all());
        return redirect()->route('showList');
    }

and the table create statement:

CREATE TABLE `tasks` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
 `completed` tinyint(1) NOT NULL DEFAULT 0,
 `user_id` bigint(20) unsigned NOT NULL,
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 `description` text COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT ' ',
 PRIMARY KEY (`id`),
 KEY `tasks_user_id_foreign` (`user_id`),
 CONSTRAINT `tasks_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
NavidMnzh
  • 169
  • 3
  • 17
  • Please share `show create table` statement result of your table (please edit the question, not post as a comment) – Ersoy Jul 04 '20 at 20:52
  • Have you tried an empty string? Like `" "`. Also are you altering the table or re-creating it each time? If you are altering it with migration then you need to append `->change();` to those definitions. – user3647971 Jul 04 '20 at 20:53
  • 3
    Can you please share the store method ? just to make sure you're not adding the description value manually as an empty string – Hassan Azzam Jul 04 '20 at 20:54
  • @HassanAzzam of course, I just edited the question now – NavidMnzh Jul 05 '20 at 06:39
  • @Ersoy Sure, just added the create statement now :) – NavidMnzh Jul 05 '20 at 06:39
  • @user3647971 I tried the both ways. In the first sequence I created a new migration, just to add the column to the table without loosing any data. And in the second sequence I added the $table->text('description') to my main migration and used migrate:refresh statement to add the new column. – NavidMnzh Jul 05 '20 at 06:42

1 Answers1

1

After seeing the create table statement and your store function. It looks like it is more likely that your store function is the problem here. Try this:

use Illuminate\Support\Facades\Auth;

public function createTask(Request $request){
    $user = Auth::user();//get the user model
    $request->validate([//validate that the data is according to limitations
        'title' => 'required|max:255',
        'description' => 'max:1000',
    ]);
    $task = new Task;  //create a new instance of Task
    //fill in the data
    $task->title = $request->input('title');
    if(!empty($request->input('description')){
        $task->description = $request->input('description');
    }
    $task->user_id = $user->id;
    $task->save();//save it
    
    return redirect()->route('showList');
}

In your code you use mass assignment described in detail here

For mass assignment you should define your database fields to be mass assignable in your Model with protected $fillable = ['title','description','user_id'];

Your problem in specific tho is that laravel sets empty inputs to null according to answer in this question: Mass assignment won't handle Null input even when default is set on migration.Any solution to this?

You should always validate the user input and laravel provides robust tools for doing just that: https://laravel.com/docs/7.x/validation

You also might wanna consider using laravels built-in default values or at least check if they are intervening with the data :How to set the default value of an attribute on a Laravel model

user3647971
  • 1,069
  • 1
  • 6
  • 13
  • 1
    Thanks a lot! your answer solved my problem completely. The problem was that the store function was passing the empty values as "null" to the description column, and the only place that default() works, is the time that no value is passed to the database. Thanks again! – NavidMnzh Jul 06 '20 at 06:41