I have self-relating table:
Schema::create('regions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('geoname')->unique();
$table->enum('type', ['continent', 'region', 'country', 'state', 'city'])->index();
$table->string('code', 2)->nullable()->index();
$table->string('name');
$table->string('language', 2)->nullable()->index();
$table->unsignedBigInteger('population')->nullable();
$table->timestamps();
$table->unique(['code', 'type']);
});
Schema::create('regions_has_regions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('region_id');
$table->unsignedBigInteger('has_region_id');
$table->timestamps();
$table->foreign('region_id')->references('geoname')->on('regions');
$table->foreign('has_region_id')->references('geoname')->on('regions');
});
I want to use geoname as primary key (as it is a globally unique integer identifier)
Model has:
protected $primaryKey = 'geoname';
public function children(): BelongsToMany
{
return $this->belongsToMany(
Region::class,
'regions_has_regions',
'region_id',
'has_region_id',
'geoname',
'geoname',
'children');
}
public function parents(): BelongsToMany
{
return $this->belongsToMany(
Region::class,
'regions_has_regions',
'has_region_id',
'region_id',
'geoname',
'geoname',
'parents');
}
Primary and relation keys are set to geoname.
But here I import countries in continents:
foreach ($continents as $continent) {
$pop = 0;
$continent->children()->saveMany(
collect($earth->find(['continent' => $continent->code])->useShortNames()->toArray())
->map(function ($c) use ($continent, $now, &$pop) {
$pop += $c['population'];
return Region::create([
'code' => $c['isoCode'],
'name' => $c['name'],
'type' => 'country',
'language' => $c['language'],
'population' => $c['population'],
'geoname' => $c['geonamesCode'],
]);
})
);
$continent->update(['population' => $pop]);
}
And get an error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`homestead`.`regions_has_regions`, CONSTRAINT `regions_has_regions_has_region_id_foreign` FOREIGN KEY (`has_region_id`) REFERENCES `regions` (`geoname`)) (SQL: insert into `regions_has_regions` (`has_region_id`, `region_id`) values (7, 6255146))
As you can see it tries to insert id value to has_region_id, instead of geoname.
How to resolve this?
Ok, figured out: Model should have this:
public $incrementing = false;
Related
I'm trying to create a create page where in a form an user text a caption and choose an image but whene i click a button to Add a New Post i get this error:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: posts.user_id (SQL: insert into "posts" ("caption", "image", "updated_at", "created_at") values (asd, C:\xampp\tmp\phpB7DC.tmp, 2021-03-12 13:06:56, 2021-03-12 13:06:56))
I want tell you that i'm using a sqlite db.
The Model of Post:
class Post extends Model
{
protected $fillable = [
'caption', 'image',
];
public function user()
{
return $this->belognsTo(User::class);
}
}
The PostsController:
class PostsController extends Controller
{
public function create()
{
return view('posts.create');
}
public function store() {
$data = request()->validate([
'caption' => 'required',
'image' => 'required|image',
]);
\App\Post::create($data);
dd(request()->all());
}
}
My table post in migration folder:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
in your migration, you didn't write this column Nullable.
you need to add post_id in your validations.
$data = request()->validate([
'caption' => 'required',
'image' => 'required|image',
'post_id' => 'required|int'
]);
You don`t send user_id value in your transaction
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id'); // this value must be set
$table->string('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
In this part
class PostsController extends Controller
{
public function create()
{
return view('posts.create');
}
public function store() {
$data = request()->validate([
'caption' => 'required',
'image' => 'required|image',
]);
// In this section you must add user_id to data
// For example
$data['user_id'] = Auth::user()->id;
\App\Post::create($data);
dd(request()->all());
}
}
I have made all the required fields nullable but still I am getting this error
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: public_problems.name (SQL: insert into "public_problems" ("answer", "helper_id", "helper_name", "updated_at", "created_at") values (Hey Bro Everythings Gonna be Alright, 2, kakashi, 2020-07-30 07:35:05, 2020-07-30 07:35:05))
Here's my Database:-
public function up()
{
Schema::create('public_problems', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('user_id')->unsigned();
$table->text('answer')->nullable();
$table->integer('helper_id')->unsigned()->nullable();
$table->string('helper_name')->nullable();
$table->string('title');
$table->text('problem');
$table->string('filled_by');
$table->timestamps();
});
}
Model:-
class PublicProblem extends Model
{
protected $fillable = ['name', 'user_id', 'title', 'problem', 'filled_by', 'helper_id', 'answer', 'helper_name'];
}
I have divided this field into 2 functions and they are:-
Controller
public function store(Request $request)
{
$data = request()->validate([
'title' => 'required',
'problem' => 'required',
]);
PublicProblem::create([
'title'=>$data['title'],
'problem'=>$data['problem'],
'name'=>Auth::user()->name,
'user_id'=>Auth::user()->id,
'filled_by'=>Auth::user()->uuid,
]);
return redirect('/home');
}
public function answer(Request $request) //The Error Occurs when I try to execute this function
{
$data = request()->validate([
'answer' => 'required',
]);
PublicProblem::create([
'answer' => $data['answer'],
'helper_id' => Auth::user()->id,
'helper_name' => Auth::user()->name,
]);
return redirect('/home');
}
The error occurs when I try to execute answer() function
Cant figure out what's causing it please help
Problem:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: public_problems.name
Solution:
The name file in your database is not nullable. If you want to call the create method, you will either have to add 'name' => 'someName' or you add the ->nullable() constrained to the name field.
PublicProblem::create([
'answer' => $data['answer'],
'helper_id' => Auth::user()->id,
'helper_name' => Auth::user()->name,
'name' => 'someName',
]);
Please Note:
You have some more fields which are not nullable, so the error might happen again for another field. (i commented it below)
$table->id();
$table->string('name'); //always needs a value
$table->integer('user_id')->unsigned(); //always needs a value
$table->text('answer')->nullable();
$table->integer('helper_id')->unsigned()->nullable();
$table->string('helper_name')->nullable();
$table->string('title'); //always need a value
$table->text('problem'); //always needs a value
$table->string('filled_by'); //always needs a value
Error here, your name, title, user_id, problem, filled_by fields are required, make this filled nullable on your migration or you should give a value while insert into table, otherwise SQL throw an error :
PublicProblem::create([
'name' => "Name", // Not null
'title' => "Title"; // Not null
'problem' => "Problem", // Not null
'filled_by' => "Filled by", // not null
'user_id' => "1", // not null
'answer' => $data['answer'],
'helper_id' => Auth::user()->id,
'helper_name' => Auth::user()->name,
]);
I a struggling to save the chosen information from my selection box. I get the message:
"SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (clientpad_notes.notebooks, CONSTRAINT notebooks_contact_id_foreign FOREIGN KEY (contact_id) REFERENCES contacts (id) ON DELETE CASCADE) (SQL: insert into notebooks (name, contact_id, note_description, note_body, user_id, updated_at, created_at) values (assddsaasdadasasd, 3, saS, ssss, 2, 2018-03-03 19:18:51, 2018-03-03 19:18:51)
My problem is that I am bringing in information to notes create page from contacts table. So I have my tables linked with authentication with user_id and inside the notes tables I have contacts_id. I am aiming to select and save a contact name fetching it by it's id, when creating a new note. It is possible I have been going around doing this in a wrong way, I am a beginner at Laravel so any help would be appreciated.
Here is my notes controllers and create a note page.
NotesController.php
public function create()
{
$user_id = auth()->user()->id;
$user = User::find($user_id);
$contacts = Contact::find($user->contacts)->pluck('fullName');
return view('notebooks.create')->with('contacts', $contacts)->with('user', $user);
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request,[
'name' => 'required',
'contact_id' => 'required',
'note_description' => 'required',
'note_body' => 'required',
]);
//Create a note
$notebook = new Notebook;
$notebook->name = $request->input('name');
$notebook->contact_id = $request->input('contact_id');
$notebook->note_description = $request->input('note_description');
$notebook->note_body = $request->input('note_body');
$notebook->user_id = auth()->user()->id; //currently logged in user show their notes
$notebook->save();
return redirect('/dashboard')->with('success', 'Your Note Was Created');
}
create.blade.php
<div class="col-6 col-sm-3">
{{Form::label('contact_id', 'Choose your Contact')}}
{{Form::select('contact_id', $user->contacts->pluck('fullName'), $contacts, ['class' => 'form-control'])}}
</div>
</div>
In the database which saved notes I have this:
Schema::create('notebooks', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('contact_id')->unsigned()->nullable();
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$table->string('name');
$table->mediumText('note_description');
$table->mediumText('note_body');
$table->timestamps();
});
You made small mistake when working with Id's from other tables. You should check if the ID actually exists in the target table.
$this->validate($request,[
'name' => 'required',
'contact_id' => 'required|exists:contacts', //This will validate that the contact ID actually exists.
'note_description' => 'required',
'note_body' => 'required',
]);
//Create a note
$notebook = new Notebook;
$notebook->name = $request->input('name');
$notebook->contact_id = $request->input('contact_id');
$notebook->note_description = $request->input('note_description');
$notebook->note_body = $request->input('note_body');
$notebook->user_id = auth()->user()->id; //currently logged in user show their notes
$notebook->save();
Laravel validation#rule-exists
Update
$this->validate($request,[
'name' => 'required',
'contact_id' => 'required|exists:contacts,id', //check contacts table, for column ID
'note_description' => 'required',
'note_body' => 'required',
]);
SO after lots of searching I found a solution. In Create I had to use mapping:
public function create(Contact $contact)
{
$user_id = Auth::user()->id;
$user = User::find($user_id);
$contacts = $user->contacts->mapWithKeys(function($contact){
return [$contact->id => $contact->fullName];
});
// dd ($contacts);
return view('notebooks.create')->with('contacts', $contacts)->with('user', $user);
}
Then in Select I just called for this:
{{Form::label('contact_id', 'Choose your Contact')}}
{{Form::select('contact_id', $contacts, null, ['class' => 'form-control'])}}
Works like a charm, in case anyone else finds this useful
So consider the following err:
[PDOException]
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "created_at" violates not-null constraint
DETAIL: Failing row contains (5, Sample Name xxx#gmail.com, xxxxxx, null, null, null).
This is the seeder:
<?php
use Illuminate\Database\Seeder;
class AdminUser extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('users')->insert([
'name' => 'Sample Name',
'email' => 'xxxx#gmail.com',
'password' => 'xxxxxx',
]);
}
}
The user model:
class Users extends Model {
protected $table = 'users';
protected $timestamps = true;
protected $fillable = ['name', 'email', 'password', 'created_at', 'updated_at'];
}
Whats going on? The migration, default from laravel install:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
Did they miss something? Did I?
Eloquent models automatically inserts timestamps for you, but the query builder doesn't. As the error message says, they can't be null. You have two options:
Add the timestamps manually:
DB::table('users')->insert([
'name' => 'Sample Name',
'email' => 'xxxx#gmail.com',
'password' => 'xxxxxx',
'updated_at' => new \Carbon\Carbon,
'created_at' => new \Carbon\Carbon
]);
Or use your User model to seed the database, and it will handle adding the timestamps for you.
User::create([
'name' => 'Sample Name',
'email' => 'xxxx#gmail.com',
'password' => 'xxxxxx'
]);
I have created a database with two tables, "goals" and "partgoals". The practial use is to make a savings goal (money) and have milestones along the way (partgoals). I want the partgoals obviously be linked to a specific goal. The relationships are created but I run into trouble when trying to create my seed data.
My goal is to set up two goals table like this (GoalsTableSeeder.php):
<?php
class GoalsTableSeeder extends Seeder {
public function run()
{
DB::table('goals')->delete();
$goals = array(
array(
'max' => 1850000,
'avgsav' => 3500,
'duedate' => date('2015-03-15'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
),
array(
'max' => 1100000,
'avgsav' => 5000,
'duedate' => date('2013-11-15'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
)
);
DB::table('goals')->insert( $goals );
}
}
And my partgoals table like this (PartgoalsTableSeeder.php):
<?php
class PartgoalsTableSeeder extends Seeder {
public function run()
{
DB::table('partgoals')->delete();
$partgoals = array(
array(
'id' => 1,
'milestone' => 100000,
'duedate' => date('2014-03-15'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
),
array(
'id' => 1,
'milestone' => 20000,
'duedate' => date('2013-06-15'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
),
array(
'id' => 2,
'milestone' => 400000,
'duedate' => date('2013-09-15'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
),
array(
'id' => 2,
'milestone' => 200000,
'duedate' => date('2014-10-15'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
)
);
DB::table('partgoals')->insert( $partgoals );
}
}
The migration table for "goals":
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateGoalsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('goals', function(Blueprint $table)
{
$table->increments('id');
$table->integer('max');
$table->float('avgsav');
$table->date('duedate');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('goals');
}
}
The migration table for partgoals:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePartgoalsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('partgoals', function(Blueprint $table)
{
$table->foreign('id')
->references('id')->on('goals')
->onDelete('cascade');
$table->increments('id');
$table->float('milestone');
$table->date('duedate')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('partgoals');
}
}
What am I doing wrong? I am new to Laravel (and Laravel 4).
I see a few problems with your code:
1) The way you create the foreign key
When assigning the Foreign key constraint, you should make that column unsignedInteger.
In the code below I will correct the mistake you made of naming two columns 'id'.
Schema::create('partgoals', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('goal_id');
$table->foreign('goal_id')
->references('id')->on('goals')
->onDelete('cascade');
$table->float('milestone');
$table->date('duedate')->nullable();
$table->timestamps();
});
2) The way you seed your database
If you specify a foreign key, you should declare the value when creating the entry in the table seeder.
If you want to specify a NULL value, this can be done by allowing the column to accept such value (by default it doesn't). In this case, we should add ->nullable()->default(NULL)
Schema::create('partgoals', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('goal_id')->nullable()->default(NULL);
$table->foreign('goal_id')
->references('id')->on('goals')
->onDelete('cascade');
$table->float('milestone');
$table->date('duedate')->nullable();
$table->timestamps();
});
Minor mistake
3) You are passing the 'id' => 1 twice in your seeder
When using increments in the query builder, that automatically makes that your primary key, auto-incremented, and unique. You can't have a foreign key also be your primary key unless it's a one-to-one relationship. That's just bad design though. Your schema should look something like below.
Schema::create('partgoals', function(Blueprint $table)
{
$table->increments('id');
$table->foreign('goal_id')
->references('id')->on('goals')
->onDelete('cascade');
$table->float('milestone');
$table->date('duedate')->nullable();
$table->timestamps();
});
Also, when seeding, if you use the insertGetId when inserting, it will return the ID of the record you just inserted. This you can use in another insert, like inserting into another table, later. However, this has to take place in the same script. You may be able to pass it back out to DatabaseSeeder and then back into another seed script, but I haven't tried this.
I'm not familiar with Laravel, or what you're trying to do, but based on the error you added in the comments it seems that your problem is a result of trying to enter multiple records with the same primary key (1) into your partgoals table.
I'm not sure how you've set your tables up, but it seems like you've defined a partgoals table with a unique primary key column ID, which you're also trying to use as a foreign key to reference the goals table. It may be worth creating another field to hold your foreign key in the partgoals table.
To seed tables with relationship, you need to defined model factories in the ModelFactory.php file and then create a seeder class to run the seeder.
For ex. ModelFactory.php
$factory->define(App\Category::class, function (Faker\Generator $faker) {
$name = $faker->name;
return [
'name' => $name,
'visible' => 1
];
});
$factory->define(App\Video::class, function (Faker\Generator $faker) {
return [
'title' => $faker->name,
'description' => '',
'status' => 1
];
});
Then the seeder class can be as follows
<?php
use Illuminate\Database\Seeder;
class CategoriesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$categories = factory(App\Category::class, 20)->create()->each(function ($u) {
for ($i=0; $i<5; $i++)
{
$u->videos()->save(factory(App\Video::class)->make());
}
});
}
}
You can refer this article on how to generate seeds for two tables with relationship http://deepdivetuts.com/seeding-two-tables-using-laravel-5-3