Mass assignment error when seeding in laravel - php

I am using the faker class to help seeder my database. The DatabaseSeeder looks like this
<?php
class DatabaseSeeder extends Seeder
{
public function run()
{
Eloquent::unguard();
$tables = [
'users',
'posts',
];
foreach ($tables as $table) {
DB::table($table)->truncate();
}
$this->call('UsersTableSeeder');
$this->call('PostsTableSeeder');
}
}
and the UsersTableSeeder
<?php
class UsersTableSeeder extends Seeder {
public function run()
{
$faker = Faker\Factory::create();
for( $i=0 ; $i<50 ; $i++ ) {
$user = User::create([
'first_name' => $faker->firstName,
'surname' => $faker->lastName,
'email' => $faker->email,
'username' => $faker->userName,
'bio' => $faker->sentences,
'bio_html' => $faker->sentences,
'wesbite' => $faker->url,
'twitter' => $faker->word,
]);
}
}
}
I am getting the following error in the terminal when I try and seed this table.
[Illuminate\Database\Eloquent\MassAssignmentException]
first_name
If I try and seed both I get this
[ErrorException]
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
I thought including Eloquent::unguard(); stopped this error? I am running the latest version of Laravel.

faker->sentences() and faker->paragraphs() return arrays and your class expects to receive a string.
You can either use faker->text() or you can you can use
implode(" ",$faker->sentences());

Well, i think you just need to do simple in your DatabaseSeeder.php, like this:
public function run()
{
Eloquent::unguard();
$this->call('UsersTableSeeder');
$this->call('PostsTableSeeder');
}
Your UsersTableSeeder.php, like these:
<?php
use Faker\Factory as Faker;
class UsersTableSeeder extends Seeder {
public function run()
{
$faker = Faker::create();
for( $i=0 ; $i<50 ; $i++ ) {
$user = User::create([
'first_name' => $faker->firstName, // try using str_random(10)
'surname' => $faker->lastName, // try using str_random(20)
'email' => $faker->email,
'username' => $faker->userName, // $faker->unique()->userName
'bio' => $faker->sentences,
'bio_html' => $faker->sentences,
'wesbite' => $faker->url,
'twitter' => $faker->word,
]);
}
}
}
And, in your model, User.php, add:
protected $guarded = [];
I executed here and both worked:
php artisan db:seed
php artisan db:seed --class=UsersTableSeeder
I configured laravel and faker, on composer, like these:
"require": {
"laravel/framework": "4.2.*",
"fzaninotto/faker": "dev-master"
},
Hope it help you.

You can define empty array of guarded fields in your model;
class User extends Eloquent
{
protected $guarded = [];
}

Related

Laravel Maatwebsite excel array

I'm a newbie in Laravel, but I'm using laravel's Maatwebsite\Excel Library v3 to export excel. But I'm having some problems exporting my array data.
here is my code
<?php
namespace App\Exports;
use App\Team;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithHeadings;
class RegisteredMemberExport implements FromCollection, WithHeadings
{
use Exportable;
public function collection()
{
$data = Team::where('reg', 1)->get();
return collect([
[
'name' => $data->name,
'email' => $data->email
]
]);
}
public function headings(): array
{
return [
'name',
'email'
];
}
}
the collect should be
return collect
([
[
'name' => 'Povilas',
'email' => 'povilas#laraveldaily.com'
],
[
'name' => 'Taylor',
'email' => 'taylor#laravel.com'
]
]);
I can't use a loop inside the collect method return.
Can I please have some help?
You can directly filter the values you need from your Eloquent model using a list of attributes as a parameter for the get method.
$data = Team::where('reg', 1)->get(['name', 'email']);
return collect($data->toArray());
You can use each or map or any chain method you want Laravel Collections like this:
return collect([
['name' => 'Povilas','email'=>'povilas#laraveldaily.com'],
['name' => 'Taylor','email' => 'taylor#laravel.com']
])->each(function($value){
return $value; // Do what you want here
});
You can use the Maatwebsite\Excel\Concerns\FromArray concern which works the same as FromCollection.
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
class RegisteredMemberExport implements FromArray, WithHeadings
{
public function array(): array
{
return [
[
'name' => 'Povilas',
'email' => 'povilas#laraveldaily.com',
],
[
'name' => 'Taylor',
'email' => 'taylor#laravel.com',
],
];
}
public function headings(): array
{
return [
'name',
'email',
];
}
}
Source

Faker laravel unknown formatter image

Am using faker in laravel and in my seeder i have
public function run()
{
$faker = new Faker\Generator();
//create a user
$adminuser = App\User::create(
[
'name' => 'admin',
'first_name' => 'firstuser',
'profile_pic'=>$faker->image('storage/app/public/users',400,300, 'people', false),
]
);
But now am getting an error
Unknown formatter "image"
Where am i going wrong
I just want to add an image to a user generated via faker
From the docs on basic usage
public function run()
{
// instead of using new Faker\Generator()
$faker = Faker\Factory::create();
//create a user
$adminuser = App\User::create(
[
'name' => 'admin',
'first_name' => 'firstuser',
'profile_pic' => $faker->image('storage/app/public/users',400,300, 'people', false),
]
);
}
You must use the ‍‍Method Injection
for example :
<?php
use Illuminate\Database\Seeder;
use Faker\Generator as Faker;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #param Faker $faker
* #return void
*/
public function run(Faker $faker)
{
$adminuser = App\User::create(
[
'name' => $faker->name,
'first_name' => $faker->firstName,
'profile_pic' => $faker->image(public_path('img'),400,300, 'people', true),
]
);
}
}

Seed multiple custom rows/entries in ModelFactory Laravel

How can I seed multiple rows using ModelFactory in Laravel?
Inside ModelFactory.php I have the following code:
$factory->define(App\User::class, function (Faker $faker) {
static $password;
return [
'name' => 'Admin',
'Description' => 'Administrators have full access to everything.'
];
});
How can I add the following arrays, without using raw expressions?
[
'name' => 'Admin',
'description' => 'Administrators have full access to everything.',
],
[
'name' => 'User',
'description' => 'User have normal access.',
],
Thanks
You can use sequence()
User::factory()->count(2)->sequence(['name' => 'admin'],['name' => 'user'])
->create()
example from laravel documentation
$users = User::factory()
->count(10)
->sequence(fn ($sequence) => ['name' => 'Name '.$sequence->index])
->create();
source https://laravel.com/docs/8.x/database-testing#sequences
Let's say you want to add 100 users in your database.
Create a UserFactory.php in database/factories:
<?php
use Faker\Generator as Faker;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => 'Admin',
'Description' => 'Administrators have full access to everything.'
];
});
Then, in database/seeds/DatabaseSeeder.php:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
factory(App\User::class, 100)->create();
}
}
You can find more details about seeding in the Laravel official documentation.
If you want to have one or two columns to have custom data, you can use each function after creating entries.
$names = ['admin', 'user', 'author', 'subscriber'];
factory(App\User::class, 100)->create()->each(function () use ($names) {
$user->name = $names[array_rand($names)];
$user->save();
});
*Note: Use your own logic inside each function to feed the custom data.
A cleaner way than Raghavendra's proposal (creates one entry per name):
$names = ['admin', 'user', 'author', 'subscriber'];
collect($names)->each(function($name) {
App\Models\User::factory()->create($name);
});

laravel factory insert foreign key

Hello everyone who's trying to help,
im trying to create the factory file to seeding my database and i have a question how can i insert a foreign key from a table already seeded ?
and the factory code is to have all in same file? any good pratice to this ?
Files
Model User
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $table = 'user'; //name of the table in database
protected $primaryKey = 'Id'; //Primary Key of the table
/**
* Relations between tables
*/
public function GetLoginInfo()
{
return $this->hasMany('App\Models\LoginInfo', 'UserId');
}
public function getStatus()
{
return $this->belongsTo('App\Models\AccountStatus');
}
}
Model Account status
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AccountStatus extends Model
{
protected $table = 'account_status'; //name of the table in database
protected $primaryKey = 'Id'; //primary Key of the table
public $timestamps = false; //true if this table have timestaps
/**
* Relations between tables
*/
public function GetUsers()
{
return $this->hasMany('App\Models\Users', 'StatusId');
}
}
factory file:
<?php
/** #var \Illuminate\Database\Eloquent\Factory $factory */
//Factory for Account Status table
$factory->define(App\Models\AccountStatus::class, function (Faker\Generator $faker) {
return [
'Description' => $faker->word,
];
});
//Factory for user table
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => Factory(App\Models\AccountStatus::class)->create()->id,
];
});
This is what im trying to do as you can see : Factory(App\Models\AccountStatus::class)->create()->id but don't work
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => factory(App\Models\AccountStatus::class)->create()->id,
];
});
i see an uppercase F in factory..
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
$accountStatus = factory(App\Models\AccountStatus::class)->create()
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => $accountStatus->id,
];
});
Edit (Improvement)
If you have one model that depend on another model. you can do it this way, using a callback function to create with the related.
Like this
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'Username' => $faker->unique()->userName,
'Password' => bcrypt('test'),
'Email' => $faker->unique()->safeEmail,
'Name' => $faker->name,
'StatusId' => function () {
return factory(App\Models\AccountStatus::class)->create()->id;
}
];
});
One thing you need to keep in mind is that this will go to an endless loop if the related(Status Model) has a model that depends on the parent(User Model).

CakePHP 3 Migration for Postgres was get PDO Error There is no active transaction for seed data

I'm trying to create seed data from CakePHP 3 migration file, with Postgres as database driver. But i have got error message under console after run:
bin/cake migrations migrate
Here are my code:
<?php
use Phinx\Migration\AbstractMigration;
use Cake\ORM\TableRegistry;
use Cake\Utility\Security;
class CreateSeedUsers extends AbstractMigration
{
/**
* Migrate Up.
*/
public function up()
{
$modelName = 'Users';
$data = [
[
'username' => 'admin',
'email' => 'admin#demo.com',
'password' => Security::hash('123', 'sha1', true)
],
[
'username' => 'seller',
'email' => 'seller#demo.com',
'password' => Security::hash('123', 'sha1', true)
],
[
'username' => 'member',
'email' => 'member#demo.com',
'password' => Security::hash('123', 'sha1', true)
]
];
$table = TableRegistry::get($modelName);
$entities = $table->newEntities($data);
debug($entities);
// In a controller.
foreach ($entities as $entity) {
// Save entity
$table->save($entity);
}
}
/**
* Migrate Down.
*/
public function down()
{
if ($this->query("TRUNCATE users")) {
echo " > Table has been initialized\n\n";
}
else
{
echo " > Warning, table failed to initialized!!!\n\n";
}
}
}
If i use mysql as database driver, its working good.
Someone please help me. Thank you.

Categories