I'm new to laravel. Help please.
Error in the console when trying to migrate:
Migrating: 2022_03_15_224441_add_permission_menu_table
Illuminate\Database\QueryException
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `permission_menu` add constraint `permission_menu_menu_id_foreign` foreign key (`menu_id`) re
ferences `menus` (`id`) on delete cascade)
at D:\DEV\OpenServer\domains\crm.loc\vendor\laravel\framework\src\Illuminate\Database\Connection.php:712
708▕ // If an exception occurs when attempting to run a query, we'll format the error
709▕ // message to include the bindings with SQL, which will make this exception a
710▕ // lot more helpful to the developer instead of just the database's errors.
711▕ catch (Exception $e) {
➜ 712▕ throw new QueryException(
713▕ $query, $this->prepareBindings($bindings), $e
714▕ );
715▕ }
716▕ }
1 D:\DEV\OpenServer\domains\crm.loc\vendor\laravel\framework\src\Illuminate\Database\Connection.php:501
PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint")
2 D:\DEV\OpenServer\domains\crm.loc\vendor\laravel\framework\src\Illuminate\Database\Connection.php:501
PDOStatement::execute()
Migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddPermissionMenuTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('permission_menu', function (Blueprint $table) {
//
$table->integer('permission_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->bigInteger('menu_id')->unsigned();
$table->foreign('menu_id')->references('id')->on('menus')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
// Schema::table('permission_menu', function (Blueprint $table) {
// $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
// $table->foreign('menu_id')->references('id')->on('menus')->onDelete('cascade');
// });
}
}
// the second migration file
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMenusTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('path');
$table->integer('parent');
$table->string('type');
$table->integer('sort_order')->default(100);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('menus');
}
}
Model File:
<?php
namespace App\Modules\Admin\Menu\Models;
use App\Modules\Admin\Role\Models\Permission;
use App\Modules\Admin\Users\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model
{Й
use HasFactory;
const MENU_TYPE_FRONT = 'front';
const MENU_TYPE_ADMIN = 'admin';
public function perms() {
return $this->belongsToMany(Permission::class, 'permission_menu');
}
public function scopeFrontMenu($query, $user) {
return $query->
where('type', self::MENU_TYPE_FRONT)->
whereHas('perms', function($q) use($user) {
$arr = collect($user->getMergedPermissions())->
map(function($item) {
return $item['id'];
}
);
$q->whereIn('id', $arr->toArray());
});
}
public function scopeAdminMenu($query, $user) {
return $query->where('type', self::MENU_TYPE_ADMIN);
}
public function scopeMenuByType($query, $type) {
return $query->where('type', $type)->orderBy('parent')->orderBy('sort_order');
}
}
I do not know what other details to describe to make it clearer what the problem is.
Please ask me if need what else.
I do not know what other details to describe to make it clearer what the problem is.
Please ask me if need what else.
I do not know what other details to describe to make it clearer what the problem is.
Please ask me if need what else.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddPermissionMenuTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('permission_menu', function (Blueprint $table) {
//
$table->bigInteger('permission_id')->unsigned();
Change integer to bigInteger on permission id
I decided so, for the permission_menus table I changed:
Schema::create('permission_menu', function (Blueprint $table) {
//
$table->integer('permission_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->bigInteger('menu_id')->unsigned();
$table->foreign('menu_id')->references('id')->on('menus')->onDelete('cascade');
});
And for the menus table:
Schema::create('menus', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->string('path');
$table->integer('parent');
$table->string('type');
$table->integer('sort_order')->default(100);
$table->timestamps();
});
And everything worked. Thanks!
I also tried to do this for the menus table left:
$table->increments('id');
And for the permission_menu table:
$table->integer('menu_id')->unsigned();
and everything worked too. It turns out to be a mismatch of two fields of two connected tables.
Related
I currently want to make an API that will get all the lessons by its module_id. These are currently my codes:
Module Migration Table:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateModulesTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up() {
Schema::create('modules', function (Blueprint $table) {
$table->id();
$table->string('module_name');
$table->bigInteger('created_by')->unsigned()->nullable();
$table->bigInteger('updated_by')->unsigned()->nullable();
$table->timestamps();
});
Schema::table('modules', function(Blueprint $table) {
$table->foreign('created_by')->references('id')->on('admins');
$table->foreign('updated_by')->references('id')->on('admins');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down() {
Schema::dropIfExists('modules');
}
}
Lesson Migration Table:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateLessonTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up() {
Schema::create('lesson', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->bigInteger('module_id')->unsigned();
$table->longText('content');
$table->bigInteger('created_by')->unsigned()->nullable();
$table->bigInteger('updated_by')->unsigned()->nullable();
$table->string('enabled')->nullable();
$table->string('position')->nullable();
$table->timestamps();
});
Schema::table('lesson', function(Blueprint $table) {
$table->foreign('module_id')->references('id')->on('modules');
$table->foreign('created_by')->references('id')->on('admins');
$table->foreign('updated_by')->references('id')->on('admins');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down() {
Schema::dropIfExists('lesson');
}
}
And this is the GetLessonByModule controller of that API I want to make (getting all the lessons by its module_id):
<?php
namespace App\Http\Controllers;
use App\Models\Lesson;
use App\Models\Modules;
use Illuminate\Http\Request;
class GetLessonByModuleController extends Controller {
public function index() {
$lessons = Lesson::all();
return response($lessons,200);
}
}
The module_id and the ID in the modules table are currently connected as seen in the migration tables. I just don't know how to compose it in my Controller. I also don't know if I should make a new model. Any kind of help/suggestion is deeply appreciated. Thanks in advance.
You can do
<?php
namespace App\Http\Controllers;
use App\Models\Lesson;
use App\Models\Modules;
use Illuminate\Http\Request;
class GetLessonByModuleController extends Controller {
public function index(int $module_id) {
$lessons = Lesson::where('module_id', '=', $module_id)->get();
return response($lessons,200);
}
}
In your api.php there should be definition of the route:
Route::get('lessons-by-module/{module_id}', [\App\Http\Controllers::class, 'index']);
If it works for you and want to do it better, you can go fancy with Laravel routing explicit binding: https://laravel.com/docs/8.x/routing#explicit-binding
I'm setting up a laravel project (I'm beginner) to manage customers (a customer has many contracts and a contract has many different products). And I want to implement a CRUD method and generate pdf but I have an issue at the beginning, when I migrate my database. (this is the beginning so I guess it will hard for me...)
I wrote all my migrations (customer + contracts + products) and migrate them
customer (clients):
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Clients extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->Increments('id');
$table->string('name');
$table->string('company');
$table->string('email', 50);
$table->string('phone', 15);
$table->string('adress1', 50);
$table->string('adress2', 50);
$table->string('adresse3', 50);
$table->string('pays', 20);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
schema::drop('clients');
}
}
Contracts (contrats)
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Contrats extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('contrats', function (Blueprint $table) {
$table->Increments('id');
/* $table->unsignedBigInteger('clients_name');
$table->foreign('name')->references('name')->on('Clients'); */
$table->string('id_dossier');
$table->string('id_contrat');
$table->string('id_bateau');
$table->date('startdate');
$table->index('startdate');
$table->date('enddate');
$table->index('enddate');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
schema::drop('contrats');
}
}
and products (produits)
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Produits extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('produits', function (Blueprint $table) {
$table->Increments('id');
$table->foreign('name');
$table->string('description', 20);
$table->double('price');
$table->double('taxes');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
schema::drop('produits');
}
}
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.03 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.02 seconds)
Migrating: 2019_10_15_131435_clients
Migrated: 2019_10_15_131435_clients (0.01 seconds)
Migrating: 2019_10_15_131454_contrats
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'name' doesn't exist in table (SQL: alter table contrats add constraint contrats_name_foreign foreign key (name) references Clients (name))
at
/Applications/MAMP/htdocs/test04/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
660| // If an exception occurs when attempting to run a query, we'll format the error
661| // message to include the bindings with SQL, which will make this exception a
662| // lot more helpful to the developer instead of just the database's errors.
663| catch (Exception $e) {
664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|
Exception trace:
1 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'name' doesn't exist in table")
/Applications/MAMP/htdocs/test04/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
2 PDOStatement::execute()
/Applications/MAMP/htdocs/test04/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
Please use the argument -v to see more details.
I expect to get a good migration to going ahead with this project
Thanks in advance for your help, cheers.
The foreign key column format must match the format of the column it's referencing on the other table, so instead of unsignedBigInteger, it should be string
Schema::create('contrats', function (Blueprint $table) {
$table->Increments('id');
/* $table->unsignedBigInteger('clients_name'); */
$table->string('name');
$table->foreign('name')->references('name')->on('clients');
$table->string('id_dossier');
$table->string('id_contrat');
$table->string('id_bateau');
$table->date('startdate');
$table->index('startdate');
$table->date('enddate');
$table->index('enddate');
$table->timestamps();
});
Tho it's highly recommended that you reference the primary key id instead
Proper way
Eloquent will make use of naming conventions to make proper relationships with less explicit code
clients
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateClientsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('company');
$table->string('email', 50);
$table->string('phone', 15);
$table->string('adress1', 50);
$table->string('adress2', 50);
$table->string('adresse3', 50);
$table->string('pays', 20);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('clients');
}
}
contrats
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateContratsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('contrats', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('client_id');
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$table->string('id_dossier');
$table->string('id_contrat');
$table->string('id_bateau');
$table->date('startdate');
$table->index('startdate');
$table->date('enddate');
$table->index('enddate');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('contrats');
}
}
produits
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProduitsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('produits', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('client_id');
$table->foreign('client_id')->references('id')->on('clients');
$table->string('description', 20);
$table->double('price');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('produits');
}
}
Hope this helps
Bon Courage :)
write your function up for contrats migration like this
Schema::create('contrats', function (Blueprint $table) {
$table->Increments('id');
$table->string('id_dossier');
$table->string('id_contrat');
$table->string('id_bateau');
$table->date('startdate')->index();
$table->date('enddate')->index();
$table->timestamps();
});
can someone please help me with this one? I'm new to Laravel and when I try to do:
php artisan migrate
I get the error:
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table posts add constraint posts_author_id_foreign foreign key (author_id) references users (id) on delete restrict)
and this is the post table content:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('author_id')->unsigned();
$table->foreign('author_id')->references('id')->on('users')->onDelete('restrict');
$table->string('title');
$table->string('slug')->unique();
$table->text('excerpt');
$table->text('body');
$table->string('image')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
I have noticed that when I comment this line:
$table->foreign('author_id')->references('id')->on('users')->onDelete('restrict');
the error is gone, so I guess the problem is in that line. So, can someone please tell me what will be the correct syntax or how to fix it?
The column data type must be the same on both tables for the foreign key to work. By default, the users id column is:
$table->bigIncrements('id');
Therefore, you need to use bigInteger for your posts migration:
$table->bigInteger('author_id')->unsigned();
Try to change the foreign ko to unsignedInteger
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('author_id');
$table->foreign('author_id')->references('id')->on('users')->onDelete('restrict');
$table->string('title');
$table->string('slug')->unique();
$table->text('excerpt');
$table->text('body');
$table->string('image')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
I'm trying to create a table to hold photos and link it to the ad (property id).
I'm getting this error
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
These are my migration files
2018_02_14_191609_create_property_adverts_table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePropertyAdvertsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('property_adverts', function (Blueprint $table) {
$table->increments('id');
$table->string('address');
$table->string('county');
$table->string('town');
$table->string('type');
$table->string('rent');
$table->string('date');
$table->string('bedrooms');
$table->string('bathrooms');
$table->string('furnished');
$table->longText('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('property_adverts');
}
}
2018_02_18_165845_create_property_advert_photos_table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePropertyAdvertPhotosTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('property_advert_photos', function (Blueprint $table) {
$table->increments('id');
$table->integer('propertyadvert_id')->nullable();
$table->foreign('propertyadvert_id')->references('id')->on('property_adverts');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('property_advert_photos');
}
}
So the
Make it unsigned because you're using increments(). And move FK constraint part to a separate closure:
public function up()
{
Schema::create('property_advert_photos', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('propertyadvert_id')->nullable();
$table->timestamps();
});
Schema::table('property_advert_photos', function (Blueprint $table) {
$table->foreign('propertyadvert_id')->references('id')->on('property_adverts');
});
}
I have a problem with dropping some foreign keys from my Laravel application. The problem is when I am trying to rollback the migration:
php artisan migrate:rollback
I don't know why I have errors in the console:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'role_user_user_id_foreign'; check that column/key exists (SQL: alter table role_user drop foreign key role_user_user_id_foreign)
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'role_user_user_id_foreign'; check that column/key exists
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'role_user_user_id_foreign'; check that column/key exists
Below I'm showing my migration class:
class UpdateRoleUserTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
schema::table('role_user',function(Blueprint $table){
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('role_id')->references('id')->on('roles');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign('role_user_user_id_foreign');
$table->dropForeign('role_user_role_id_foreign');
});
}
}
My table in the database has been created by migration class:
class CreateRoleUserTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('role_id')->unsigned();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('role_user');
}
}
In all of the >4.0 versions of Laravel, it allows placing column names into an array, which it will then resolve on its own. I tried to find accompanying docs, but they seem to have left it out.
In your update migration, try this:
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['role_id']);
});
I just had this issue and the problem was due to the fact that $table->dropForeign([column_name]); drops the index and not the column itself. The solution is in the down function drop the index in one block and then drop the actual column in a separate block. They have to be dropped in separate blocks because of something to do with not being able to drop the key in the same connection as where the column is being dropped.
So the down function should look like this:
public function down() {
// drop the keys
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['role_id']);
});
// drop the actual columns
Schema::table('role_user', function (Blueprint $table) {
$table->dropColumn('user_id');
$table->dropColumn('role_id');
});
}
now you can run php artisan migrate to run the up function and php artisan migrate:rollback to run the down command and the error no longer shows.
I have modified your code below.
Add the onDelete() and onUpdate() to your code.
public function up()
{
Schema::table('role_user',function(Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('CASCADE')->onUpdate('CASCADE');
});
}
public function down() {
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['role_id']);
});
}
In Laravel 9.x, you do not need to specify a separate deletion of foreign keys.
<?php
use App\Models\Question;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up(): void
{
Schema::create('answers', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Question::class, 'question_id');
$table->text('correctly');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down(): void
{
Schema::dropIfExists('answers');
}
};