I have an entity which has one-to-one relationship to the user table. The entity uses the foreign key user_id as a primary key and it doesn't have it's own auto-incrementing id field.
When I added this entity to the auditable entities, every time this entity is persisted and flushed I get an exception, that the User entity can't be converted to integer.
Digging into the code of the bundle I found out that the postFlush method of the LogRevisionsListener executes a piece of code that tries to build a query. It uses entity manager to gather info about the entity and the field types, but from what I see my case is not covered.
The code gets the type of the identifier(primary key) using the entity manager associationMappings which in this case is '1' (integer), because the primary key is a 'relationship', and because of that then it tries to cast to int and fails. Looking at the code it looks like it should get the type of the associationMappings identity column (a.k.a get the type from the primary key of the relationship).
Does someone know how can this be handled or worked around. Or maybe I'm doing something wrong? Any tips will be much appreciated, thanks!
I'm using the Sonata Admin and currently trying to get me to be able to change my query to every click event in the sonata_type_collection.
I have the 'Variation' entity in which it contains the collection type in the form to call the entity 'Value'.
However, this 'Value' entity contains an auto relationship to reference parent values and child values ex: (Id 1 does not contain any parent, so its field will be null, but id 2 contains a parent value, putting id 1 in the parent field parent).
The idea was that with each click that was given to add a new row of values, check the previous row and perform a new query to bring only the "child values".
Take a look into the SonataMediaBundle and SonataClassificationBundle source code it seems there is a similar case like you described.
I have a form built in Symfony 2.8 and I have been stumped for a few days trying to work out why a field will not populate.
So I have a form that is inserting a product for an order and the fields are all posting but the insert query is not picking up the data. It thinks the field is null.
Any suggestions?
First check your inserted data is valid for price field or change your price field nullable true.
If it's not helping you then describe your code descriptively.
For a project I need to check if all form's fields are present in a PUT request.
Simple data validation with the NotNull / NotBlank constraints is not appropriate because the fields in the request can be set with NULL or blank values but they have to be present.
My idea is to take all names from a Form's field and check if those fields are present in the request array.
To do the trick I need to get names of those fields, there's an array in the Form class named orderedKeys which contains exactly what I want, but the variable is set to private.
Is there any other way to get access to those keys ?
You can get all the child forms of a form by doing
$form->all();
Then you can recover the name of each field by doing
$child->getName();
In Symfony2, if I embed a collection of forms pointing at a many to one relationship in Doctrine and allow adding and deletion, if I delete a record from the beginning, add one at the end, and edit some in the middle how does the system know which records to update with which data?
There is nothing in the tutorial that passes the primary key of the embedded data around. Under certain circumstances, my records are getting needlessly deleted and added again rather than edited in place (even if there are no changes to the particular record). This breaks the fields on the records that are not included on the form, setting them to their default values from the DB model.
Is there a way to pass the primary key in the form and have it used to perform updates when the data comes back?
If you want to index the collection (by the entity id) for all querys, you can simply use the indexBy annotation in your entity class.
/**
* #ORM\OneToMany(targetEntity="EntityClass", mappedBy="EntityVariable", indexBy="id")
*/
private $collection;
Based on the Akkumulator's answer and comment and some experimentation, I did this:
Create new fields (using Javascript as described in the documentation) with __name__ replaced not by a number but by a string: new_ followed by an forever increasing number that has nothing to do with the list (e.g. new_1, new_2, new_3...)
I don't have to push the primary keys into the forms and I don't need indexBy either - that's good, because indexBy felt like it was too far removed from the form, ending in having the Action at a distance anti-pattern.
Why this works:
PHP arrays aren't like those in other languages. They're always dictionaries, so you can add string keys to them even if they only have numeric keys to start with.
Because the Symfony collection is mapped by field name, new fields will not match existing data and deleted fields will not be matched to existing data (and thus be removed from the set)
One way to pass primary id is to use INDEX BY.
For example, say I have an entity called Customer and a Customer has several Emails. In my Customer repository class, I can specify my collection to be indexed by Email's primary id.
$qb->select('c, e')
->leftJoin('c.emails', 'e', null, null, 'e.id')
->where('c.id = :id');
By doing so, the generated name of the input tag would be
customer[emails][e.id][fieldName]
Upon submitting the form, Symfony will bind the request values according to the input names.