Update doctrine entity with ArrayCollection field - doctrine-orm

I have problem with update entity with relations (one to many, many to one). I trying to add some new element to ArrayCollection when update, but nothing to do.
Here is my code of create and add relation:
$auctionPhoto = new AuctionPhoto();
$auctionPhoto->setAuction($auction);
$auctionPhoto->setPath($path);
$auction->getPhotos()->add($auctionPhoto);
All is running by doctrine entity listener (preUptade). The same code is do when I create entity (prePersist), but then is works fine.
I debug this and before persist I have in Auction object right relations, but nothing save to database.

Why do you do $auction->getPhotos()->add($auctionPhoto) ?
You should have a method addPhoto() or addAuctionPhoto() in your Auction entity, and use it like this:
$auction->addPhoto($auctionPhoto) or $auction->addAuctionPhoto($auctionPhoto)
EDIT:
Maybe your entity Auction is not the owner of the relation between the two entities, then you need to add $auctionPhoto->setAuction($auction), or if it's ManyToMany relation, then add $auctionPhoto->addAuction($auction)

Replace $auction->getPhotos()->add($auctionPhoto); with $auction->addPhoto($auctionPhoto);.
In your Auction entity, define the new method
// Auction.php
public function addPhoto(AuctionPhoto $thePhoto)
{
$this->photos[] = $thePhoto; // Add the photo to the object
$thePhoto->setAuction($this); // AuctionPhoto entity need to know about the reference
return $this; // Just for method chaining
}
(I assume $photos is your ArrayCollection which contains auction's photos)
Basically what you missed is to give a reference back to your entity:
$thePhoto->setAuction($this);

Are you saying nothing is in the database before you run this:
$em->persist($auction);
$em->flush();
If so, that is correct functionality. You need to persist then flush, then data is stored.

Related

Find the class name of a relation from the instance of a model in ember JS

I have foo an instance of the ember-data model thing. thing.js has the following property :
owner: DS.belongsTo('user')
If I have foo with an empty owner, how can I, with only foo and the 'owner' string, retrieve the value 'user' representing the model of the owner relation?
EDIT: I want to allow my select-relation component to works with relations where the name is different from the class name
It sounds like you have some work to do to finish setting up your relationships. Have a read through this page of the guides.
If the relationships are set up correctly, to get the associated user, you should be able to do foo.owner. This assumes that users are already present in the store. I recommend using the Ember Inspector browser plugin to debug the relationships.
This looks like a use case for typeForRelationship.
In your example you should be able to do something like
store.modelFor('thing').typeForRelationship('owner', store);
If you don't like that approach you can use the belongsTo reference API, where you use the meta data from the relationship to get the type
foo.belongsTo('owner').type
The only thing with that approach is that the type property may not be public API and possible (though unlikely) to change at some point.
It seems I can do the following :
this.get('model').get('_internalModel._relationships.initializedRelationships.'+this.get('relation')+'.relationshipMeta.type')
model being an instance and relation the string of the relation name, it correctly return the model of the relation.
EDIT : a better solution not using private API courtesy from the ember discord :
function getRelatedModelName(record, relationName){
let ParentModelClass = record.constructor;
let meta = get(ParentModelClass, 'relationshipsByName').get(relationName);
return meta.type;
}

how to consider annotation groups in a ObjectConstructor

JMSSerializer comes with a Doctrine Object Constructor that does its job, but imagine an Entity with two properties forming a primary key:
UserBase
prop annotated with #ORM\Id and #Serializer\Groups({"1"})
- username
prop annotated with #ORM\Id and #Serializer\Groups({"2"})
- email
User extends UserBase
- other props here, no Id defined.
one property key is excluded by using group=1 while deserializing. The client potentially still sends both email and username. email should not be considered though.
Unfortunately, if you pass the two properties in the body, DoctrineObjectConstructor does not check if something is excluded by deserialization, so it tries to load the Entity from the DB, according to the two values:
foreach ($classMetadata->getIdentifierFieldNames() as $name) {
if ( ! array_key_exists($name, $data)) {
return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
}
$identifierList[$name] = $data[$name];
}
What I would like to do is taking into account my annotated groups, so as to use the fallbackConstructor in case some property forming the identifier is missing.
As a starter this is a good point: I created my own service, by passing along the annotationDriver. Then, if the property forming the identifier is not associated with the actual group:
$classMetadata = $this->annotationDriver->loadMetadataForClass($metadata->reflection);
$classMetadata->properties //here groups are listed for each property
I can fall back to the fallbackConstructor, as if I had not passed that property in the body
...not so fast! My Entity User extends a UserBase where all my identifier are, so I should take into account hierarchy, possibly in a generic way.
Any hint?
Alright, JMSSerializer's Object Constructor does not consider serialization groups when determing identifiers. Hence, if you include all the IDs in your object, whether they are part of the actual context group or not, they will be counted in.
I created an alternative version of the Object in order to fix this misbehavior (at least for me). Hope it helps

django model inheritance & FK, could not create unique index

I want to be able to have a foreign key to a parent class, thereby allowing queries of the children classes as well. All other solutions are nightmarish.
I have tried to make this (Destination is also a parent class that has a # of children classes I want to relate to):
class Destination(PolymorphicModel)
class Account(Destination)
class Organization(Destination)
class Person(Destination)
class Transaction(models.Model)
destination = models.ForeignKey(Destination, verbose_name="Destination", null=True, blank=True,
related_name="CompletedTransaction_Destination_FK")
I am referencing destination in other places as well.
This is the error message I get when I try to migrate:
psycopg2.IntegrityError: could not create unique index "baseapp_organization_organization_destination_ptr_id_key"
DETAIL: Key (organization_destination_ptr_id)=(1) is duplicated.
I would love it if I could make the destination class
abstract = True
but then I can't have a foreign key. I need to be able to choose all of those destinations, and they need to remain distinct, real models in the database.
I have also tried GenericRelations, but that proved to be a nightmare as I said earlier.
It feels like I could just get around this error somehow though, any help?
The solution, and I'm guessing it would apply to other errors where the index could not be created, was to wipe the database an delete all the migrations. It was a pain to be sure, but now I can do:
destinations = Destination.objects.all()
and it will give me all the objects, as according to django polymorphic

Doctrine and ZF2

I am facing trouble using doctrine join. I can't share my code. But I can tell you scenario.
Please help me to achieve that.
I have created 2 entity. One User and Language.
User table is having foreign key language_id. and Language is master table with id and code fields.
I want to fetch user with some criteria, such a way it returns Language code from Language table as well.
I write join for that but it returns some full object...
Not sure how to fetch corresponding language code from Language table for language_id set in user table
If there is some example you know which can help me then also fine
i have return this in __construct()
$this->languageObj = new ArrayCollection();
when we print it is gives this
[languageObj:User:private] => Common\User\Entity\Language Object
(
[languageId:Language:private] => 1
[languageCode:Language:private] => en
[languageName:Language:private] => English
[languageCode2:Language:private] => User Object
RECURSION
)
I am not able to fetch languageCode from the object
You need methods defined in your entity to return the value from the object. It seems like everything is correct you would just need to grab the value from the entity. Here is an example:
$userEntity->getLanguageObj()->getLanguageId();
Your user Entity would need the getLanguageObj method which you can define like this:
public function getLanguageObj() {
return $this->languageObj;
}
And your Language Entity would also need a getLanguageId method:
public function getLanguageId() {
return $this->languageId;
}
Hope that helps!

symfony 1.4 and propel - foreign constraints fails saved relation

I am working in a Symfony 1.4 project with Propel 1.4.2.
I have 2 related tables. workshop and trainers which is a many to many relation mapped by a join table (workshop_trainers) which contains the workshop_id and the trainer_id).
In my Workshop Form I have a select box for adding the trainers to the workshop. The problem is when the workshop is new (Create) I get an error:
Cannot add or update a child row: a foreign key constraint fails
This happens because, when saving the workshop_trainers relation the workshop_id field is null. IsnĀ“t Propel intelligent enough to know that there is a relation between the tables and save the base object first? What I am doing wrong?
My trainer list widget.
$this->widgetSchema['workshop_trainer_list'] = new sfWidgetFormChoice(array(
'choices' => $trainers,
'multiple' => true,
));
Thanks for your help.
This is not fixing the problem but that's the easiest practical solution to this problem:
In the form, simply deactivate the workshop_trainer_list field if the object is a new one (doesn't have an ID yet).
Something like:
if ($this->getObject()->isNew())
{
$this->offsetUnset('workshop_trainer_list'); // not sure of that method name
}
A better solution is to update the doSave method to have the ID first, something like this:
protected function doSave($con = null)
{
$isNew = $this->getObject()->isNew();
if (null === $con)
{
$con = $this->getConnection();
}
// retrieve the value of workshop_trainer_list here and remove it from the form
$trainers = ...
$this->offsetUnset('workshop_trainer_list');
// save without it
parent::doSave($con);
// add it back
$this->getObject()->set...
// save
$this->getObject()->save($con);
}