I have one foreign key in my database named images.
This is its Migration:
class CreateImagesTable extends Migration
{
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned();
$table->integer('product_r_id')->unsigned();
$table->string('name', 50);
$table->text('images', 50);
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
Schema::table('images', function (Blueprint $table) {
$table->foreign('product_r_id')->references('id')->on('products_r')->onDelete('cascade')->onUpdate('cascade');
});
}
public function down()
{
Schema::drop('images');
}
}
Its Model looks like this:
class Images extends Model
{
protected $table = 'images';
protected $fillable = ['product_id', 'product_r_id', 'name', 'images'];
public function product()
{
return $this->belongsTo('App\Product', 'product_id');
}
public function productR()
{
return $this->belongsTo('App\ProductR', 'product_r_id');
}
}
ProductR Model looks like this:
class ProductR extends Model
{
protected $table = 'products_r';
protected $fillable = ['email', 'title', 'filename', 'inputMpg', 'number_of_chapters'];
public function images()
{
return $this->hasMany('App\Images');
}
}
And Product Model like this:
class Product extends Model
{
protected $table = 'products';
protected $fillable = ['email', 'title', 'filename', 'inputMpg', 'number_of_chapters'];
public function scenesImages()
{
return $this->hasMany('App\Images');
}
}
So I basicaly try to save in two different forms different products with their image into the same table in my database (images).
Running my Program returns me this error:
QueryException in Connection.php line 655: SQLSTATE[23000]: Integrity
constraint violation: 1452 Cannot add or update a child row: a foreign
key constraint fails (mydb.images, CONSTRAINT
images_product_id_foreign FOREIGN KEY (product_id) REFERENCES
products (id) ON DELETE CASCADE ON UPDATE CASCADE) (SQL: insert
into images (name, images, product_r_id, updated_at,
created_at) values (ki, 0Chrysanthemum.jpg, 10, 2016-05-20 10:50:51,
2016-05-20 10:50:51))
I think the issue arises because of these lines:
$table->integer('product_id')->unsigned();
[...]
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade')->onUpdate('cascade');
You cannot just create an image without filling out product_id which seems to be the case because the error
insert into images (name, images, product_r_id, updated_at, created_at) ...
shows that you're inserting into images without product_id which cannot be null and has a foreign key constraint.
I suppose you can do a
$table->integer('product_id')->unsigned()->nullable();
so you don't need to assign it when inserting.
Related
I am currently learning Laravel through a personal project.
Context
In a blog like application, I need to link an article to its author. When I save the article, I get the error below.
Error
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (parabolica-dev.articles, CONSTRAINT articles_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id)) (SQL: insert into articles (title, content, excerpt, updated_at, created_at) values (rgergregerg, regergergregerg, regregregregreg, 2020-04-29 09:55:12, 2020-04-29 09:55:12))
Models
Article
class Article extends Model
{
protected $fillable = ['title', 'content', 'excerpt', 'user_id'];
public function user() {
return $this->belongsTo('App\User');
}
}
User
class User extends Authenticatable
{
protected $fillable = [
'name', 'email', 'password',
];
public function article()
{
return $this->hasMany('App\Article');
}
}
Migrations
Users
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
Articles
class CreateArticlesTable extends Migration
{
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('title');
$table->text('excerpt');
$table->text('content');
$table->string('type');
$table->string('status');
// Relationship between article and user
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
}
public function down()
{
Schema::dropIfExists('articles');
}
}
Controller
ArticleController
class ArticleController extends Controller
{
public function store(StoreArticle $request)
{
$validatedData = $request->validated();
$user = Auth::user()->id;
$article = Article::create($validatedData);
$article->user_id = $user;
$request->session()->flash('status', 'Article was created!');
return redirect()->route('articles.show', ['article' => $article->id]);
}
}
Solutions tried
Adding user_id to the $fillable array in my Article model, I still get the error.
Adding the nullable() method to user_id in my migration. Saving the article goes through without the error message but the user_id is recorded as null in my table afterwards.
Those are the 2 most proposed solutions across SO / LaravelCasts from what I found. Any suggestions on what I did wrong ?
Thanks for helping me !
The create method creates and saves a new instance of your model. Since the model does not include the users id at that point, it fails.
You could fix that by adding user_id to the fillables array of your model and also add the user id to the $validatedData array before creating the model.
Alternatively, you can also create a new instance of your model with the new keyword, set all data and explicitely save it once you're done:
$article = new Article($validatedData);
$article->user()->associate( Auth::user() );
$article->save();
You have to change this three lines. You insert a row but at the time user_id is null. That's why it shows the error because you assigned the user_id field not nullable.
$article = new Article;
$article->fill($validatedData);
$article->user_id = Auth::user()->id;
$article->save();
I have a truck table, a package table, and a postman table. Truck table and package table has a one to many relationship. Truck table and postman table has a one to one relationship.
Now I can delete truck table just fine, but I got integrity constraints violation error inside the truck table when I try to update postman_name on truck data that has packages assigned to it. I don't get the error when I try to change other non-foreign key properties or when I try to change postman_name on a truck data that currently has zero package assigned.
I only got the error when I try to update postman_name on a truck_number with packages assigned to it.
How can I fix this error?
the postman form inside truck/edit.blade.php :
<div class="form-group">
<label for="postman_name">Postman in Charge</label>
<select name="truck_number" class="form-control">
<option selected disabled>-</option>
#foreach ($postmen as $count => $postman)
<option value="{{$postman['postman_name']}}">{{$postman['postman_name']}}</option>
#endforeach
</select>
</div>
Truck update controller:
public function update(Request $request, $truck_id)
{
$request->validate([
'truck_number'=>'required|unique:trucks,truck_id',
'postman_name',
'date_of_operation'=>'required'
]);
$trucks = Truck::find($truck_id);
$trucks->truck_number = $request->get('truck_number');
$trucks->postman_name = $request->get('postman_name');
$trucks->date_of_operation = $request->get('date_of_operation');
$trucks->save();
return redirect(TRUCK)->with('success', 'Truck Updated!');
}
Package migration file:
Schema::create('packages', function (Blueprint $table) {
$table->increments('package_id');
$table->string('truck_number')->nullable();
$table->foreign('truck_number')->references('truck_number')->on('trucks')->onDelete('cascade');
$table->string('package_number')->unique();
$table->string('receiver_name');
$table->string('destination');
$table->timestamps();
});
postman migration file:
Schema::create('postmen', function (Blueprint $table) {
$table->increments('postman_id');
$table->string('truck_number')->nullable();
$table->foreign('truck_number')->references('truck_number')->on('trucks')->onDelete('cascade');
$table->string('postman_number')->unique();
$table->string('postman_name');
$table->timestamps();
});
truck migration file:
Schema::create('trucks', function (Blueprint $table) {
$table->increments('truck_id');
$table->string('truck_number')->unique();
$table->string('postman_name')->nullable();
$table->date('date_of_operation');
$table->timestamps();
});
Models:
class postman extends Model
{
use HasFactory;
protected $primaryKey = 'postman_id';
protected $fillable = ['truck_number','postman_number','postman_name'];
public function Truck(){
return $this->belongsTo(Truck::class);
}
}
class Package extends Model
{
use HasFactory;
protected $primaryKey = 'package_id';
protected $fillable = ['truck_number', 'package_number', 'receiver_name', 'destination'];
public function Truck(){
return $this->belongsTo(Truck::class);
}
}
class Truck extends Model
{
use HasFactory;
protected $primaryKey = 'truck_id';
protected $fillable = ['truck_number', 'postman_name', 'date_of_operation', 'status'];
public function Package()
{
return $this->hasMany(Package::class, 'truck_number', 'truck_number');
}
public function postman()
{
return $this->hasOne(postman::class, 'truck_number', 'truck_number');
}
}
note: by the way, I also cannot add $table->foreign('postman_name')->references('postman_name')->on('postmen')->onDelete('cascade'); to truck migration file. it throws this error when I do that:
SQLSTATE[HY000]: General error: 1005 Can't create table proj_db.trucks (errno: 150 "Foreign key constraint is incorrectly formed")
You need to change postman_name column to be unique on postmen table:
$table->string('postman_name')->unique();
And in your Truck model you need to specify the foreign key name and the local key name, like this:
return $this->hasOne(postman::class, 'postman_name','postman_name');
Change your relationship in postman Model
public function truck(){
return $this->belongsTo(Track::class, 'postman_name', 'postman_name');
}
and in Truck model
public function postman(){
return $this->hasOne(Postman::class, 'postman_name', 'postman_name');
}
I am currently learning Laravel through a personal project.
Context
In a blog like application, I need to link an article to its author. When I save the article, I get the error below.
Error
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (parabolica-dev.articles, CONSTRAINT articles_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id)) (SQL: insert into articles (title, content, excerpt, updated_at, created_at) values (rgergregerg, regergergregerg, regregregregreg, 2020-04-29 09:55:12, 2020-04-29 09:55:12))
Models
Article
class Article extends Model
{
protected $fillable = ['title', 'content', 'excerpt', 'user_id'];
public function user() {
return $this->belongsTo('App\User');
}
}
User
class User extends Authenticatable
{
protected $fillable = [
'name', 'email', 'password',
];
public function article()
{
return $this->hasMany('App\Article');
}
}
Migrations
Users
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
Articles
class CreateArticlesTable extends Migration
{
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('title');
$table->text('excerpt');
$table->text('content');
$table->string('type');
$table->string('status');
// Relationship between article and user
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
}
public function down()
{
Schema::dropIfExists('articles');
}
}
Controller
ArticleController
class ArticleController extends Controller
{
public function store(StoreArticle $request)
{
$validatedData = $request->validated();
$user = Auth::user()->id;
$article = Article::create($validatedData);
$article->user_id = $user;
$request->session()->flash('status', 'Article was created!');
return redirect()->route('articles.show', ['article' => $article->id]);
}
}
Solutions tried
Adding user_id to the $fillable array in my Article model, I still get the error.
Adding the nullable() method to user_id in my migration. Saving the article goes through without the error message but the user_id is recorded as null in my table afterwards.
Those are the 2 most proposed solutions across SO / LaravelCasts from what I found. Any suggestions on what I did wrong ?
Thanks for helping me !
The create method creates and saves a new instance of your model. Since the model does not include the users id at that point, it fails.
You could fix that by adding user_id to the fillables array of your model and also add the user id to the $validatedData array before creating the model.
Alternatively, you can also create a new instance of your model with the new keyword, set all data and explicitely save it once you're done:
$article = new Article($validatedData);
$article->user()->associate( Auth::user() );
$article->save();
You have to change this three lines. You insert a row but at the time user_id is null. That's why it shows the error because you assigned the user_id field not nullable.
$article = new Article;
$article->fill($validatedData);
$article->user_id = Auth::user()->id;
$article->save();
I'm trying to delete a user but there is ForeignKey constraints that I also need to delete.
In my User model, I have
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
public $incrementing = false;
protected $fillable = [
'name',
'email',
'password',
'timezone',
'profile_picture',
'notification_key'
];
protected $hidden = [
'password',
'pivot',
'admin'
];
public static function boot()
{
parent::boot();
static::creating(function ($instance) {
$instance->id = Uuid::uuid4();
});
}
public function groups()
{
return $this->belongsToMany(Group::class)
->withPivot('user_role')
->withTimestamps();
}
public function events()
{
return $this->belongsToMany(Event::class);
}
}
migrations for relation are
class CreateEventUserTable extends Migration
{
public function up()
{
Schema::create('event_user', function (Blueprint $table) {
$table->uuid('event_id');
$table->uuid('user_id');
$table->primary(['event_id', 'user_id']);
$table->foreign('event_id')->references('id')->on('events');
$table->foreign('user_id')->references('id')->on('users');
});
}
public function down()
{
Schema::dropIfExists('event_user');
}
}
and
class CreateGroupUserTable extends Migration
{
{
Schema::create('group_user', function (Blueprint $table) {
$table->uuid('group_id');
$table->uuid('user_id');
$table->string('user_role')->nullable();
$table->timestamps();
$table->boolean('owner');
$table->primary(['group_id', 'user_id']);
$table->foreign('group_id')->references('id')->on('groups');
$table->foreign('user_id')->references('id')->on('users');
});
}
public function down()
{
Schema::dropIfExists('group_user');
}
}
so I was trying to delete user like this
public function delete($user)
{
$user = User::findOrfail('id', $user->id);
$res = $user->groups()->events()->delete();
if ($res) {
return response('Success, user was deleted', 204);
} else {
return response()->json(error);
}
}
but still, I'm receiving
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`event_activities`, CONSTRAINT `event_activities_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) (SQL: delete from `users` where `id` = someID) in file /home/server/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 664
I was hoping to do deletion in the manner by relationship in the User model, but I'm still receiving an Integrity error, so what is the proper way of doing this?
There are 3 ways to achieve this:
Using detach
$user->groups()->events()->detach();
$user->groups()->detach();
Utilise the deleting event on related models like in this answer
Migrations.
// in user_roles
$table->integer('group_id');
$table->foreign('group_id')->references("id")->on("groups")->onDelete("cascade");
This translates into:
When group 'id' is deleted on 'groups', delete this row.
Apply same thing to groups for events.
Edit:
Looking at your migrations, you implemented 3rd solution, but you seem to forget
->onDelete('cascade');
I am using two pivot tables to store two different relations of a table. One relation works fine on insert. but the next one throws the following error. I don't know what's causing this.
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (sdesk.approvers, CONSTRAINT approvers_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id)) (SQL: insert into approvers (user_id, request_id, updated_at, created_at) values (2, 6, 2014-04-29 10:54:37, 2014-04-29 10:54:37))
Here's my code:
UrequestsController.php
public function postCreate() {
$request = new Urequest;
$request->vms = Input::get('vms');
$request->location = Input::get('location');
$request->descr = Input::get('descr');
$request->status = Input::get('status');
//$request->role_group = Input::get('team');
$request->save();
$ruser = new Ruser;
$ruser->user_id = Input::get('userid');
$ruser->urequest()->associate($request);
$ruser->save();
$approver = new Approver;
$approver->user_id = Input::get('aid');
$approver->urequest()->associate($request);
$approver->save();
return Redirect::to('users/dashboard')->with('message', 'Saved!');
}
Approver.php
class Approver extends Eloquent {
protected $fillable = array('request_id', 'user_id');
public function urequest() {
return $this->belongsTo('Urequest','request_id');
}
}
Ruser.php
class Ruser extends Eloquent {
protected $fillable = array('request_id', 'user_id');
public function urequest() {
return $this->belongsTo('Urequest','request_id');
}
}
urequest.php
class Urequest extends Eloquent {
protected $table = 'requests';
protected $fillable = array('vms', 'location', 'descr', 'status');
public function ruser() {
return $this->hasOne('Ruser');
}
public function approver() {
return $this->hasOne('Approver');
}
}
Schema
Schema::create('requests', function($table)
{
$table->increments('id');
$table->string('vms', 20);
$table->string('location', 20);
$table->string('descr', 255);
$table->string('status', 20);
$table->timestamps();
});
Schema::create('rusers', function($table)
{
$table->increments('id');
$table->integer('request_id')->unsigned();
$table->foreign('request_id')->references('id')->on('requests');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
Schema::create('approvers', function($table)
{
$table->increments('id');
$table->integer('request_id')->unsigned();
$table->foreign('request_id')->references('id')->on('requests');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
"A foreign key constraint" usually fails when you don't have a row for the value(s) you are inserting/updating in the foreign table.
In this case you probably doesn't have a user_id of 2 in the users table or a request_id of 6 in the requests table.
EDIT just saw morawcik answered it in comments.