Comments (14)
Hi,
A question before I further dig: did you modify the factories after baking them? If yes, please kindly share the code of all 3 factories. This will help me provide you a solution to your two issues.
from cakephp-fixture-factories.
InvoicesFactory was not modified, I only added some default data to CustomersFactory using faker such as username, password etc. I will add the exact code later this day
from cakephp-fixture-factories.
-
Helpful would be the output of
InvoiceFactory::make()->withCustomers()->getEntity()->toArray();
and
CustomerFactory::make()->with('Invoices.DeliveryAddresses')->getEntity()->toArray();
-
Are there some required fields in the invoices table, that you did not populate?
The saving of belongsTo associations is covered by the package, so I do not see for the moment where the issue comes from.
The package's tests cover a similar case here:
https://github.com/pakacuda/cakephp-fixture-factories/blob/master/tests/TestApp/src/Model/Table/AddressesTable.php
https://github.com/pakacuda/cakephp-fixture-factories/blob/master/tests/Factory/AddressFactory.php
Where the AddressesTable belongs to a City.
Tests pass when calling AddressFactory::make()->withCity()->persist();
For example in this test:
https://github.com/pakacuda/cakephp-fixture-factories/blob/master/tests/TestCase/Factory/BaseFactoryTest.php#L690
- The only difference I see, is that the associated model is singular cased. This should not be an issue, but you may try calling your association in the InvoicesTable
Customer
instead ofCustomers,
and thus in the InvoiceFactory name the methodwithCustomer
instead ofwithCustomers
. This reflects the model's logic a bit clearer. But again, it should work without doing that.
from cakephp-fixture-factories.
Here are my three factories:
InvoiceFactory.php
class InvoiceFactory extends CakephpBaseFactory
{
protected function getRootTableRegistryName(): string
{
return 'Invoices';
}
protected function setDefaultTemplate(): void
{
$this->setDefaultData(function(Generator $faker) {
return [];
});
}
public function withCustomers(array $parameter = null): InvoiceFactory
{
return $this->with(
'Customers',
\App\Test\Factory\CustomerFactory::make($parameter)
);
}
public function withDeliveryAddresses(array $parameter = null): InvoiceFactory
{
return $this->with(
'DeliveryAddresses',
\App\Test\Factory\DeliveryAddressFactory::make($parameter)
);
}
}
CustomerFactory.php
class CustomerFactory extends CakephpBaseFactory
{
protected function getRootTableRegistryName(): string
{
return 'Customers';
}
protected function setDefaultTemplate(): void
{
$this->setDefaultData(function(Generator $faker) {
return [
'name' => $faker->name,
'login' => $faker->userName,
'password' => $faker->password
];
});
}
public function withInvoices(array $parameter = null, int $n = 1): CustomerFactory
{
return $this->with(
'Invoices',
\App\Test\Factory\InvoiceFactory::make($parameter, $n)->without('Customers')
);
}
}
DeliveryAddressFactory.php
class DeliveryAddressFactory extends CakephpBaseFactory
{
protected function getRootTableRegistryName(): string
{
return 'DeliveryAddresses';
}
protected function setDefaultTemplate(): void
{
$this->setDefaultData(function(Generator $faker) {
return [
'address' => $faker->address
];
});
}
public function withInvoices(array $parameter = null): DeliveryAddressFactory
{
return $this->with(
'Invoices',
\App\Test\Factory\InvoiceFactory::make($parameter)
);
}
}
Here are requested outputs:
InvoiceFactory::make()->withCustomers()->getEntity()->toArray();
results in an empty array
[]
The line below
CustomerFactory::make()->with('Invoices.DeliveryAddresses')->getEntity()->toArray();
results in
[
"name" => "John Doe",
"login" => "bernhard.gilda",
"password" => "$2y$10$5snFBm8XALfTU6AKCQxy4eZ6KXD0NqLGdCEnNwQpOesfKZTG3PmH2",
"invoices" => [
[],
],
]
My invoices table for now only has the following fields: id, customer_id, delivery_address_id, created, modified. Only the first two are required.
I do not really understand your third point. CakePHP conventions are clear that association names are plural and so are their table names. If i singularize my association from Customers to Customer, Cake will look for the table called customer instead of customers which produces errors.
from cakephp-fixture-factories.
Regarding the third point, you simply have to set the key className
to customers
, and the association Customer
will work. This is illustrated in the examples I sent you.
from cakephp-fixture-factories.
All right i managed to resolve the first issue with renaming the association as you pointed out. Now it gets correctly saved.
However singularizing the associations in InvoicesTable and DeliveryAddressesTable did not work as expected, the DeliveryAddress record is still not saved when using.
CustomerFactory::make()->with('Invoices.DeliveryAddresses')->persist();
from cakephp-fixture-factories.
I found out that when using
DeliveryAddressFactory::make()->with('Invoices.Customer')->persist();
All three entities are correctly saved. I have no idea why it does not work the other way.
from cakephp-fixture-factories.
How about if you singularize the association DeliveryAddresses
to DeliveryAddress
?
There might be an issue in the package, the saving should work regardless of the name of the association. But if this worked, you could at least keep on working for the moment. I'll be able to search for a bug only by next week.
from cakephp-fixture-factories.
Tried that, no effect
from cakephp-fixture-factories.
I found out that association saving really does depend heavily on association name. Especially whether it's plural or singular. After setting all properties in my entities to accessible with
protected $_accessible = [
'*'=> true
]
i noticed that sometimes the association ends as an array istead of an entity instance with incorrect property name.
I would seem that FixtureFactory does not extract the correct property name from association, especially hasOne/belongsTo.
from cakephp-fixture-factories.
I have found that the native singularization/pluralization of 'Address/Addresses' is un predictable. I've had to add this rule:
Inflector::rules('singular', ['/^(.*)(address)$/i' => '\1\2']);
and make sure it gets run in both my app and the testing bootstrap
from cakephp-fixture-factories.
@rtrochim Do you have a concrete example illustrating that?
I agree with dreamingmind.
from cakephp-fixture-factories.
I have fixed the issue of non saved plural toOne association.
As described in the documentation here:
https://book.cakephp.org/3/en/orm/saving-data.html#saving-belongsto-associations
the associated data should be singular, which the package did not consider.
This is now fixed, you may update the package with its latest version.
I personally prefer naming my toOne associations singular, but if you don't, feel free rename your associations plural, and please let me know if it worked for you.
I will close this issue in three days, if this alright for you.
from cakephp-fixture-factories.
Everything now works correctly.
Thank you for your time and contribution. This plugin really does ease handling test data.
Cheers!
from cakephp-fixture-factories.
Related Issues (20)
- Skip cake entity setter when set fields data HOT 5
- How to specify database connection other than `test`? HOT 1
- How to nest ->with() HOT 2
- Feature requests: Enhancements to configuration HOT 6
- Recurrent PersistenceExceptions thrown in factories due to Primary Key collisions HOT 6
- Fix Psalm
- Composer require no DB cleaner
- Calling fixture factories for a table breaks application code that uses that table downstream HOT 4
- Primary key of type text should generate UUID HOT 1
- What is the mergeAssociated(array $data) function for? HOT 1
- Testing simple method without persisting data HOT 1
- fakerphp 8.2 warnings HOT 1
- Creating multiple translations using shadowStrategy HOT 1
- Truncate Dirty Tables Slowness HOT 2
- Feature Request: Add back-reference property to sub-entities HOT 5
- Error: Column "id" is an identity column defined as GENERATED ALWAYS HOT 1
- Feature Request: Ability to set nested values using `make` method HOT 2
- Enhance array notation
- Calling `with()` inside `setDefaultTemplate()` occurs unexpected increase of the associated entities HOT 4
- phpdoc @param types of `FactoryAwareTrait::getFactory()` is too narrower than acceptable types HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cakephp-fixture-factories.