Giter VIP home page Giter VIP logo

Comments (14)

pabloelcolombiano avatar pabloelcolombiano commented on May 14, 2024

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.

rtrochim avatar rtrochim commented on May 14, 2024

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.

pabloelcolombiano avatar pabloelcolombiano commented on May 14, 2024
  1. Helpful would be the output of
    InvoiceFactory::make()->withCustomers()->getEntity()->toArray();
    and
    CustomerFactory::make()->with('Invoices.DeliveryAddresses')->getEntity()->toArray();

  2. 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

  1. 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 of Customers, and thus in the InvoiceFactory name the method withCustomer instead of withCustomers. This reflects the model's logic a bit clearer. But again, it should work without doing that.

from cakephp-fixture-factories.

rtrochim avatar rtrochim commented on May 14, 2024

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.

pabloelcolombiano avatar pabloelcolombiano commented on May 14, 2024

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.

rtrochim avatar rtrochim commented on May 14, 2024

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.

rtrochim avatar rtrochim commented on May 14, 2024

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.

pabloelcolombiano avatar pabloelcolombiano commented on May 14, 2024

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.

rtrochim avatar rtrochim commented on May 14, 2024

Tried that, no effect

from cakephp-fixture-factories.

rtrochim avatar rtrochim commented on May 14, 2024

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.

dreamingmind avatar dreamingmind commented on May 14, 2024

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.

pabloelcolombiano avatar pabloelcolombiano commented on May 14, 2024

@rtrochim Do you have a concrete example illustrating that?

I agree with dreamingmind.

from cakephp-fixture-factories.

pabloelcolombiano avatar pabloelcolombiano commented on May 14, 2024

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.

rtrochim avatar rtrochim commented on May 14, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.