Open ssendev opened 2 years ago
Hey @ssendev. That's an interesting case! I haven't seen that before. So the query string that's generated would be post?box=false&box=true
if the checkbox is checked? That's kind of surprising.
Can you show me where that comes up? For example, checking out the rails guide, that's not what I'm seeing: https://guides.rubyonrails.org/v5.0/form_helpers.html#checkboxes
It wouldn't be possible to handle this in serde_qs currently. It would need to be added as new logic.
If you can change the name
fields, you could do:
<input type="hidden" name="box[]" value="false" />
<input type="checkbox" name="box[]" value="true" />
and deserialize to a box: Vec<bool>
. Which you could make into a bool with box.iter().any(|checked| checked)
@samscott89 Yes that's the query string. The hidden field is there when instead of check_box_tag
check_box
is used.
Yeah I used a similar Vec
workaround though mine was more janky. I guess i hoped there would be something similar to the Flatten workaround which would allow to have an Option<bool>
.
Usability wise I imagined it similar to serde_with
. Something like
#[derive(Deserialize, Serialize, Debug, PartialEq)]
struct Query {
#[serde_into(into="vec_to_bool", over="Vec<bool>")]
common: Option<bool>,
}
fn vec_to_bool(vec: Vec<bool>) -> Option<bool> {
if vec.empty() {
return None
} else {
Some(vec.iter().any(|checked| checked)
}
}
But i can live with the Vec
in the struct it just leaks some implementation details. So just consider this a low prio feature request and maybe someone comes along that knows of a solution.
Thank you for the reference, that's exactly what I was looking for.
This line is very telling:
Since the HTML specification says key/value pairs have to be sent in the same order they appear in the form, and parameters extraction gets the last occurrence of any repeated key in the query string, that works for ordinary forms.
Whereas what's implemented here is something stricter: make sure there are no repeated keys (that aren't vector elements as indicated by []
or [i]
).
I'll change this behaviour to match the spec, probably with an option somewhere to toggle the previous behaviour. Thank you!
In Ruby on Rails checkboxes are usually used like
since that way it's possible to model an
Option<bool>
but that causesFailed to deserialize query string: duplicate field 'box'
Adding#[serde(keep_last)]
is apparently not a thing: https://github.com/serde-rs/serde/issues/690. Is there a way to get it to work?