How to use DataFixtureLoader

0

I'm relying on this tutorial , but I have the Country and State classes. I'm trying to import the data using the command:

php console doctrine:fixtures:load

When I run it works for CountryLoader , it loads the data and stores it in the database, but fails to load StateLoader.

The message it displays is:

[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Undefined index: country

How do I get the StateLoader to work?

CountryLoader.php

namespace Test\Bundle\TestBundle\DataFixtures\ORM;

use Hautelook\AliceBundle\Alice\DataFixtureLoader;

/**
 * Description of CountryLoader
 *
 */
class CountryLoader extends DataFixtureLoader {

    protected function getFixtures() {
        return array(
            __DIR__ . '/country.yml',
        );
    }

}

StateLoader.php

namespace Test\Bundle\TestBundle\DataFixtures\ORM;

use Hautelook\AliceBundle\Alice\DataFixtureLoader;

/**
 * Description of StateLoader
 *
 */
class StateLoader extends DataFixtureLoader {

    protected function getFixtures() {
        return array(
            __DIR__ . '/country.yml',
            __DIR__ . '/state.yml',
        );
    }

}

Country.php

/**
 * Description of Country
 * @ORM\Entity
 * @ORM\Table(name="country")
 */
class Country {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=64, unique=true) 
    */
        private $name;
    /**
     * @ORM\Column(type="string", length=8, unique=true) 
     */
    private $iso3;

    /**
     * @ORM\Column(type="string", length=8, unique=true) 
     */
    private $numcode;

    /**
     * @ORM\Column(type="string", length=8, unique=true) 
     */
    private $acronym;

    /**
     * @ORM\OneToMany(targetEntity="City", cascade={"all"}, mappedBy="country")
     * @var ArrayCollection
     */
    private $states;

    public function getId() {
        return $this->id;
    }
    public function getName() {
        return $this->name;
    }

    public function getIso3() {
        return $this->iso3;
    }

    public function getNumcode() {
        return $this->numcode;
    }

    public function getAcronym() {
        return $this->acronym;
    }

    public function getStates() {
        return $this->states;
    }

    public function setId($id) {
        $this->id = $id;
        return $this;
    }
    public function setName($name) {
        $this->name = $name;
        return $this;
    }
    public function setIso3($iso3) {
        $this->iso3 = $iso3;
        return $this;
    }

    public function setNumcode($numcode) {
        $this->numcode = $numcode;
        return $this;
    }

    public function setAcronym($acronym) {
        $this->acronym = $acronym;
        return $this;
    }

    public function setStates(ArrayCollection $states) {
        $this->states = $states;
        return $this;
    }

}

State.php

/**
 * Description of State
 * @ORM\Entity
 * @ORM\Table(name="state")
 */
class State {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
    /**
     * @ORM\Column(type="string", length=64, unique=true) 
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=8, unique=true) 
     */
    private $acronym;

    /**
     * @ORM\OneToMany(targetEntity="City", cascade={"all"}, mappedBy="state")
     * @var ArrayCollection 
     */
    private $cities;

    /**
     * @ORM\ManyToOne(targetEntity="Country", inversedBy="states", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="country_acronym", referencedColumnName="acronym", onDelete="CASCADE")
     * @var Country
     */
    private $country;

    public function getId() {
        return $this->id;
    }
    public function getName() {
        return $this->name;
    }

    public function getAcronym() {
        return $this->acronym;
    }

    public function getCities() {
        return $this->cities;
    }

    public function getCountry() {
        return $this->country;
    }

    public function setId($id) {
        $this->id = $id;
        return $this;
    }

    public function setName($name) {
        $this->name = $name;
        return $this;
    }
    public function setAcronym($acronym) {
        $this->acronym = $acronym;
        return $this;
    }

    public function setCities(ArrayCollection $cities) {
        $this->cities = $cities;
        return $this;
    }

    public function setCountry(Country $country) {
        $this->country = $country;
        return $this;
    }

}

country.yml

Test\Bundle\TestBundle\Entity\Country:
    BR: 
        iso3: BRA
        acronym: BR
        numcode: 76
        name: Brasil

state.yml

Test\Bundle\TestBundle\Entity\State:
    AC:
        acronym: AC
        name: Acre
        country: @BR    
    
asked by anonymous 07.04.2015 / 19:00

1 answer

1

There are some errors with your data modeling and I believe loading fixtures might be somehow related to this:

  • The foreign key of the country table in the state table is the acronym of the country instead of id ; this is not a very recommended practice - you should use id of the table.
  • Country fixtures ( country.yml ) are being loaded twice: on country loading and state loading. You do not need to create a class for each file. You can create a single class (for example, loadLocationData ) and load all data inherent to that domain.
  • In addition, I replicated your template here and saw that there are some problems in mapping the classes to the tables in the database. When you model a database using Doctrine, always try to use the doctrine:schema:validate command to see if there is no problem in the mapping. :)

        
    07.04.2015 / 21:08