Make column not nullable in a Laravel 5 migration - php

I have found this question very similar to mine Make column not nullable in a Laravel migration though it is almost 3 years old and it surely does not belong to Laravel 5
My problem is that I have a migration which in the up function it modifies a column to make it nullable.
Now, in the down function I want to make it not nullable again.
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('mytable', function(Blueprint $table) {
$table->string('mycolumn')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('mytable', function(Blueprint $table) {
/* THIS IS WHAT I WOULD EXPECT TO DO
THOUGH OF COURSE THE FUNCTION notNullable DOES NOT WORK */
$table->string('mycolumn')->notNullable()->change();
});
}
I could achieve that using raw SQL, but I would like to do it using Laravel methods if it is possible... but I couldn't find it, probably it hasn't been implemented it in the version 5 either.

To reset it back to not nullable. You may try this.
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('mytable', function(Blueprint $table) {
$table->string('mycolumn')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('mytable', function(Blueprint $table) {
/* By default it's NOT NULL */
$table->string('mycolumn')->nullable(false)->change(); // <--- here
});
}

By default its NOT NULL, so you should try this.
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('mytable', function(Blueprint $table) {
$table->string('mycolumn')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('mytable', function(Blueprint $table) {
/* By default it's NOT NULL */
$table->string('mycolumn')->change();
});
}

Related

Laravel 8 - Change existing migration

I am developing on Laravel Framework 8.33.1 and have the following migration on my local environment and also in production.
class CreateCompanyTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('company', function (Blueprint $table) {
$table->id();
$table->integer('company_id');
$table->integer('messageId');
$table->string('url');
$table->timestamps();
/**
New table:
$table->id();
$table->integer('company_id')->nullable($value = true);
$table->integer('messageId');
$table->integer('people_id')->nullable($value = true);
$table->string('url')->nullable($value = true);
$table->timestamps();
*/
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('company');
}
}
I would like to change the migration with the following adapted fields:
$table->id();
$table->integer('company_id')->nullable($value = true);
$table->integer('messageId');
$table->integer('people_id')->nullable($value = true);
$table->string('url')->nullable($value = true);
$table->timestamps();
As I am using the current migration in production I do not want to lose data.
I simply tried to modify the migration file with my new table definition, but I get:
> php artisan migrate
Nothing to migrate.
Any suggestions how to change the migration properly in laravel?
I appreciate your replies!
To modify an existing table, create a new migration.
php artisan make:migration alter_company_table
class AlterCompanyTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('company', function (Blueprint $table) {
$table->integer('company_id')->nullable()->change();
$table->integer('people_id')->nullable();
$table->string('url')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('company', function (Blueprint $table) {
$table->integer('company_id')->nullable(false)->change();
$table->dropColumn('people_id');
$table->string('url')->nullable(false)->change();
});
}
}
If you don't mind losing data and you are in development mode, you can do php artisan migrate:rollback and after execute: php artisan migrate. So your migrations works correctly. You can to read more here.
Now, if you just want to add new tables and modify others in you database, you should make another migration. But before this, you should to install doctrine/dbal to be able to modify your tables correctly, or else, it will give you many errors. After, add this lines in your config/database.php
use Illuminate\Database\DBAL\TimestampType;
'dbal' => [
'types' => [
'timestamp' => TimestampType::class,
],
],
Now you can do: php artisan make:migration add_new_tables_to_company and your file in database/migrations.
class AlterCompanyTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('company', function (Blueprint $table) {
$table->integer('company_id')->nullable()->change();
$table->integer('people_id')->nullable();
$table->string('url')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('company', function (Blueprint $table) {
$table->integer('company_id')->nullable(false)->change();
$table->dropColumn('people_id');
$table->string('url')->nullable(false)->change();
});
}
}

Create a migration for adding 2 instances

I've got a task to create a migration for adding 2 instances of WorkRoom into database, I've already create a migration when created the Model and added to table 3 fields, I don't understand what migration should I do now.
class CreateWorkRoomsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('work_room', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
$table->integer('building')->nullable();
$table->integer('floor')->nullable();
$table->integer('office_number')->nullable();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('work_room');

Changing column of enum through DB::statement

I have a column of type enum I want to change it to type varchar but it brings an error that the sql syntax is not correct, please what's the solution
This is the table creation migration code
class CreateCurrenciesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
$symbols = ['₦', '$', '£'];
Schema::create('currencies', function (Blueprint $table) use($symbols) {
$table->increments('id');
$table->string('name', 50);
$table->string('code', 5);
$table->enum('symbol', $symbols);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
Schema::dropIfExists('currencies');
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
This is the migration code I want to use to change the column type but keep on getting an error
class AddSymbolToImagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('images', function (Blueprint $table) {
DB::statement('ALTER TABLE images ALTER COLUMN symbol VARCHAR(200)');
// $table->text('symbol')->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('images', function (Blueprint $table) {
// $symbols = ['₦', '$', '£'];
// $table->enum('symbol', $symbols)->change();
DB::statement('ALTER TABLE images ALTER COLUMN symbol enum ');
});
}
}
This does not really have anything to do with Laravel and you should also include the error next time.
To change the column type you can use MODIFY or MODIFY COLUMN.
So this would work:
ALTER TABLE images MODIFY symbol varchar(200)
There is a few to change the column name as you can see in the docs here: https://dev.mysql.com/doc/refman/8.0/en/alter-table.html#alter-table-redefine-column

Laravel eloquent inverse one to many returns empty

I have following MySQL table structure:
posts table:
posts: {id(PK), title, content, slug, date, writer_id, created_at, updated_at}
writers table:
writers: {id(PK), name, type, created_at, updated_at}
Migration classes in database/migrations directory:
posts table:
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('content');
$table->string('slug');
$table->date('date');
$table->date('modified_date');
$table->integer('publish');
$table->integer('trash');
$table->integer('wid');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
Changed the type of column:
class RenamePostColumn extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('posts', function ($table) {
$table->longText('content')->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('posts', function ($table) {
$table->longText('content')->change();
});
}
}
Renamed a column:
class RenamePostColumnWid extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('posts', function ($table) {
$table->renameColumn('wid', 'writer_id')->change();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('posts', function ($table) {
$table->renameColumn('writer_id', 'wid')->change();
});
}
}
writers table:
class CreateWritersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('writers', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('name');
$table->string('type');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('writers');
}
}
Following are my modals in app directory:
Post.php:
class Post extends Model
{
public function writer()
{
return $this->belongsTo(Writer::class);
}
}
Writer.php:
class Writer extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
Now I have created a repository class in app/Repositories directory.
PostRepository.php:
class PostRepository
{
public function forSingle($slug)
{
return Post::whereSlug($slug)->get();
}
}
I debugged above query with:
return Post::whereSlug($slug)->toSql();
It returns the following query:
select * from `posts` where `slug` = ?
My routes are in routes/web.php file.
web.php:
Route::get('/post/{slug}', 'PostController#single');
Finally I have my controller in app/Http/Controllers directory.
PostController.php:
use App\Repositories\PostRepository;
class PostController extends Controller
{
protected $post;
function __construct(PostRepository $post)
{
$this->post = $post;
}
public function single($slug)
{
return view('single', [
'post' => $this->post->forSingle($slug)
]);
}
}
I have rendered a view file as follows:
single.blade.php
#if (count($post) > 0)
#foreach ($post as $blog)
<h3>{{$blog->title}}</h3>
<p>{!!$blog->content!!}</p>
#foreach($blog->writer as $writer)
<span>{{$writer->name}}</span>
#endforeach
#endforeach
#endif
Here is my problem. Everything works fine until I add
#foreach($blog->writer as $writer)
<span>{{$writer->name}}</span>
#endforeach
This section gives me error saying:
Trying to get property of non-object (View:\resources\views\single.blade.php)
I have printed the $blog in view by {{$blog}}. It does not return any writer attribute. Can you help me with this?
PS: I have not defined primary key foreign key relationships in MySQL database tables.
When it is inverse one to many eloquent, we need to explicitly tell that we need the other table data. Changing following in the PostRepository.php fixed the issue.
class PostRepository
{
public function forSingle($slug)
{
return Post::whereSlug($slug)->with('writer')->get();
}
}
You have to define foreign key or index
In my projects, I use index relation
so what you have to do is to add index relation in writer_id like this
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('content');
$table->string('slug');
$table->date('date');
$table->date('modified_date');
$table->integer('publish');
$table->integer('trash');
$table->integer('wid')->unsigned()->index(); // add this
$table->timestamps();
});
}
Please try the previous

Laravel 4 - one migrations in workbench can be rolled back, while others cannot

I have two types of workbench migrations: creating regular tables and creating pivot tables for Many-to-Many relationships.
Sample of regular migration:
<?php
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function(\Illuminate\Database\Schema\Blueprint $table)
{
$table->increments('id')->unsigned();
$table->string('login')->unique();
$table->string('username')->unique();
$table->string('password');
$table->string('email');
$table->boolean('active')->default(true);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
Above migration can be rolled back
<?php
use Illuminate\Database\Migrations\Migration;
class CreatePivotRoleUser extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('role_user', function(\Illuminate\Database\Schema\Blueprint $table)
{
$table->integer('role_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->primary(['role_id', 'user_id']);
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('role_user');
}
}
While this cannot, because it gives
"Class 'CreatePivotPermissionRole' not found"
error.
How to fix it?
Your code looks correct.
If CreatePivotPermissionRole is not found, it means it had been deleted before. Check the content of all your down() methods, there must be something wrong there.

Categories