I have a problem with a foreign key.
I have a user who has a sex:
My migration users :
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('nom');
$table->string('prenom');
$table->string('adresse');
$table->integer('cp');
$table->string('ville');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->tinyInteger('admin')->nullable();
});
Schema::table('users', function ($table) {
$table->integer('sexe_id')->unsigned();
$table->foreign('sexe_id')->references('id')->on('sexes');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}`
My sexe migration :
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('sexes', function (Blueprint $table) {
$table->increments('id');
$table->string('libelle');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('sexes');
}
My sexes seeder :
class SexesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('sexes')->insert([
[
'libelle' => 'Homme',
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'libelle' => 'Femme',
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]
]);
}
}
My users seeder :
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('users')->insert([
[
'name' => 'admin',
'nom' => 'Virlois',
'prenom' => 'Peter',
'sexe_id' => 1,
'email' => 'admin#admin.fr',
'adresse' => '12 rue Jean Rostand',
'cp' => 90000,
'ville' => 'Belfort',
'password' => bcrypt('admin123'),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'admin' => 1,
],
[
'name' => 'test',
'nom' => 'Mennegain',
'prenom' => 'Mathieu',
'sexe_id' => 1,
'email' => 'test#test.fr',
'adresse' => '12 rue Jean Rostand',
'cp' => 90000,
'ville' => 'Belfort',
'password' => bcrypt('test123'),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'admin' => 0,
]
]);
}
}
My database seeder :
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$this->call(SexesTableSeeder::class);
$this->call(UsersTableSeeder::class);
$this->call(SaisonTableSeeder::class);
$this->call(ProduitTypeSeeder::class);
$this->call(SportsTableSeeder::class);
$this->call(ProduitsTableSeeder::class);
}
}
When i run : php artisan migrate:refresh -seed
I have this error :
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `users` add constraint `users_sexe_id_foreign` foreign key (`
sexe_id`) references `sexes` (`id`))
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
The order of migrations is super important. From what you posted you run the users migration first and in that same migration you try to create a users table and alter a table. the other table sexes doesn't exist
($table->foreign('sexe_id')->references('id')->on('sexes');)
so that is why you get a error.
I suggest separating the migrations in order to run users, sexes, alter users or sexes, users and alter in the same migration, but this is not a good way to do things, I mean to mix migrations (create and alter).
Probably there are nothing with id 1 in sexes table and sexe_id => 1 generating this error. In your UsersTableSeeder rather than hardcoding 'sexe_id' => 1 query your sexes table for any row and use that dynamic id.
Related
I'm adding these values to an existing table. In my down() function, how do I remove only the items I just added? truncate() will remove all the items in the table. I can use DB::table('user_account_cancel_reasons')->where('action', '==', 'cancel')->delete();, but that doesn't guarantee only removing the items in this migration. Using Laravel 7.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNewFieldsToUserAccountChangeReasons extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
DB::table('user_account_change_reasons')->insert(
[
[
'reason' => 'Health Issues',
'action' => 'cancel',
'created_at' => DB::raw('CURRENT_TIMESTAMP'),
'updated_at' => DB::raw('CURRENT_TIMESTAMP')
],
[
'reason' => 'Did not use',
'action' => 'cancel',
'created_at' => DB::raw('CURRENT_TIMESTAMP'),
'updated_at' => DB::raw('CURRENT_TIMESTAMP')
],
[
'reason' => 'Other',
'action' => 'cancel',
'created_at' => DB::raw('CURRENT_TIMESTAMP'),
'updated_at' => DB::raw('CURRENT_TIMESTAMP')
],
]
);
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('user_account_change_reasons', function(Blueprint $table) {
DB::table('user_account_change_reasons')->truncate();
});
}
}
Try, i solved it
public function down()
{
Schema::table('user_account_change_reasons', function(Blueprint $table)
{
DB::table('user_account_change_reasons')->where('action',
'cancel')->delete();
});
}
I got this error when try to seed database.
Laravel 7.
BlogPost Model
class BlogPost extends Model
{
protected $fillable = [
'title',
'slug',
'user_id',
'category_id',
'excerpt',
'content_raw',
'content_html',
'is_published',
'published_at',
'updated_at',
'created_at',
];
public function category()
{
return $this->belongsTo(BlogCategory::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
User model
class User extends Authenticatable
{
use Notifiable;
/**
* 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',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
User migration
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();
});
BlogPost migration
Schema::create('blog_posts', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('category_id');
$table->foreignId('user_id')->constrained();
$table->string('title');
$table->string('slug')->unique();
$table->text('excerpt')->nullable();
$table->text('content_raw');
$table->text('content_html');
$table->boolean('is_published')->default(false)->index();
$table->timestamp('published_at')->nullable();
$table->foreign('category_id')->references('id')->on('blog_categories');
$table->timestamps();
});
User seeder
class UserTableSeeder extends Seeder
{
public function run()
{
$users = [
[
'name' => 'Author',
'email' => 'seriiburduja#mail.ru',
'password' => bcrypt('some1234')
],
[
'name' => 'Admin',
'email' => 'seriiburduja#gmail.com',
'password' => bcrypt('some1234')
]
];
DB::table('users')->insert($users);
}
}
BlogPost Factory
$factory->define(BlogPost::class, function (Faker $faker) {
$title = $faker->sentence(rand(3, 8), true);
$text = $faker->realText(rand(1000, 4000));
$isPublished = rand(1, 5) > 1;
$createdAt = $faker->dateTimeBetween('-6 months', '-1 day');
return [
'category_id' => rand(1, 10),
'user_id' => 1,
'title' => $title,
'slug' => Str::slug($title),
'excerpt' => $faker->text(rand(100, 400)),
'content_raw' => $text,
'content_html' => $text,
'is_published' => $isPublished,
'published_at' => $isPublished ? $faker->dateTimeBetween('-6 months', '-1day') : null,
'created_at' => $createdAt,
'updated_at' => $createdAt
];
});
DatabaseSeeder
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
$this->call(UserTableSeeder::class);
$this->call(BlogCategorySeeder::class);
factory(BlogPost::class, 1)->create();
}
}
When i run php artisan migrate:fresh --seed i got this error.
Tables users and blog_categories seeds successfully, but error appear for blog_categories.
I don't understand why.
Field user_id exists in $fillable in BlogPost Model.
If i change migration for blog_posts and add a nullable for user_id, than seed work, but user_id is null. But i don't need that.
Thansk in advance.
In Blog Post Model
Change user relationship to
public function owner()
{
return $this->belongsTo(User::class);
}
In User Model
Add this relationship
public function blogposts()
{
return $this->hasMany(BlogPost::class);
}
In Database seeder don't use UserSeeder Directly create user in DatabaseSeeder
public function run()
{
$user = User::create([
'name' => "Your name",
'email' => "youremail#gmail.com",
'password' => Hash::make('YourPassword')
]);
$this->call(BlogCategorySeeder::class);
$user->blogposts()->saveMany(BlogPost::factory(1));
}
In BlogPost Factory remove user_id
return [
'category_id' => rand(1, 10),
'title' => $title,
'slug' => Str::slug($title),
'excerpt' => $faker->text(rand(100, 400)),
'content_raw' => $text,
'content_html' => $text,
'is_published' => $isPublished,
'published_at' => $isPublished ? $faker->dateTimeBetween('-6 months', '-1day') : null,
'created_at' => $createdAt,
'updated_at' => $createdAt
];
fillable is not required when you are using Seeder to insert data.
If you want to insert each and every column in database then you can use guarded property which is opposite of fillable.
I am creating a seeder in laravel, but I have to write 1 column json data, but I could not do it, how can I create a seeder column.
Seeder In seeder there will be "bank name" and "iban" in iban column
Migration
public function up()
{
Schema::create('settings', function (Blueprint $table) {
$table->id();
$table->string('account_type');
$table->string('name');
$table->json('ibans')->nullable();
$table->timestamps();
});
}
Seeder
public function run()
{
DB::table('settings')->insert([
'name' => 'Şirket Ünvanı',
'account_type' => 'settings',
'ibans' => json_decode('"a":1,"b":2',true),
'created_at' => now(),
'updated_at' => now(),
]);
}
It's
public function run()
{
DB::table('settings')->insert([
'name' => 'Şirket Ünvanı',
'account_type' => 'settings',
'ibans' => json_encode(['bankname' => 1, 'iban' => '2', '0' => true]),
'created_at' => now(),
'updated_at' => now(),
]);
}
You can add this json field to your Model (Settings) as casting field (protected $cast). It will be automatically handles json_encode, -decode to an array.
protected $casts = [
'ibans' => 'array'
];
$settings->ibans = $array;
$array = $settings->ibans;
https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting
I have a ‘recurring_payments’ table
Schema::create('recurring_payments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('user_id');
$table->string('card_id');
$table->string('day');
$table->integer('amount');
$table->timestamps();
});
I have a ‘card’ table
Schema::create('cards', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->string('token');
$table->string('last4');
$table->timestamps();
$table->softDeletes();
});
I have a ‘belongs to’ relationship between a ‘recurring_payment’ and a ‘card’
class RecurringPayment extends Model
{
protected $guarded = [];
public function card()
{
return $this->belongsTo(Card::class, 'token');
}
}
When I try to store the recurring payment
class Card extends Model
{
use SoftDeletes;
protected $fillable = [
'user_id',
'token',
'last4',
];
protected $hidden = [
'user_id',
'token',
'created_at',
'updated_at',
];
...
public function storeRecurringPayment($payment, $user)
{
$attributes = [
'user_id' => $user,
'card_id' => $payment->source['id'],
'day' => Carbon::now()->day()->addMonths(1)->format('d'),
'amount' => $payment->amount
];
// dd($attributes);
return $this->recurringPayment()->create($attributes);
}
public function recurringPayment()
{
return $this->hasOne(RecurringPayment::class);
}
...
}
it will not populate the ‘card_id’, it complains that the ‘card_id’ cannot be null, which is what I want, so far enough, but the ‘card_id’ is populated, this is the $attributes array died and dumped just before it's passed to the 'return $this->recurringPayment()->create($attributes);'
array:4 [▼
"user_id" => 3
"card_id" => "src_4zcdnrruvgxetpkgxocg6hhk5m"
"day" => "30"
"amount" => 10
]
I’m specifying in the ‘recurring_payment’ that I want to use ‘token’ as the foreign key not the default ‘card_id’ but I still get this error
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'card_id' cannot be null (SQL: insert into 'recurring_payments' ('user_id', 'card_id', 'day', 'amount', 'updated_at', 'created_at') values (3, ?, 30, 10, 2019-07-11 13:53:08, 2019-07-11 13:53:08))
Can anyone see the mistake I've made?
I modified the default laravel's user table and I did that by creating my own migration.
Here's my migration sample:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('username', 15)->unique()->after('id');
$table->string('lastname', 15)->unique()->after('username');
$table->string('firstname', 15)->unique()->after('lastname');
$table->string('contact')->nullable()->after('email');
$table->date('birthday')->after('contact');
$table->tinyInteger('status')->default(1)->after('birthday');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('username');
$table->dropColumn('lastname');
$table->dropColumn('firstname');
$table->dropColumn('contact');
$table->dropColumn('birthday');
$table->dropColumn('status');
});
}
And I removed the column name in the default laravel table so it looks like this:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
I checked the values from my form in the AuthController and I dont have an issue in getting the values. Here's what I added in the AuthController
protected $username = 'username'; //choose username instead of email
protected $redirectPath = '/dashboard'; //if successful login
protected $loginPath = 'auth/login'; //if not login
protected $redirectAfterLogout = 'auth/login'; //redirect after login
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'username' => 'required|min:8|max:16|unique:users',
'lastname' => 'required',
'firstname' => 'required',
'contact' => 'required',
'birthday' => 'date_format: Y-m-d',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
//dd($data); -- I can get all the values here
// I added my own column in this part to save. Is it correct?
return User::create([
'username' => $data['username'],
'lastname' => $data['lastname'],
'firstname' => $data['firstname'],
'birthday' => $data['birthday'],
'contact' => $data['contact'],
'email' => $data['email'],
'status' => 1,
'password' => bcrypt($data['password']),
]);
}
And when I try to save the data I can only save these columns
mysql> select * from users \G;
*************************** 1. row ***************************
id: 1
username:
lastname:
firstname:
email: myemail#gmail.com
contact: NULL
birthday: 0000-00-00
status: 1
password: $2y$10$3NkmqZaje4MKzheqPZKbhOIGD7ZlqYRfIP6DJZz4zb4gXVNvFsv2W
remember_token: PCYczF2Y9ts97TvbDOLsiXO5hxkekkxysmMYuIdN5MsaIY8TnroEof6d2jVM
created_at: 2015-09-17 06:56:43
updated_at: 2015-09-17 07:00:35
1 row in set (0.00 sec)
ERROR:
No query specified
How can I add my new column in the database?
Ok that's all I hope you can help me.
You can not edit the users table with this way
first, go to the terminal and write this command :
php artisan make:migration add_new_fields_to_users_table
and click enter.
After that, go to the migration file and in the add_new_fields_to_users_table.php
and write your new columns
$table->string('username', 15)->unique()->after('id');
$table->string('lastname', 15)->after('username');
$table->string('firstname', 15)->after('lastname');
$table->string('contact')->nullable()->after('email');
$table->date('birthday')->after('contact');
$table->tinyInteger('status')->default(1)->after('birthday');
Then , go to the terminal and do this:
php artisan migrate
and finally go to the User model and add the name's of your new table to the fillable variable
protected $fillable = [
'name', 'email', 'password','username',
'lastname','firstname','contact','birthday','status'
];
I hope this will help you
Ok I found the answer.
I need to put my own custom column in the fillable content:
protected $fillable = ['username', 'lastname', 'firstname', 'contact', 'email', 'birthday', 'status', 'password'];
Three files you need no adjust when you are adding new fields to the default users table or modifying to the default users table:
Users model found in Controllers\User.php or Controllers\Models\User.php
Update:
protected $fillable = [
'name',
'email',
'password',
];
Register blade in view located in views\auth\register.blade.php
Add new text-field for your new fields
Register Controller located at Controllers\Auth\RegisterController.php
Update:
Validator function and create function
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
return User::create([
'username' => $data['username'],
'email' => $data['email'],
'phone' => $data['phone'],
'password' => Hash::make($data['password']),
]);
}
Users table found in database\migrations\create_users_table.php
Add/Modify your schema
In the start I was able to add a role column to the users table like this.
public function up()
{
Schema::create('users', function (Blueprint $table) {
...
$table->string("role")->default("user");
...
});
}
I ran migrate and rollback commands several times while I was testing the application with different data. Later I needed two more columns in the user table.
Did as I had done before but failed.
Solved my problem with this artisan command and I was able to add more columns just by defining them in the user table schema as above.
Warning:
This rolls back all the migrations and you will lose all the data in your database. Make sure that you intentionally wanna happen this to the data.
php artisan migrate:reset