How to delete a foreign key constraint in Laravel? - php

I'm working on a project in which I' m adding data in two tables User & Registration in one form like this
public function storeStudent(Request $request)
{
$created_user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'parent_id' => $request->parent_id,
'role_id' => $request->role_id,
'gender'=> $request->gender,
'date_of_birth'=> $request->date_of_birth,
'cnic'=>$request->cnic,
'religion'=>$request->religion,
'skills'=>$request->skills,
'physical'=>$request->physical,
'emergency_name'=>$request->emergency_name,
'phone_no'=>$request->phone_no,
'medical_info'=>$request->medical_info,
'family_dr'=>$request->family_dr,
'address'=>$request->address,
]);
Registration::create([
//reg_id is id for registration table
'user_id' => $created_user->id,
'class_id' => $request->class_id,
'section_id' => $request->section_id,
]);
Now I want to delete the data I'm bad with syntaxes. I don't know what should I do to delete the data I m trying
public function destroy(Request $request)
{
$user = User::findOrFail($request->user_id);
$user->delete();
$registration=Registration::findOrFail($request->user_id);
$registration->delete();
return back();
}
Table for Registration is
Schema::create('registrations', function (Blueprint $table) {
$table->increments('reg_id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('class_id')->unsigned();
$table->foreign('class_id')->references('id')->on('classses');
$table->integer('section_id')->unsigned();
$table->foreign('section_id')->references('id')->on('sections');
$table->timestamps();
});
But it gives me error
Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`jurs1`.`registrations`, CONSTRAINT `registrations_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) (SQL: delete from `users` where `id` = 10)
Please help me in this case.

$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Using ->onDelete('cascade') works for me :)

You cannot delete a record from the user table because you have a relationship with the registrations table (registrations_user_id_foreign). In order to delete a user record, you first have to delete all the records for that user from the registrations table. You have two ways:
Modify the relationships of your registrations table
$table->foreign('user_id')->references ('id')->on('users')->onDelete ('cascade');
With this, when you do a
$user->delete()
the records of that user will be deleted from the registrations table too.
Or second way:
Delete user after deleting registrations records
$user->registrations()->delete();
$user->delete();

In Laravel 9 you can use detach method:
$user->registrations()->detach();
$user->delete();

Related

Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into `users`

I have a question and the answers i have been getting are not really helping me.
So I have been trying to basically create a Profiles table for each users. I followed through the rules for One to One relationship but i keep getting this error
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into users (name, email, password, admin, updated_at, created_at) values (Darlington Okorie, darlingtonokoriec#gmail.com, $2y$10$Ob161LW8sbbv5uDv9VVbienlmW.DWXVDK3wdfC0I0NlnOrg1Jx/a2, 1, 2019-12-23 17:41:30, 2019-12-23 17:41:30))
Heres the code i wrote in my UsersTableSeeder
public function run()
{
$user = App\User::create([
'name' => 'Darlington Okorie',
'email' => 'darlingtonokoriec#gmail.com',
'password' => bcrypt('password'),
'admin' => 1
]);
App/Profile::create([
'user_id' => $user->id,
'avatar' => 'uploads/avatar/img.png',
'about' => 'Great at writing. Better at blogging',
'facebook' => 'facebook.com',
'youtube' => 'youtube.com'
]);
}
And i had also defined user_id in my create_users_table
public function up()
{
Schema::create('users', function (Blueprint $table) {
Schema::dropIfExists('users');
$table->bigIncrements('id');
$table->string('name');
$table->string('user_id');
$table->string('email')->unique();
$table->boolean('admin')->default(0);
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
And defined the user_id in my create_profiles_table
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('avatar');
$table->integer('user_id');
$table->text('about');
$table->string('facebook');
$table->string('youtube');
$table->timestamps();
});
}
What could be wrong?
I faced this kind of issue as well.
My Case, I forgot to write the field in fillable.
protected $fillable = [
'name',
];
After writing the field in $fillable. My Issue was solved.
This is an issue with your users migration, and not the profiles migration. Your migration has this line:
Schema::create('users', function (Blueprint $table) {
...
$table->string('user_id'); // This one
Which is creating a non-null varchar column called user_id. In your Seed file, you're not setting that, and null is not allowed. Add and configure the following line below:
$user = App\User::create([
'name' => 'Darlington Okorie',
'email' => 'darlingtonokoriec#gmail.com',
'password' => bcrypt('password'),
'admin' => 1,
'user_id' => 'SomeRandomString' // Add this, set to whatever is logical.
]);
Alternatively, set nullable() on your users migration:
Schema::create('users', function (Blueprint $table) {
$table->string('user_id')->nullable();
Honestly, unless you need a separate identifier for each User, your users table likely doesn't need a user_id, and you can remove it from the migration completely.
Edit: I'm really not sure who downvoted, but read the error message:
Field 'user_id' doesn't have a default value (SQL: insert into users ...)
When this error is encountered, the query is trying to insert into the users table, not the profiles one. Since users.user_id doesn't have a default value, nor does it allow null, the error is being thrown. The 3 alternatives above provide a solution to this.
The error has nothing to do with the User or Profile models, as there is an issue with the migration itself.
General error: 1364 Field 'user_id' doesn't have a default value
what this error is saying is that you have a column in the table that you didn't pass
a value for in your form...In your case you didn't pass a value for the field
user_id.I guess what you are trying to implement is that you want to give the primary
key a name.so the fix should be to rename the column $table->bigIncrements('id'); to
$table->bigIncrements('user_id'); and delete the $table->string('user_id');
You can set 'user_id' to allow null from db.
I don't how your relationship is set up but try to make some changes as mentioned below. REMOVE THE use_id from users table. You don't need that column. Or Just rename it to USER_CODE for example make it nullable if it is not a mandatory column $table->string('user_id')->nullable();
To be honest I don't see the purpose of having user_id column in usrs table
// Profiles Migration:
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
...
$table->unsignedInteger('user_id');
....
$table->foreign('user_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
});
}
// Profile.php Model
public function user()
{
return $this->belongsTo('App\User');
}
// User.php Model
public function user()
{
return $this->hasOne('App\Profile');
}
// Inside your Controller
$user = new App\User;
$user->name = 'Darlington Okorie';
$user->email = 'darlingtonokoriec#gmail.com';
$user->password = bcrypt('password');
$user->admin => 1;
if($user->save()) {
$userID = $user->id;
$profile = new App/Profile;
$profile->user_id = $userID;
$profile->avatar = 'uploads/avatar/img.png';
$profile->about = 'Great at writing. Better at blogging';
$profile->facebook = 'facebook.com';
$profile->youtube = 'youtube.com';
$profile->save();
}

Unable to Add Username to Post Author

I'm trying to insert the username for the author from the users table into the posts table, but it's not letting me. I'm using Backpack for my CRUD, and I'm not sure what I'm doing wrong. I'm also not sure as to why the ID is appearing for the username instead of the username itself, as the correct username(s) are appearing in the select box. I am getting the following error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails (idf.posts,
CONSTRAINT posts_author_foreign FOREIGN KEY (author) REFERENCES
users (username)) (SQL: insert into posts (title, content,
author, updated_at, created_at) values (aasdasd, asdasda,
1, 2018-12-24 04:25:23, 2018-12-24 04:25:23))
I'm running SQL 8, Laravel 5.7, and PHP 7.1.19. So far I've tried clearing the cache via the artisan command and performing a migrate:refresh (which is fine because I have no legitimate data).
In App\Models\Post:
protected $table = 'posts';
protected $primaryKey = 'id';
protected $foreignKey = 'author';
public $timestamps = true;
protected $guarded = ['id'];
protected $fillable = [
'title', 'content', 'author'
];
protected $hidden = [];
protected $dates = [];
public function user()
{
return $this->hasOne('App\Models\User');
}
Posts Table Creation:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id')->unique();
$table->string('title')->required();
$table->longtext('content')->required();
$table->string('author');
$table->foreign('author')->references('username')->on('users');
$table->timestamps();
});
Select Box on PostCrudController:
$this->crud->addField([
'label' => "Author",
'type' => 'select2',
'name' => 'author', // the db column for the foreign key
'entity' => 'user', // the method that defines the relationship in your Model
'attribute' => 'username', // foreign key attribute that is shown to user
'model' => "App\Models\User", // foreign key model
'options' => (function ($query) { //limit to only admins
return $query->orderBy('username', 'ASC')->where('admin', 1)->get();
}),
]);
In all, I just need to allow the username from the select dropdown to be inserted into the author column, which would be the username for the user itself.
What I understood from your problem is that you are trying to add a relation between your posts table and users.
So from my point of view, instead of using foreign migration like
$table->foreign('author')->references('username')->on('users');
you should make the foreign key like this
$table->unsignedInteger('user_id')
$table->foreign('user_id')
->references('id')
->on('users')
->onUpdate('CASCADE')
->onDelete('CASCADE');
And then you can pass the id of the user in the user_id column to establish the relationship between these two.
The benefits of using the foreign key like this are
The id column is a primary key in users table so it will uniquely Identify your user
and it is an unsigned integer so it will be easy for the SQL engine to index this.
Now for fatching your data you can definitely the following eloquent relation in your Post model
public function user() {
return $this->belongsTo('App/User');
}
And while fatching posts you can use eager loading (with() eloquent method) something like
$posts = Post:::with('user)->get();
Now with all of the posts you can access any associated user information for example:
forach ($posts as $post){
$userName = $post->user->name;
}
Hope this will help.

Laravel 5.4 transaction and one-many relation

I just started laravel but I'm stuck to this point and I don't find a way to do it
Basically I insert an article with a category.
With select2, I select an existing category or I create a new one.
My article model :
public function category(){
return $this->belongsTo('App\Category');
}
My categories model :
public function articles(){
return $this->hasMany('App\Article');
}
My article migration :
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('content')->nullable();
$table->timestamps();
});
}
My category migration :
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('nom')->unique();
});
Schema::table('articles', function(Blueprint $table){
$table->integer('category_id')->unsigned()->index();
});
And finally my controller function to store article (I want to use transaction) :
public function store(Request $request)
{
$this->validate($request, [
'numero' => 'required',
'category' => 'required',
'title' => 'required'
]);
$article = new Article();
DB::transaction(function() use ($request) {
$category = Category::firstOrCreate(['nom' => $request->input('category')]);
$article->title = $request->input('title');
$article->save();
});
return response()->json([
'title' => $article->title
]);
}
So I know I don't save category id into article db but my category doesn't even insert, on my debug bar I've got this :
Begin Transaction
select * from batiments where (nom = 'HI') limit 1
Rollback Transaction
And my post page give me this error :
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicata du champ '' pour la clef 'batiments_nom_unique' (SQL: insert into batiments () values ())
Someone knpw how to insert or select if exist category and insert is id into article table ?
Thank
$table->integer('category_id')->unsigned()->index();
You set this field as index, just remove index(). Identity field must have only unique records, but your category_id may have same value many times.
code:
$table->integer('categorie_id')->unsigned();
$table->foreign('categorie_id')->references('id')->on('categories');
Laravel provides support for creating foreign key constraints, which are used to force referential integrity at the database level. For example, let's define a categorie_id column on the articles table that references the id column on a categories table
laravel.com/docs/5.4/migrations#foreign-key-constraints

Laravel - Table with foreign key not working --Updated

I'm using Laravel 5.2 and MySQL.
I'm developing a project to get used to Laravel. My project is a phonebook, where you can store contact info on a table. But to do this, you need to be logged in the system, which I made using the make:auth command. Simplicity, it seems.
In my "Users" table I have the field ID. This table is used to store the user info so they can login and access the contact stuff.
In my "Contacts" table, which is where I store my contacts, is a column named "Created By" that is supposed to take the field ID from the users table, just to reference who was the creator of said contact.
But here is the thing:
The contacts table isn't migrating, it doesn't matter what I do.
I already dropped both tables and made them from scratch, the USERS first, because it has the referenced primary key, and then the CONTACTS, with the foreign field set. I even dropped my models and created them using the same order above, because who knows what might work.
Here is my migration files:
USERS MIGRATION
----- ... -----
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email', 191)->unique();
$table->string('password', 191);
$table->timestamp('updated_at');
$table->timestamp('created_at');
$table->rememberToken();
});
}
----- ... -----
As stated, the table has the ID field I am referencing in my other table.
CONTACTS MIGRATION
----- ... -----
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id', false, true);
$table->foreign('user_id')->references('id')->on('users');
$table->string('image');
$table->string('name');
$table->string('lastname');
$table->string('email', 191)->unique();
$table->string('phone',191)->unique();
$table->string('address');
$table->string('description', 255);
});
----- ... -----
The field user_id references the id field in the table users, as stated. The second parameter is setting incrementing to false and the third is setting unsigned to true.
Even if I make the default style ($table->integer('user_id')->unsigned(); --- $table->foreign.....;), the migration isn't working.
I even made the foreign field in a separated schema from this main body, like so:
Schema::table('contacts', function($table) {
$table->foreign('user_id')->references('id')->on('users');
});
But even like this, the migration isn't working.
I really don't know what is happening.
This is my Contact Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
// Getting the user associated with the contact
// which means, I hope,
// The user that created the contact entry in the table 'contacts'
public function user()
{
return $this->belongsTo('App\User');
}
// protected $table = 'contacts';
// not using an id field
// could this be the error?
// dunno
// isn't laravel making an automatic id field?
// dunno too
public $fillable = array('name', 'lastname', 'email', 'phone', 'address');
// public $foreign = ('user_id');
//added because of error at migration
public $timestamps = false;
}
This is my User Model
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
// Putting it in simple terms
// Hopefully, this will return
// the many contacts that said user recorded in the 'contacts' table
public function contact()
{
return $this->hasMany('App\Contact');
}
// protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
UPDATE
I just rolled back my migrations and use the migrate command again, and it worked this time.
I can register an user, so the auth::check works and I can see the view with the form to insert a contact in the CONTACTS table.
But when I click the button to save, I get the following error:
2/2
QueryException in Connection.php line 729:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`phonebook`.`contacts`, CONSTRAINT `contacts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))
1/2
PDOException in Connection.php line 457:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`phonebook`.`contacts`, CONSTRAINT `contacts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))
I still don't know what is going on.
These are some of the ways you can add a contact and attach the user. Since you solved the foreign key issue, i won't address that.
$user = \Auth::user();
$user->contact()->create([
'name' => $request->input('name'),
'lastname' => $request->input('lastname'),
'email' => $request->input('email'),
'phone' => $request->input('phone'),
'address' => $request->input('address')
]);
Or
\App\Contact::create([
'name' => $request->input('name'),
'lastname' => $request->input('lastname'),
'email' => $request->input('email'),
'phone' => $request->input('phone'),
'address' => $request->input('address'),
'user_id' => \Auth::id()
]);
Or
$contact = new \App\Contact;
$contact->name = $request->input('name');
$contact->lastname = $request->input('lastname');
$contact->email = $request->input('email');
$contact->phone = $request->input('phone');
$contact->address = $request->input('address');
$contact->user_id = \Auth::id();
$contact->save();
Also add user_id to the $fillable property when you mass assign the value (second option shown above).

Integrity constraint violation: 1452 Cannot add or update a child row in Laravel 5.2

I get an error when i try to insert a role.I have found some solution of this issue in StackOverFlow but all those does not solve my problem.
I am trying to get id from roles table into roleID column of user_roles table.Here i am using Query Builder of Laravel 5.2.
public function store(Request $request)
{
//
$role = [];
$role['role'] = $request->input('role');
$data= Role::create($role);
$id= $data->id;
DB::table('user_roles')->insert([
'roleID' => $id
]);
//return $data;
return redirect(route('allRole'));
}
When i insert any role then it insert new data in roles table but i am not getting roleID in user_roles table.I get an error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(`amarjobs`.`user_roles`, CONSTRAINT `fkuserRolesuserID` FOREIGN KEY
(`userID`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE
CASCADE) (SQL: insert into `user_roles` (`roleID`) values (14))
Where is the problem i have done? Thanks in advanced.
Searched result:
1. First Solution.
2. Second Solution.
As you can see your user_roles table required userID column & you aren't passing the field while inserting that's what generating the error.
DB::table('user_roles')->insert([
'roleID' => $id,
'userID' => $userId, //pass your userID here
]);
Also I like to mention couple of things you are naming your DB table column names in camel case which is bad you should be using underscores & as db sqls are generally case insensitive so using userID is equivalent to userid.
Also you are using DB::insert it will not insert any created_at or updated_at field or other eloquent features so I suggest you insert using eloquent model & using relations which is the beauty of laravel & eloquent active records
try like this
public function store(Request $request)
{
//
$role = [];
$role['role'] = $request->input('role');
$data= Role::create($role);
$userdata = User::all();
$user_id = $userdata->first()->id;
$id= $data->id;
DB::table('permissions')->insert([
'role_id' => $id
]);
DB::table('user_roles')->insert([
'roleID' => $id,
'userID' => $user_id
]);
//return $data;
return redirect(route('allRole'));
}
Here $userdata = User::all(); you are selecting all user do you want all your to have this role then you have to loop through on it & insert it. Or if you want first user to have this role then it's fine.
Also I suggest I think you should read more Laravels documentation to clear things.
It seems you are trying to insert only roleID to user_roles table.
But within in your given error it seems the user_roles TABLE has also userID field what is foreign key and connect with users (id) table.
As user_roles is a pivot table and it has both roleID and userID and both are foreign key. So while inserting with only roleID value it's trying to insert the userID with the NULL value what is not matched with user Table any of IDs that's why Integrity constraint Violated.
So inserting data in a right way would be, you have to provide VALID userID as well.
$id= $data->id;
DB::table('user_roles')->insert([
'roleID' => $id,
'userID' => $EXISTING_USER_ID
]);
I think, it will solve your problem.
in your above error, you are missing the userID field, which is must in relationship perspective. so you should pass the userID then your code will be working.
$role = [];
$role['role'] = $request->input('role');
$data= Role::create($role);
$id= $data->id;
DB::table('user_roles')->insert([
'roleID' => $id,
'userID'=>1, // pass userID with whom you wan to attach new roleID
]);
return redirect(route('allRole'));
here is advance version of using relationship method
Add these method in respective models
user model
public function userRoles(){
return $this->belongsToMany('App\Role','user_roles','userID','roleID');
}
role model
public function roleUsers(){
return $this->belongsToMany('App\User','user_roles','roleID', 'userID');
}
and do this for insertion of roles.
$user = App\User::find(1);
$user->roles()->attach($roleId);
$role = [];
$role['role'] = $request->input('role');
$data= Role::create($role);
$id= $data->id;
$user->userRoles()->attach(['
'roleID' => $id,
'userID'=>$user->id
']);
return redirect(route('allRole'));

Categories