-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Documenting how to keep option value BC - see #14377 #14825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Is that intended? To me, if that is the solution, the |
@xabbuh Good point - there is a confusion between "value" as in "this is the value that will be returned by the form" and "value" as in "this is the value attribute of the option". These are not the same thing, so it can be confusing. But yes, I believe this is all intended. |
@xabbuh if I understood the initial implementation correctly The reason behind this change was to easily allow values of types other than int or string as choice values. This was apparently implemented by ignoring the model value when creating the html This should be documented, but it is no BC issue as the option previously just didn't exist. |
@apfelbox If I understand you correctly, it is nothing more than a trigger for the |
@xabbuh something in this direction. It is a way to provide both a) a comfortable and minimally verbose way of configuring the choices option (no object, nothing to implement just a plain array) and b) supporting model values in this compact form that don't work as PHP array keys (floats, objects, etc..). I guess historically the array was defined this way, because the assumption was that the model values will be unique per options. Now the realization came, that the label probably is unique per option, too (otherwise the user can't differentiate different values). And by using this direction one can use any arbitrary type as model data – as the label is required to be a string it is optimal for usage in the array keys. But as arbitrary model data can't be embedded into the So therefore... it is more of a convenience method of expanding the usage of the compact choice array definition. (... but as I keep thinking about that, I just realized that there is another possible issue with this implementation (maybe someone could verify that): as the choices are just numbered now, the order of the choices in the array suddenly becomes important. Although it would be weird for these options to have an arbitrary order, this currently would produce wrong results in the current implementation ("wrong" as in you select option "a", but after page refresh you selected option "b"). Probably not frequent enough, but I just wanted to mention it.) |
I have a situation where I have duplicate labels, but they are in different groups. I'm not 100% sure if this use case is supported, as I'm still trying to make sense of the changes. |
@davedevelopment I've thought about this - I believe the answer is that you should make your array keys unique, but then use I'm with you - I understand why the change was made, but I'm still making sense of it too :). |
@weaverryan you legend, just fixed something in 3 minutes that I've been working on for about 3 hours :) |
And the fix is in production, thanks again @weaverryan, I owe you big time |
@davedevelopment too nice :) |
@webmozart I'm pretty sure this is an easy merge into the UPGRADE log - we just need you to confirm - thx :) |
@weaverryan Why is the change even required? It feels kind of weird. |
👍 |
Thank you @weaverryan. |
…averryan) This PR was merged into the 2.7 branch. Discussion ---------- Documenting how to keep option value BC - see #14377 | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #14377 (kinda) | License | MIT | Doc PR | symfony/symfony-docs#5179 Hi guys! I'm still making sense of the form changes, but it seems that this before and after isn't totally honest - your option values will change, unless your add this extra option. @webmozart look correct to you? Thanks! Commits ------- deb9db8 Documenting how to keep option value BC - see #14377
This change makes no sense to me. Why not use the choice as option value by default as before? That looks like the better default. With this change, developers have to ensure the options are always sorted by ID basically and not by changing values. Otherwise you will run into TOCTTOU problems as decribed in #14377 (comment) |
In addition it should be better to advice user to keep this option to BTW, what does that mean? This is really not comprehensive IMO. 'choices_as_values' => false |
@soullivaneuh using choices as values is planned to become the default in Symfony 3.0 |
@stof I know. But what is the advantage of adding a closure like this to get this working properly with some JS forms? Don't we have proper way? |
Another problem of using this without the form_value option is if you generate your options dynamically, the order could change between displaying the form and submitting it leading hard to find bugs. |
@jvasseur this is probably the main issue. As the order doesn't have to be guaranteed, this component becomes unreliable. |
@soullivaneuh The main advantage is that you can now use any kind of data as choice. Before, you were limited to strings and integers, because any other values are not valid array keys. The downside is that we cannot guarantee anymore that choices can be cast to strings that uniquely identify the choice. For array keys, we could do that. As a consequence you now need to implement your own "choice_value" closure where you apply your knowledge of your domain to return unique strings for each choice - even if that's the choice itself. But Symfony can't guess that magically for you. |
@webmozart What I'm not understanding it's that tricky closure just returning the choice given on anonymous function argument, without any modification. I found that is writing code for nothing IMO. Why not enable this by default? |
@soullivaneuh Because that would be wrong in some use cases, for example: $builder->add('field', 'choice', array(
'choices' => array(null, true, false),
'choices_as_values' => true,
)); If we create the choice values by casting choices to strings, we'll receive the values Note that the "entity" type will try to use the entity ID as value if possible (i.e. if it's not a composite ID). |
Thanks for this explanation. I see the problem now. But I'm still think that set |
@soullivaneuh Yes you are right :) At the moment, we have "choices_as_values" which can take two values:
The question is how we'll deal with this option in the future? Again, we have two possibilites:
I think that the second solution is much easier to understand, even if it means a little more (trivial) work. |
I know :) But keeping both possibilities also means maintaining both of them, documenting both of them and upgrading both of them when introducing new functionality. This makes it much harder and more time consuming to change the code base. I prefer removing non-essential features that currently only slow development down so that we can add essential features more easily in the future. |
Well,
I'm speaking about this trick notes of this PR. ;-) |
No: #14951 |
@webmozart Maybe we should just provide an option that sets |
@xabbuh Automate a one-liner by adding another one-liner? |
@webmozart I have the feeling that this could be more intuitive and more easy to remember. |
How about having a different form type for those array choices which inherits all the functionality and provides the easy default settings? Should improve the UX without much additional work to maintain. |
@xabbuh I think that the main problem at the moment is that we're changing things. People are naturally reluctant to change, since it means that they need to learn something new even if they had to learn much more than newcomers will have to learn after the change. The only sane automatism I can imagine is to traverse the options and see if they contain scalars only that can be cast to duplicate-free strings. But that means worse performance just to automate away a one-liner. In any case, IMO the way to go is to do this, wait until people get used to the new API and then try to improve/automate things if necessary. That's what we did for 2.1 and quite successfully so. |
Well, in my personal case, I'm not "reluctant to change" at all. I'm reluctant when the change introduce the usage obligation of an obscure closure just to fix a JavaScript trick. This is why I'm discussing here. :-) |
And btw, the usage of incremented integers already exists in Symfony 2.3+ in other cases:
|
@stof Exactly. So what's new is that the user of the choice field is now explicitly responsible for choosing a unique string representation for their choices. If the closure is the big hassle, we can also support some magic like: $builder->add('field', 'choice', array(
'choices' => array(1, 42, 128),
'choice_value' => '__choice__',
)); But I don't think that this is clearer than: $builder->add('field', 'choice', array(
'choices' => array(1, 42, 128),
'choice_value' => function ($choice) { return $choice; },
)); |
@webmozart I'm divided about your proposition. :|
|
Let's say we have string/integer values as choices. Why not use that as value by default then? So for common cases like Even if you have the same scalar twice in the options it makes no difference since when setting the value on the model there is no difference between the two. And what we could also do is just check if the choices are unique stringrepresented scalars and only use incrementing integers if not. |
Yes we could do that. That's what I was trying to say with:
However, we have to check how big the performance penalty is. |
Hi, I'm not very experienced with symfony and I landed here when I wanted to file a bug report. I have forms 2.7.1 and filled
|
This PR was merged into the 2.8 branch. Discussion ---------- Upgrade information for the choice_value option | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Relates to #14825 and #14377. The behaviour was changed with #16681 so a not in the upgrade information makes sense to me. Commits ------- 28675c9 Reflected the change of the choice_value option in the Upgrade information
Hi guys!
I'm still making sense of the form changes, but it seems that this before and after isn't totally honest - your option values will change, unless your add this extra option.
@webmozart look correct to you?
Thanks!