Reputation: 1773
how do you save a record (from a service) that has one of it's properties set as a OneToMany relationship with another entity?
I have the following service class for my users:
namespace Federico\Entity;
use Federico\Entity\User;
/**
* Description of UserService
*
* @author fiodorovich
*/
class UserService {
protected $em;
public function __construct ($em) {
$this->em = $em;
}
public function saveUser($user) {
if ($user['id'] != null) { //update
$entity = $this->getUser($user['id']);
//do something
if (!$entity)
throw new Exception('Error saving user!');
} else { //insert
$entity = new User();
foreach ($user as $k => $v) {
if ($k !== 'submit') {
if ($k == 'password') {
//echo $this->_salt;die;
$entity->$k = $this->createPass($v);
} else {
$entity->$k = $v;
}
}
}
}
$this->em->persist($entity);
$this->em->flush(); //save the user
}
//do something else...
}
But when I try saving the user and the countries property (a collection which refers to a OneToMany relationship oneUser-manyCountries) is set I get a "Class does not exist" exception.
EDIT: User and Countries entities
namespace Federico\Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Description of User
* @Table(name="users")
* @Entity
* @author fiodorovich
*/
class User
{
/**
* @var integer
* @Id @Column (name="id", type="integer", nullable=false)
* @GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* @Column(type="string",length=60,nullable=true, unique=true)
* @var string
*/
private $email;
/**
* @Column(type="string",length=60,nullable=true)
* @var string
*/
private $password;
/**
* @Column(type="string",length=60,nullable=true,unique=true)
* @var string
*/
private $url;
/**
* @Column(type="string",length=60,nullable=true,unique=true)
* @var string
*/
private $responsable;
/**
* @Column(type="string",length=20,nullable=true)
* @var string
*/
private $role;
/**
*
* @var datetime
* @Column(type="datetime", nullable=false)
*/
private $created;
/**
*
* @param \Doctring\Common\Collections\Collection $property
* @OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"})
*/
private $countries;
public function __construct()
{
$this->created = new \DateTime(date('Y-m-d H:i:s'));
$this->countries = new ArrayCollection();
}
public function __get($property)
{
return $this->$property;
}
public function __set($property, $value)
{
$this->$property = $value;
}
public function getCountries()
{
return $this->countries;
}
}
And Countries entity:
namespace Federico\Entity;
/**
* @Table(name="countries")
* @Entity
* @author fiodorovich
*
*/
class Countries {
/**
* @var integer
* @Id @Column (name="id", type="integer", nullable=false)
* @GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
*
* @var string
* @Column(type="string")
*/
private $countryName;
/**
*
* @var User
* @ManyToOne(targetEntity="User", inversedBy="id")
* @JoinColumns({
* @JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $user;
public function __get($property)
{
return $this->$property;
}
public function __set($property, $value)
{
$this->$property = $value;
}
}
Upvotes: 1
Views: 4735
Reputation: 8046
I do not see a line of code where you add a country to a user. If you want to add a country to a user keep in mind your $this->countries
is a collection and you need to threat it that way. The magical setter you use will not work for collections.
To add a country to a user you also have to add the user to the country:
$User->countries->add($CountryObject);
$CountryObject->user = $User;
Afterwards save it to the database:
$EntityManager->persist($User);
$EntityManager->persist($CountryObject);
$EntityManager->flush();
Good luck!
@la_f0ka
You have two options here. In your previous approach your magical setter didn't work properly, but your magical getter was fine. You can just keep using $user->email
instead of $user->getEmail()
. Both are fine. Some say the magical getter is a bit slower, but I never noticed it.
Just don't access your attributes public. This ruins your encapsulation which is one of the biggest powers of Object Orriented programming.
Upvotes: 0
Reputation: 85
Read the documentation Working With Associations. Especially the section Association Management Methods. That should give you an idea as to how to add a record to an association. You didn't put up the User class/entity so I'm assuming you're initializing the "countries" field in __construct. Also, your error indicates that the autoloader is having trouble finding the User class or the Country class, of which I did not see you import in the 'use' statement in your example. The error could be for that and may be what is keeping you from moving forward.
Upvotes: 1