Insert new column from existed column in Laravel - mysql

I had data in my database. Now i want to add a column
$table->string('md5_url');
It work. But now i want to add unique index on md5_url. But it don't work because rows in my database have same value(=default value).
So what should i do if i want to create new column form existed column(such as i want md5_url = md5(url_column_value)
I have known 2 way to set default value.
$table->string('md5_url')->default($value);
and
$stack_links = DB::table('stack_links')->update(['md5_url' => $value]);
but 2 above way, the $value is fix, how to make it flexible (diffirent in each row) so that i can add unique index after that.
Note: i don't want to create model StackLink so don't try this way:
$stack_links = StackLink::get();
foreach($stack_links as $stack_link) {
$stack_link->md5_url = md5($stack_link->url);
$stack_link->save();
}
Update: have try
$table->string('md5_url')->default(uniqid());
but it don't work too.The result is

Change your column property like this:
$table->string('md5_url')->nullable();
It's okay now!

Try IGNORE to set unique index to add new column.
public function up()
{
Schema::table('listings', function (Blueprint $table) {
$table->string('md5_url');
});
DB::statement('ALTER IGNORE TABLE listings ADD UNIQUE INDEX myindex (md5_url)');
}
public function down()
{
Schema::table('listings', function (Blueprint $table) {
$table->dropColumn('md5_url');
});
}

Related

Database columns exclusive or relationship

In my project it would come in handy to put two boolean columns of a table in an 'exclusice or' like relationship, is that somehow possible in laravel? FYI: I use mysql as a driver if that matters.
A CHECK constraint can be used to check specific requirements for a table row. This logic be placed inside the up function of a migration.
public function up ()
{
Schema::create('order', function (Blueprint $table) {
$table->increments('id');
$table->boolean('in_transit');
$table->boolean('is_delivered');
});
// Add the constraint
DB::statement('ALTER TABLE order ADD CONSTRAINT chk_delivery CHECK ((in_transit AND NOT is_delivered) OR (is_delivered AND NOT in_transit));');
}

Switching primary key from id to a combination of values in a pivot table

I am trying to switch the primary key of a pivot table from "id" to a combination of two values using a migration inside a laravel project. My up method looks as follows and it works fine:
public function up() {
Schema::table('gallery_image', function (Blueprint $table) {
$table->dropColumn('id');
$table->primary(['image_id', 'gallery_id']);
});
}
However, when I declare the down method in order to undo the above changes like this:
public function down() {
Schema::table('gallery_image', function (Blueprint $table) {
$table->dropPrimary(['image_id', 'gallery_id']);
$table->increments('id');
});
It first gives me an error 1068 Multiple primary key defined, which tells me that the first line in the down method does not work as intended, but when I just run the dropPrimary line, it gives me an error errno: 150 - Foreign key constraint is incorrectly formed.
I am not quite sure as to what I am doing incorrectly.
You could try the following
$table->dropPrimary(); // without the parameters.
Or you could wrap the closure in the down method as following:
DB::statement('SET FOREIGN_KEY_CHECKS=0');
$table->dropPrimary(['image_id', 'gallery_id']);
$table->increments('id');
DB::statement('SET FOREIGN_KEY_CHECKS=1');
or
Schema::disableForeignKeyConstraints();
//code
Schema::enableForeignKeyConstraints();
This will temporarily set the FK Checks off, and turn it back on afterwards.
EDIT
You could look into https://laravel.com/docs/6.0/migrations#dropping-indexes and try out the various functions!

Laravel with MySQL relationship foreign key not appearing

I just want to ask if it is normal that, in Laravel, everytime I use foreign key constraint the constraint icon key is not showing inside MYSQL? Also, inside index is not showing.
Note: this is just to clarify if I am doing it the wrong way. Please help amend. Thanks.
This is the image
Schema:
public function up()
{
Schema::create('subjects', function (Blueprint $table) {
$table->increments('id');
$table->string('subject_name');
$table->integer('Level_id')->unsigned()->nullable();
$table->timestamps();
});
}
When you define a Relationship in Laravel, like this:
class Comment extends Model
{
/**
* Get the original post from where the comment is from.
*/
public function post()
{
return $this->belongsTo('App\Post');
}
}
Laravel does not define a relationship constrain in your database by default. This is not how Laravel handle relationships.
To specify one, you need to add the constrain in the migration, like the documentation states:
Schema::table('comments', function (Blueprint $table) {
$table->unsignedInteger('post_id');
// Check this part:
$table->foreign('post_id')->references('id')->on('posts');
});
Update:
I think than the actual version of the docs (L5.6) has removed this part but in the L5.0 you can see it:
Check this part:
Let's imagine that a User model might have one Phone. We can
define this relation in Eloquent:
class User extends Model {
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 it
using Eloquent's dynamic properties:
$phone = User::find(1)->phone;
The SQL performed by this statement will be as follows:
select * from users where id = 1
select * from phones where user_id = 1
Take note that Eloquent assumes the foreign key of the relationship based on the model name. In this case, Phone model is assumed to use a
user_id foreign key.
As you can see in bold, this is how Laravel manages to get the relationship information.
Also, check this answer.
From the documentation:
Laravel also provides support for creating foreign key constraints,
which are used to force referential integrity at the database level.
For example, let's define a user_id column on the posts table that
references the id column on a users table:
An example using the default users table and a new posts table, defined:
Schema::table('posts', function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
From this, you can see that $table->unsignedInteger('user_id'); is the definition of the column in the table posts,
Then, we need define the relationship of user_id to users: $table->foreign('user_id')->references('id')->on('users'); defines the re

Laravel nullable migration with foreign key

I have items table with supplier_id column and the foreign key to that column. The column is not nullable and I want to make it nullable. So the up() method works:
$table->integer('supplier_id')->unsigned()->nullable()->change();
But I can't get down() method to work, always get the error:
Cannot change column 'supplier_id': used in a foreign key constraint 'items_supplier_id_foreign'
Latest attempt:
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('items', function (Blueprint $table) {
$table->dropForeign(['supplier_id']);
$table->integer('supplier_id')->unsigned()->nullable(false)->change();
$table->foreign('supplier_id')->references('id')->on('suppliers');
});
}
Any suggestions? I'm using Laravel 5.4
#apokryfos is right. See here
Before any changes are made to your table, it’s important to briefly go over what data can (and cannot) be specified within an existing column that you wish to alter to NOT NULL, ensuring that no row is allowed to have a NULL value in that column.
At first, you need fill all nullable values using seeds and then modify column. Or your can drop supplier_id and than using default() method fill all rows in the table.
Only dropping foreign key constraint is not enough if you're changing the column next, you have to also drop its index. Below is the migration down function
Schema::table('users', function (Blueprint $table) {
$table->dropForeign('users_role_id_foreign');
$table->dropIndex('users_role_id_foreign');
});
// Conflict with change on same Blueprint instance (strange)
Schema::table('users', function (Blueprint $table) {
$table->integer('role_id')->change();
});
Credits: Github

Laravel 5 migration - foreign key constraint fails

I'm having problems with running my migration. I have a mysql database with some tables. The specific table is product_blender. Some fields in the table are like this:
id (PK)
area_id (FK)
inhabitants (varchar)
heating_type_id (FK)
...
Now I would like to create another table called installateur_types. The table needs to contain a PK and a varchar field. I would also like to create a FK in product_blender table to the id of my newly created tabel.
This is what I've done:
Created migration to create a table:
public function up()
{
Schema::create('installateur_types', function(Blueprint $table)
{
$table->increments('id');
$table->string('type');
});
}
public function down()
{
Schema::drop('installateur_types');
}
Run the migration, this was successful. Table was created with correct fields.
Then I've created the migration to add a FK field to the product_blender table.
public function up()
{
Schema::table('product_blenders', function ($table) {
$table->integer('installateurtype_id')->unsigned();
$table->foreign('installateurtype_id')->references('id')->on('installateur_types')->onDelete('cascade');
});
}
public function down()
{
//
}
When I now run the migration I get the following error:
What am I doing wrong?
If your products_blender table is not empty, then when you add a new column which is not null (which is the default for eloquent), it will be assuming some default value on its own. This value may not be available in the table this new column is referring to, causing the foreign key constraint to fail.
One of the way to get around this is to give a default value to the new column or just make it nullable.
$table->integer('installateurtype_id')->unsigned()->nullable();
$table->foreign('installateurtype_id')->references('id')->on('installateur_types')->onDelete('cascade');
There is one other solution, which turns off this checks, which can be done using DB::statement('SET FOREIGN_KEY_CHECKS=0;'). Then again turn that one for future with DB::statement('SET FOREIGN_KEY_CHECKS=1;'). In you code you can do something like
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$table->integer('installateurtype_id')->unsigned();
$table->foreign('installateurtype_id')->references('id')->on('installateur_types')->onDelete('cascade');
DB::statement('SET FOREIGN_KEY_CHECKS=1;');