Reputation: 51
I have run into a problem that defies all my attempts to unproblem it. Its probably simple, I have just totally exhausted myself on this one :)
Basically I want to give the user the ability to add modules (facebook id, a bio, text inputs) and assets (image logo, pdf, et al) to a page object.
I have set up a onetomany relationship for Module and Asset to Page.
Module works as expected, however Asset will not work at all: when PageController calls getAsset() from its entity, it is null. There is no error until I try to iterate over the Assets.
Also, in PageController there are the following namespace declarations:
use Linkme\SiteBundle\Entity\Module;
use Linkme\SiteBundle\Entity\Asset;
If I remove the Module declaration I get an error, but if I remove the Asset line, nothing changes. Therefore I believe the relationship is not created.
If I run
app/console doctrine:schema:create --dump-sql
then amongst others I get the following line:
ALTER TABLE Asset ADD CONSTRAINT FK_C36E75589D3B65E3 FOREIGN KEY (pageId) REFERENCES Page(id);
which makes me think the schema is correct. It as least understands Asset is related to Page
Im starting to feel I have a typo or I am totally missing something equally as obvious - any assistance on troubleshooting or other suggestions would be much appreciated!
app/console --version
Symfony version 2.0.1 - app/dev/debug
Page.php
/*
* @ORM\OneToMany(targetEntity="Asset", mappedBy="pageId", cascade={"persist", "remove"})
* @ORM\OrderBy({"type" = "ASC"})
* @ORM\OrderBy({"id" = "ASC"})
*
* @var ArrayCollection $assets
*/
protected $assets;
/**
* @ORM\OneToMany(targetEntity="Module", mappedBy="pageId", cascade={"persist", "remove"})
* @ORM\OrderBy({"type" = "ASC"})
* @ORM\OrderBy({"id" = "ASC"})
*
* @var ArrayCollection $modules
*/
protected $modules;
/**
* Set assets
* @param Asset $assets
*/
public function setAssets(Asset $assets = null)
{
$this->assets = $assets;
}
/**
* Get assets
*
* @return Asset
*/
public function getAssets()
{
echo '<br />Asset is '.gettype($this->assets); // outut: Asset is NULL
return $this->assets;
}
/**
* Set modules
* @param Module $modules
*/
public function setModules(Module $modules = null)
{
$this->modules = $modules;
}
/**
* Get modules
* @return Module
*/
public function getModules()
{
echo '<br />Module is '.gettype($this->assets); // output: Module is object
return $this->modules;
}
Asset.php
/**
* @var integer $pageId
*
* @ORM\ManyToOne(targetEntity="Page", inversedBy="assets")
* @ORM\JoinColumn(name="pageId", referencedColumnName="id")
*/
protected $pageId;
Module.php
/**
* @var integer $pageId
*
* @ORM\ManyToOne(targetEntity="Page", inversedBy="modules")
* @ORM\JoinColumn(name="pageId", referencedColumnName="id")
*/
protected $pageId;
PageController.php
use Linkme\SiteBundle\Entity\Module;
use Linkme\SiteBundle\Entity\Asset;
/**
* Add modules and assets to a page
*
* @Route("/{id}/wizardmodule", name="page_wizardmodule")
* @Template()
*/
public function wizardmoduleAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$page = $em->getRepository('LinkmeSiteBundle:Page')->find($id);
$modules = $page->getModules();
$assets = $page->getAssets();
depmod
[symfony]
git=http://github.com/symfony/symfony.git
version=v2.0.1
[twig]
git=http://github.com/fabpot/Twig.git
version=v1.1.2
[monolog]
git=http://github.com/Seldaek/monolog.git
version=1.0.1
[doctrine-common]
git=http://github.com/doctrine/common.git
version=2.1.1
[doctrine-dbal]
git=http://github.com/doctrine/dbal.git
version=2.1.1
[doctrine]
git=http://github.com/doctrine/doctrine2.git
version=2.1.1
[swiftmailer]
git=http://github.com/swiftmailer/swiftmailer.git
version=v4.1.1
[assetic]
git=http://github.com/kriswallsmith/assetic.git
version=v1.0.1
[twig-extensions]
git=http://github.com/fabpot/Twig-extensions.git
[metadata]
git=http://github.com/schmittjoh/metadata.git
version=1.0.0
[SensioFrameworkExtraBundle]
git=http://github.com/sensio/SensioFrameworkExtraBundle.git
target=/bundles/Sensio/Bundle/FrameworkExtraBundle
version=v2.0.1
[JMSSecurityExtraBundle]
git=http://github.com/schmittjoh/JMSSecurityExtraBundle.git
target=/bundles/JMS/SecurityExtraBundle
version=v2.0.1
[SensioDistributionBundle]
git=http://github.com/sensio/SensioDistributionBundle.git
target=/bundles/Sensio/Bundle/DistributionBundle
version=v2.0.1
[SensioGeneratorBundle]
git=http://github.com/sensio/SensioGeneratorBundle.git
target=/bundles/Sensio/Bundle/GeneratorBundle
version=v2.0.1
[AsseticBundle]
git=http://github.com/symfony/AsseticBundle.git
target=/bundles/Symfony/Bundle/AsseticBundle
version=v1.0.0
Upvotes: 1
Views: 1881
Reputation: 51
I got it! and as I predicted, it was an incredibly annoying PEBKAC....
The relationship was not being created because the annotations were not being read, because I was missing a * on the annotations comment box..... ddddoooohhhhh!
Page.php
Before:
/* <========================== there is only one * here. It needs to be two: **
* @ORM\OneToMany(targetEntity="Asset", mappedBy="pageId", cascade={"persist", "remove"})
* @ORM\OrderBy({"type" = "ASC"})
* @ORM\OrderBy({"id" = "ASC"})
*
* @var ArrayCollection $assets
*/
protected $assets;
After:
/** <========================== like this.
* @ORM\OneToMany(targetEntity="Asset", mappedBy="pageId", cascade={"persist", "remove"})
* @ORM\OrderBy({"type" = "ASC"})
* @ORM\OrderBy({"id" = "ASC"})
*
* @var ArrayCollection $assets
*/
protected $assets;
I'd just like to say a big thanks to everyone who helped out with this problem.
Upvotes: 2
Reputation: 1896
This is because you don't initialize your $assets collection in your Page constructor.
public function __construct(){
$this->assets = new ArrayCollection();
}
Then I think you haven't run the doctrine:generate:entities command, it simplifies your life a little, creating get, set and add methods for every mapped field. In your case it would create a
public function addModules(Module $modules)
{
$this->modules[] = $modules;
}
Note that actually you simply assign $modules to $this->modules, this is wrong, it's an array not a scalar.
And to add the reference to the page referred by every module you'll have to add another instruction:
public function addModules(Module $modules)
{
$this->modules[] = $modules;
$modules->setPage($this);
}
I've done this in my code and it works, let me know if it works for you too, bye
Linuxatico
Upvotes: 0
Reputation: 1204
Do you correctly initialize collections into your page constructor?
Upvotes: 0