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),
]
);
}
}
Related
I'm trying to seed my Laravel 5.6 application through faker factory, I went through the link and little bit confused, As I have some basic static data, like for example I've a company model:
class Company extends Model {
use SoftDeletes, HasDataSearchTable, HasSlug;
protected $fillable = [
'name', 'code_link', 'slug', 'establishment', 'parent_id', 'website', 'updates', 'user_id', 'tracked', 'verified', 'active', 'premium', 'status'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'created_at','updated_at','deleted_at'
];
public function roles()
{
return $this->belongsToMany('Noetic\Plugins\Conxn\Models\Variables\Company\Role', 'company_role_relation', 'company_id', 'role_id')->withTimestamps();
}
}
And a relational role model:
class Role extends Model
{
use SoftDeletes , HasDataSearchTable;
protected $table='company_role';
protected $fillable = [
'name', 'parent_id'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'created_at','updated_at','deleted_at'
];
}
and respective database, I'm following the laravel convention, Now I want to seed the data:
I've particular set of roles which I'm seed in manually,
class CompanyRoleSeed extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('company_role')->insert([
['name' => 'Contractor', 'parent_id' => null],
['name' => 'Consultant', 'parent_id' => null],
['name' => 'Manufacturer', 'parent_id' => null],
['name' => 'Miscellaneous', 'parent_id' => null],
['name' => 'Owner', 'parent_id' => null],
['name' => 'Supplier', 'parent_id' => null],
]);
}
}
For company I want to create factory so I did:
$factory->define(Company::class, function (Faker $faker) {
return [
'name' => $faker->company,
'code_link' => rand(5, 10),
'slug' => str_slug($faker->company),
'about' => $faker->paragraphs(),
'establishment' => $faker->randomElement('2015', '2016', '2017', '2018'),
'parent_id' => $faker->randomElement(null, '1', '2', '3'),
'website' => $faker->url,
'user_id' => $faker->randomElement('1', '2', '3', '4', '5'),
'updates' => $faker->paragraphs(),
'tracked' => $faker->boolean,
'verified' => $faker->boolean,
'active' => $faker->boolean,
'premium' => $faker->boolean,
'status' => $faker->randomElement('saved', 'draft')
];
});
And in company seed I'm having:
class CompanySeed extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
factory(Company::class, 10)->create()->each(function ($company) {
$company->roles()->save(); // Don't now how to execute here
});
}
}
Help me at place $company->roles()->save(); What should I do over here.
Any guidance or improvisation welcome.
You can query which roles you want to assign to the companies and related them to the created records like this:
class CompanySeed extends Seeder
{
public function run()
{
$contractorRole = Role::whereName('Contractor')->firstOrFail();
$ownerRole = Role::whereName('Owner')->firstOrFail();
factory(Company::class, 10)->create()->each(function ($company) use ($contractorRole, $ownerRole) {
$company->roles()->attach([
$contractorRole->id,
$ownerRole->id
]);
});
}
}
You can check the doc for relating records https://laravel.com/docs/5.6/eloquent-relationships#inserting-and-updating-related-models
before answering your question you should know that Laravel's documentation explains how to do this.
But in order to save a related Model you first need to create a fake one, or in your case relate a role you have already created. In order to do this you could first create a Role factory using something like this:
$factory->define(App\Role::class, function (Faker $faker) {
$randomRoleAlreadyCreated = \App\Role::all()->random();
return [
'name' => $randomRoleAlreadyCreated->name,
'parent_id' => $randomRoleAlreadyCreated->parent_id
];
});
As you can see on Role factory I created I pull a random Role since you stated that you already created them manually, so if you choose one randomly then your companys will be related to one of your roles randomly!
Once you have: Roles created in DB, factory of roles, you could relate random roles to a company using the factory to save a random instance.
factory(Company::class, 10)->create()->each(function ($company) {
$company->roles()->save(factory(App\Role::class)->make()); // Don't now how to do here
});
Update
If you want to save multiple roles for each company you could do this:
factory(Company::class, 10)->create()->each(function ($company) {
// Instead of 4 you could also create a random number
// using $numberOfRolesToAttach = rand($min,$max)
for($i = 1; $i <= 4; $i++) :
$company->roles()->save(factory(App\Role::class)->make());
endfor;
});
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);
});
When i try to log in , it redirects me to www.example.com/admin/{username} but it shows a NotFoundHttpException error. Thank you in advance!
The routes.php file
Route::get('/admin', 'SessionsController#create');
Route::get('/logout', 'SessionsController#destroy');
Route::get('profile', function()
{
return "welcome! Your username is" . Auth::admin()->username;
});
Route::resource('sessions', 'SessionsController', ['only' => ['index', 'create', 'destroy', 'store']]);
here is the controller SessionsController.php
<?php
class SessionsController extends \BaseController {
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
return View::make('admins');
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
$rules = array('username' => 'required', 'password' => 'required');
$validator = Validator::make(Input::all(), $rules);
if($validator -> passes()){
$credentials = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
if(Auth::admin($credentials,true)){
$username = Input::get('username');
return Redirect::to("admin/{$username}");
} else {
return Redirect::to('/admin')->withErrors('Username or password invalid');
}
} else {
return Redirect::to('/admin')->withErrors($validator->messages());
}
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
Auth::logout();
return Redirect::home();
}
}
the admins.blade.php
{{Form::open(array('route' => 'sessions.store'))}}
<h1>ADMIN LOGIN </h1>
{{Form::label('username', 'Username')}}
{{Form::text('username')}}
{{Form::label('password', 'Password')}}
{{Form::password('password')}}
{{Form::submit('Login')}}
{{$errors->first()}}
{{Form::close()}}
and here is the model Admin.php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class Admin extends Eloquent implements UserInterface, RemindableInterface {
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'admins';
}
I also installed ollieread multiauth
and here is auth.php file
return array(
'multi' => array(
'admin' => array(
'driver' => 'database',
'model' => 'Admin',
'table' => 'admins'
),
'user' => array(
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users'
)
),
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
You haven't declared any routes pointing to /admin/{username} . That's the reason it can't be found by laravel.
Here is an example:
In your route files
Route::get('/admin/{username}', 'SessionsController#getByUserName');
I strongly advice you to use named routes. They are a lot easier to manage, even if your application gets bigger.
For example
In your route files
Route::get('/admin/{username}',array('as' => 'admin.username', 'uses'=>'SessionsController#getByUserName'));
Then you can call the url that points to the certain controller either using
URL::route('admin.username')(inside views) or
Redirect::route('admin.username') (inside controller)
You can also pass variables using an array. like this
URL::route('admin.username',array($user->username))
More about routing here
I've follow all the steps on the Extending User plugin screencast but for some reason I can not see "Profile" tab and either new added fields. Since I used the second approach, the easy one, this is what I've done:
Create the plugin and models and so on under Alomicuba namespace
Create and make the needed changes to the files as explained in video:
Plugin.php
<?php namespace Alomicuba\Profile;
use System\Classes\PluginBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Controllers\Users as UsersController;
/**
* Profile Plugin Information File
*/
class Plugin extends PluginBase
{
public $requires = ['RainLab.User'];
/**
* Returns information about this plugin.
*
* #return array
*/
public function pluginDetails()
{
return [
'name' => 'Profile',
'description' => 'Add extra functionalities for Alomicuba WS by extends RainLab User',
'author' => 'DTS',
'icon' => 'icon-users'
];
}
public function boot()
{
UserModel::extend(function($model){
$model->hasOne['profile'] = ['Alomicuba\Profile\Models\Profile'];
});
UsersController::extendFormFields(function ($form, $model, $context){
if ($model instanceof UserModel)
return;
$form->addTabFields([
'pinCode' => [
'label' => 'PIN',
'tab' => 'Profile'
],
'phone2' => [
'label' => 'Teléfono (2)',
'tab' => 'Profile'
],
'phone3' => [
'label' => 'Teléfono (3)',
'tab' => 'Profile'
],
'phone4' => [
'label' => 'Teléfono (4)',
'tab' => 'Profile'
]
]);
});
}
}
add_profiles_fields_to_user_table.php
<?php namespace Alomicuba\Profile\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class AddProfilesFieldsToUserTable extends Migration
{
public function up()
{
Schema::table('users', function($table)
{
$table->integer('pinCode')->unsigned();
$table->dateTime('pinCodeDateTime');
$table->integer('phone2')->unsigned()->nullable();
$table->integer('phone3')->unsigned()->nullable();
$table->integer('phone4')->unsigned()->nullable();
});
}
public function down()
{
$table->dropDown([
'pinCode',
'pinCodeDateTime',
'phone2',
'phone3',
'phone4'
]);
}
}
version.yaml
1.0.1: First version of Profile
1.0.2:
- Created profiles table
- create_profiles_table.php
- add_profiles_fields_to_user_table.php
Profile.php (Model)
<?php namespace Alomicuba\Profile\Models;
use Model;
/**
* Profile Model
*/
class Profile extends Model
{
/**
* #var string The database table used by the model.
*/
public $table = 'alomicuba_profile_profiles';
/**
* #var array Relations
*/
public $belongsTo = [
'user' => ['RainLab\User\Models\User']
];
// This method is not need anymore since I'll use the second approach
public static function getFromUser($user)
{
if ($user->profile)
return $user->profile;
$profile = new static;
$profile->user = $user;
$profile->save();
$user->profile = $profile;
return $profile;
}
}
But when I edit a existent user I didn't see the 'Profile' tab and also didn't see any new added field. See image below:
Any advice around this? Did I miss something?
Also I have a few question around plugin extends:
How do I add a required field to the register form?
How do I display each new added field on the account form?
I haved tested your code on my machine you need to write
$require instead of $requires in plugin.php
please check documentation
http://octobercms.com/docs/plugin/registration#dependency-definitions
and when extendFormFields() method called for UserController you need to specify that you only want to extends fields for UserModel not for other
if (!$model instanceof UserModel)
return;
so plugin.php code look like this
<?php namespace Alomicuba\Profile;
use System\Classes\PluginBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Controllers\Users as UsersController;
/**
* Profile Plugin Information File
*/
class Plugin extends PluginBase
{
public $require = ['RainLab.User'];
/**
* Returns information about this plugin.
*
* #return array
*/
public function pluginDetails()
{
return [
'name' => 'Profile',
'description' => 'Add extra functionalities for Alomicuba WS by extends RainLab User',
'author' => 'DTS',
'icon' => 'icon-users'
];
}
public function boot()
{
UserModel::extend(function($model){
$model->hasOne['profile'] = ['Alomicuba\Profile\Models\Profile'];
});
UsersController::extendFormFields(function ($form, $model, $context){
if (!$model instanceof UserModel)
return;
$form->addTabFields([
'pinCode' => [
'label' => 'PIN',
'tab' => 'Profile'
],
'phone2' => [
'label' => 'Teléfono (2)',
'tab' => 'Profile'
],
'phone3' => [
'label' => 'Teléfono (3)',
'tab' => 'Profile'
],
'phone4' => [
'label' => 'Teléfono (4)',
'tab' => 'Profile'
]
]);
});
}
}
and in add_profiles_fields_to_user_table.php
for dropping column write following code
Schema::table('users', function($table)
{
$table->dropDown([
'pinCode',
'pinCodeDateTime',
'phone2',
'phone3',
'phone4'
]);
}
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 = [];
}