简体   繁体   中英

Struggling with one-to-many relation in an admin form

I do apologize if the answer to my question would be very obvious. I am new to Symfony and I wasn't able to find another question with exactly the same issue as mine at SO, thus I am posting a question. (And Google didn't help much either, but then again I am not very familiar with Symfony's terminology, so I might have worded my queries badly.)

So, straight to the point. The schema.yml :

user:
  id:
  email:   { type: varchar, size: 255, required: true }
  ... # etc.

partner:
  user_id: { type: integer, foreignTable: user, foreignReference: id }

(BTW, using Symfony 1.3 and Propel 1.4).

So I have $user->getPartners() and $partner->getUserId() methods generated (even though I read somewhere that if your FK is a PK in the referenced table, Propel forces one-to-one relationship, but I observe one-to-many, unless I got it very wrong). Fine. However, I have an admin module to edit an User and at the moment I am struggling to even understand how exactly am I to make Symfony show a multiple-select list of Partners in the "User/edit" form (double list would be fine too).

Tried with putting "partners" and "partner_list" in apps/backend/modules/user/generator.yml (where I successfully added a boolean and a static-choice [via *Peer::getXXXChoices() ] fields already), only to get errors "Widget 'partners' doesn't exist".

I could go edit the form class I guess, but I have no idea how to tell Propel to form a one-to-many visual relationship using "multiple = true", because "choices" isn't static; it depends on another table.

So how do I do this? Feel free to ask for additional details if I did omit something crucial.

Regards.

I had come across the same problem once so this is my solution to the problem. Symfony is not very smart in this kind of situations, so you need to help it a bit. The model you describe is perfeclty good relational model interpretation of the problem:

user:
  id:
  email:   { type: varchar, size: 255, required: true }
  ... # etc.

partner:
  user_id: { type: integer, foreignTable: user, foreignReference: id }

Thing is that Symfony really simplifies it and when Propel generates forms and generator parses submition forms in order to save data, it interprets the user_id field like if it was any normal field (not in a one-to-many way ).

So if you really want that multiselect created by symfony and all logic behind it to be generated for you, you will need to create a many to many relation between those two classes. The schema should end up something like this:

user:
  id:
  email:   { type: varchar, size: 255, required: true }
  ... # etc.

partner:
  user_id: { type: integer, foreignTable: user, foreignReference: id }

user_partner:
  user_id: { type: integer , foreignTable: user, foreignReference: id, primaryKey: true}
  partner_id: { type: integer , foreignTable: partner, foreignReference: id, primaryKey: true}

This way you will have the partner_list widget in the user form and also the user_list widget in the partner form. I always unset the one i dont need and really works like a charm.

The other solutions, the one that fits best your model implementation is a bit more complex becase you'll need to modify the UserForm and add a partner_ids multiselect widget then modify the doSave method to be able to handle the multiselect save logic (create instances , associate them to the user and save them, also remove the ones not selected).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM