Unable to locate factory with name on production? - php

I create a factory of a model inside an artisan command:
public function handle()
{
if (!$this->isDevelopment()) {
$this->errorMessageSwitchEnvToDev();
return;
}
$userId = $this->ask('Please specifiy user_id you want to add the payouts to.',2148);
$numberOfPayouts = $this->ask('How many payouts you want to generate?', 10);
factory(\App\Payout::class, $numberOfPayouts)->create([
'user_id' => $userId,
]);
}
The artisan works on my local desktop, but it does not work after deployment on my test server.
I get the following error message:
InvalidArgumentException : Unable to locate factory with name [100] [App\Payout].
at /www/htdocs/w0146a6f/dev/dev4.partner.healyworld.net/releases/20201014150056/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:269
265| */
266| protected function getRawAttributes(array $attributes = [])
267| {
268| if (! isset($this->definitions[$this->class][$this->name])) {
> 269| throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}] [{$this->class}].");
270| }
271|
272| $definition = call_user_func(
273| $this->definitions[$this->class][$this->name],
Exception trace:
1 Illuminate\Database\Eloquent\FactoryBuilder::getRawAttributes([])
/www/htdocs/w0146a6f/dev/dev4.partner.healyworld.net/releases/20201014150056/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:292
2 Illuminate\Database\Eloquent\FactoryBuilder::Illuminate\Database\Eloquent\{closure}()
/www/htdocs/w0146a6f/dev/dev4.partner.healyworld.net/releases/20201014150056/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php:122
I do the deployment with envoyer.
My factory is defined in database/factories/PayoutFactory.php
<?php
$factory->define(\App\Payout::class, function (Faker\Generator $faker) {
return [
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'amount' => $faker->randomFloat(2),
'req_amount' => 0,
'tax_amount' => 0,
'withheld' => 0,
'vat_rate' => $faker->randomNumber(2),
'released_amount' => $faker->randomFloat(2),
'released_amount_local_currency' => $faker->randomFloat(2),
'status' => 'released',
'flag' => 0,
'created_at' => $faker->dateTimeBetween('-6 months', 'now'),
];
});
However, it won't work on production. I already cleared the cache, the routes and called composer dump-autoload, but it still failes with the same issue.
Any suggestions?
I also read all answers of Laravel 5.2: Unable to locate factory with name [default] but none of them worked.

Notice this:
Unable to locate factory with name [100]
It looks like factory() is willing to use states instead of quantity. In this case it's looking for a factory state called (string) "100" instead of (int) 100
Cast your amount variable to be an integer
$numberOfPayouts = (int) $this->ask('How many payouts you want to generate?', 10);
Alternatively, try using ->times($amount) method to be more explicit.

Related

Inconsistent Data being associate on belongsTo

I am creating a feature test on one to many relationship. I just have a simple one to many relation with a proper setup base on the Laravel documentation. My test goes like this.
/** #test */
public function it_attach_containers()
{
$this->withoutExceptionHandling();
$vendor = factory(Vendor::class)->create();
$containersCount = 30;
$containers = factory(Container::class, $containersCount)->create();
$user = factory(User::class)->create();
$attributes = [
'vendor' => $vendor->id,
'ordered' => null,
'deployed' => null,
'last_contact' => null,
'containers' => $containers->pluck('name')
];
$response = $this->actingAs($user, 'api')
->withHeaders([
'X-Requested-With' => 'XMLHttpRequest'
])
->json('POST', '/api/deployments', $attributes);
$deployment = Deployment::find($containers[0]->id);
$this->assertInstanceOf(Deployment::class, $deployment);
$this->assertCount($containersCount, $deployment->containers()->get());
$this->assertDatabaseHas('deployments', [
'vendor' => $vendor->id,
'ordered' => null,
'deployed' => null,
'last_contact' => null
]);
}
The relation I have is a one to many relationship. A one deployment has many container. The code below is how I associate relation..
public function associateDeployment(Deployment $deployment, $data)
{
foreach ($data['containers'] as $containerName) {
$container = Container::where('name', $containerName)->first();
if (!$container) {
$container = Container::create([
'name' => $containerName,
'status' => true
]);
}
if (is_null($container->deployment_id)) {
$container->deployment()->associate($deployment);
$container->save();
}
}
}
The result on my test is really weird. sometimes it pass but sometimes not. I notice that the issue occur on the assertCount. as you can see on my test. it assert if the containers is 30. but mostly it didnt go up to 30. its about 25-29.. then sometimes it pass. what do you think is the problem?
I think the bug is the following line:
$deployment = Deployment::find($containers[0]->id);
Here you are fetching a deployment record by using container id. Instead use the following code:
$deployment = Deployment::find($containers[0]->deployment_id);

Phinx seeders work in console but not work in unit test

I have a project made with slim, Eloquent and Phinx and I am integrating PHPunit.
Everything works correctly except the new test that I need to perform an information seeder before executing the test.
The seed
<?php
use Phinx\Seed\AbstractSeed;
class Permissions extends AbstractSeed
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
[
'id' => '1',
'level' => 'admin',
'created_at' => date('Y-m-d H:i:s'),
],
];
$level = $this->table('users_levels');
$level->insert($data)
->save();
$data = [
[
'users_level_id' => '1',
'method' => 'GET',
'url' => '/api/events/{date:\d{4}-\d{1,2}-\d{1,2}}',
'created_at' => date('Y-m-d H:i:s'),
],
[
'users_level_id' => '1',
'method' => 'POST',
'url' => '/api/event',
'created_at' => date('Y-m-d H:i:s'),
],
];
$urls = $this->table('level_urls');
$urls->insert($data)
->save();
}
}
I run it from the console works perfectly,
C:\xampp\htdocs\CirceApi> .\vendor\bin\phinx seed:run
Phinx by CakePHP - https://phinx.org. 0.8.1
using config file .\phinx.php
using config parser php
using migration paths
- C:\xampp\htdocs\CirceApi\database\migrations
using seed paths
- C:\xampp\htdocs\CirceApi\database\seeds
warning no environment specified, defaulting to: development
using database circe
== Permissions: seeding
== Permissions: seeded 0.1773s
but when I launch it in the following way for the tests
use Phinx\Console\PhinxApplication;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
protected function runMigration()
{
$app = new PhinxApplication();
$app->setAutoExit(false);
$app->doRun(new StringInput("migrate"), new NullOutput());
$app->doRun(new StringInput("seed:run"), new NullOutput());
}
it returns the following error.
14) Tests\Profile\ProfileTest::it_returns_404_status_code_when_profile_is_not_found
PDOException: SQLSTATE[HY000]: General error: 1 table users_levels has no column named level
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Db\Adapter\PdoAdapter.php:215
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Db\Adapter\AdapterWrapper.php:191
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Db\Adapter\TimedOutputAdapter.php:125
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Db\Table.php:667
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Db\Table.php:610
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Db\Table.php:697
C:\xampp\htdocs\CirceApi\database\seeds\Permissions.php:29
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Migration\Manager\Environment.php:156
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Migration\Manager.php:403
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Migration\Manager.php:536
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Console\Command\SeedRun.php:110
C:\xampp\htdocs\CirceApi\vendor\symfony\console\Command\Command.php:255
C:\xampp\htdocs\CirceApi\vendor\symfony\console\Application.php:901
C:\xampp\htdocs\CirceApi\vendor\symfony\console\Application.php:262
C:\xampp\htdocs\CirceApi\vendor\robmorgan\phinx\src\Phinx\Console\PhinxApplication.php:83
C:\xampp\htdocs\CirceApi\tests\UseDatabaseTrait.php:19
C:\xampp\htdocs\CirceApi\tests\BaseTestCase.php:44
ERRORS!
Tests: 17, Assertions: 7, Errors: 14.
Thanks for the help.
Try this:
use Phinx\Console\Command\SeedRun;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
$phinxApplication = new Application();
$phinxApplication->add(new SeedRun());
$phinxSeedRunCommand = $phinxApplication->find('seed:run');
$phinxCommandTester = new CommandTester($phinxSeedRunCommand);
$phinxCommandTester->execute(['command' => $phinxSeedRunCommand->getName()]);
$phinxDisplay = $phinxCommandTester->getDisplay();
$phinxStatusCode = $phinxCommandTester->getStatusCode();
if ($phinxStatusCode > 0) {
throw new RuntimeException('Seed:run failed');
}

Laravel 5.1 factory definition unable to resolve closure for foreign relationships

I'm having trouble defining the factory function to handle foreign relationships for my business model. This is the code for my business model factory. The error message that I am getting is :
Uncaught exception 'ErrorException' with message 'Object of class
Closure could not be converted to string' in
/Users/patricia/Code/thank-views/vendor/laravel/framework/src/Illuminate/Database/Connection.php:390
Stack trace
It seems that it is unable to resolve the id for the user. When I run it in tinker it creates the model with a closure function for those fields. However I want to be able to generate these models to be used for my BusinessTest class. It's unable to resolve these dependencies. I'm not sure whether the best place to resolve these dependencies should be in the ModelFactory or elsewhere in the codebase.
$factory->define(App\Business::class, function (Faker\Generator $faker) {
return [
'slug' => $faker->word,
'name' => $faker->name,
'end_card' => $faker->word,
'white_label' => $faker->boolean,
'white_label_url' => $faker->word,
'payment_header' => $faker->word,
'payment_amount' => $faker->randomNumber(),
'payment_amount_display' => $faker->word,
'payment_cost' => $faker->randomNumber(),
'payment_activated' => $faker->boolean,
'main_user_id' => function () {
return factory(App\User::class)->create()->id;
},
];});
You can it change to:
'main_user_id' => $factory->create(\App\User::class)->id
or:
'main_user_id' => $faker->unique()->numberBetween($min = 1, $max = 50)
or:
'main_user_id' => $faker->unique()->randomDigit

relationship is not working - Laravel / phpunit / Sqlite

I am coding a test, but I get some unexpected results in basic relationships. I use in memory sqlite db.
Those test were working well with MySQL db. I guess it has something to do with this migration.
$tournament0 = factory(Tournament::class)
->create(['user_id' => $this->simpleUser->id]);
$this->simpleUser is created on setUp() method
Now, when $this->simpleUser->tournaments should return $tournament0, but it is empty.
My relationship is working, it is not broken. Also, when testing manually in the browser, it works.
It just fail when using phpunit...
Here is the setUp() Method:
public function setUp()
{
parent::setUp();
$this->simpleUser = factory(User::class)->create(['role_id' => Config::get('constants.ROLE_USER')]);
}
Full method that is failing:
/** #test */
public function dashboard_check_initial_state()
{
Artisan::call('db:seed', ['--class' => 'CountriesSeeder', '--database' => 'sqlite']);
Artisan::call('db:seed', ['--class' => 'TournamentLevelSeeder', '--database' => 'sqlite']);
Artisan::call('db:seed', ['--class' => 'CategorySeeder', '--database' => 'sqlite']);
// Given
$this->logWithUser($this->simpleUser);
// Nothing has been created, default dash
$this->visit('/')
->see(trans('core.create_new_tournament'))
->dontSee(trans('core.congigure_categories'));
// Create 1 tournament
$tournament0 = factory(Tournament::class)->create(['user_id' => $this->simpleUser->id]);
$this->visit('/')
->seeInElement("p.text-muted", trans('core.no_tournament_created_yet'));
// Now configure 2/2 categories
$championship1 = factory(Championship::class)->create(['tournament_id' => $tournament0->id,'category_id'=>1]);
$championship2 = factory(Championship::class)->create(['tournament_id' => $tournament0->id,'category_id'=>2]);
factory(ChampionshipSettings::class)->create(['championship_id' => $championship1->id]);
factory(ChampionshipSettings::class)->create(['championship_id' => $championship2->id]);
$this->visit('/')
->seeInElement("span.text-muted", trans('core.congigure_categories'));
}
Any idea what can it be?

Laravel factory returns 0 for field, stores number in database

I have a laravel factory that looks like this:
$factory->define( Municipality::class, function ( Generator $faker ) {
return [
'name' => $faker->city,
'number' => (int) $faker->numerify( '####' )
];
} );
If I run php artisan tinker and use the factory like this factory(Acme\Models\Municipality::class)->create, I get the output
=> Acme\Models\Municipality {#797
name: "West Alysaland",
number: 0,
}
When I run Acme\Models\Municipality::all() I get
>>> Municipality::all();
=> Illuminate\Database\Eloquent\Collection {#771
all: [
Acme\Models\Municipality {#798
number: 9449,
name: "Lake Rosemarie",
},
],
}
number is set as fillable in the model and the field is set to unsignedInteger in the migration.
Do anyone have any idea why this happens?
Edit:
After some debugging I found out that this happened after ->save() was called on the model.
The model did not have an auto incrementing primary key, so I needed to set public $incrementing = false; in the model.

Categories