为什么第一个元素在我的Rails多选中总是空白,使用嵌入式数组? [英] Why is the first element always blank in my Rails multi-select, using an embedded array?
问题描述
我正在使用 Rails 3.2.0.rc2 。我有一个 Model
,其中我有一个静态 Array
,我通过一个表单用户可以选择 Array
的子集并将其选择保存到数据库中,并存储在 Model
中的单个列中。我在存储 Array
的数据库列上使用了serialize,并且Rails将用户的选择正确地转换为Yaml(并在读取该列时返回到数组)。我正在使用多选表单输入来进行选择。
我的问题是,按照我目前的方式,一切都按我的预期工作除非用户的子集数组在发送到服务器时始终具有空的第一个元素。
这不是什么大问题,我可以写代码在事实之后将其切掉,但我觉得我只是在制造某种语法错误,因为在我看来,默认的Rails行为在没有任何理由的情况下会故意添加这个空白元素。我一定错过了某些东西,或者忘记禁用某种设置。请帮助我了解我错过了什么(或者指出我有一些很好的文档,这些文档的描述比我在intetubes上找到的更深入)。
MySQL数据库表'models':
- 包含名为
subset_array
这是一个TEXT字段
类模型包括以下设置:
-
serialize:subset_array
-
ALL_POSSIBLE_VALUES = [value1,value2,value3,。 ..]
编辑模型包含以下输入选项:
-
f.select:subset_array,Model :: ALL_POSSIBLE_VALUES,{},:multiple => true,:selected => @ model.subset_array
从客户端上传到服务器看起来像这样:
- 假设只选择了value1和value3
-
model=> {subset_array=> [,value1,value3]}
数据库更新如下所示:
$ b'b-
UPDATE'models'SET'subset_array'='--- \\\
- \\\\\
- value1\- value3\\\
'
正如您所看到的那样, ,数组中的元素被发送并设置在数据库中。我该如何摆脱?是否有我从 f.select
调用中缺少的参数?
非常感谢:) p>
编辑:这是从 f.select
语句生成的HTML代码。它看起来好像有一个隐藏的输入正在产生,这可能是我的问题的原因?为什么在那里?
< input name =model [subset_array] []type =hiddenvalue>
隐藏字段是导致问题的原因。但有一个很好的理由:当所有值都被取消选中时,您仍然会收到一个subset_array参数。从Rails文档(您可能需要滚动到右侧才能看到所有内容):
#HTML规范说明了什么时候+多个参数传递给select并取消所有选项
#web浏览器不向服务器发送任何值。不幸的是,这引入了一个问题:
#如果一个+ User +模型有很多+角色+并且有+ role_ids + accessor,并且以编辑用户角色的形式
#,用户将取消选择来自+ role_ids +选择框中,不发送+ role_ids +参数。因此,
#任何类似于
#
#@ user.update_attributes(params [:user])
#
#的大量分配习惯用法不会更新角色。
#
#为了防止这种情况,助手会在
#每隔多次选择之前生成一个辅助隐藏字段。隐藏字段与多个选择和空白值具有相同的名称。
#
#这样,客户端只发送隐藏字段(表示
#取消选定的多选框)或两个字段。由于HTML规范
#表示键/值对必须以相同的顺序发送,它们出现在
#表中,并且参数提取将获得最后一次出现的任何重复的
#键查询字符串,适用于普通窗体。
编辑:最后一段建议您不应该看到在选择某些东西的情况下清空一个,但我认为这是错误的。将此提交给Rails的人(请参阅 https://github.com/rails/rails/commit / faba406fa15251cdc9588364d23c687a14ed6885 )正在尝试使用Rails用于复选框的相同技巧(如此处所述: https://github.com/rails/rails/pull/1552 ),但我不认为它可以用于多选框,因为在这种情况下通过形成一个数组发送参数,所以没有值被忽略。
所以我的感觉是这是一个bug。
I'm using Rails 3.2.0.rc2. I've got a Model
, in which I have a static Array
which I'm offering up through a form such that users may select a subset of Array
and save their selection to the database, stored in a single column in Model
. I've used serialize on the database column which stores the Array
and Rails is correctly converting the users' selections into Yaml (and back to an array when reading that column). I'm using a multi-select form input to make selections.
My problem is that, the way I currently have it, everything works as I would expect except that the user's subset array always has a blank first element when it's sent to the server.
This isn't a big deal, and I could write code to cut that out after the fact, but I feel like I'm just making some kind of syntactical error as it doesn't seem to me that the default Rails behaviour would intentionally add this blank element without some reason. I must have missed something or forgot to disable some kind of setting. Please help me understand what I'm missing (or point me in to some good documentation that describes this with more depth than what I've been able to find on the intertubes).
MySQL Database Table 'models':
- includes a column named
subset_array
which is a TEXT field
Class Model includes the following settings:
serialize :subset_array
ALL_POSSIBLE_VALUES = [value1, value2, value3, ...]
Form for editing Models includes the following input option:
f.select :subset_array, Model::ALL_POSSIBLE_VALUES, {}, :multiple => true, :selected => @model.subset_array
PUT to server from client looks something like this:
- assuming only value1 and value3 are selected
"model" => { "subset_array" => ["", value1, value3] }
Database update looks like this:
UPDATE 'models' SET 'subset_array' = '--- \n- \"\"\n- value1\n- value3\n'
As you can see, there's this extra, blank, element in the array being sent and set in the database. How do I get rid of that? Is there a parameter I'm missing from my f.select
call?
Much thanks appreciated :)
EDIT: This is the generated HTML code from the f.select
statement. It looks as though there is a hidden input being generated which may be the cause of my issue? Why is that there?
<input name="model[subset_array][]" type="hidden" value>
<select id="model_subset_array" multiple="multiple" name="model[subset_array][]" selected="selected">
<option value="value1" selected="selected">Value1</option>
<option value="value2">Value2</option>
<option value="value3" selected="selected">Value3</option>
<option...>...</option>
</select>
The hidden field is what is causing the issue. But it is there for a good reason: when all values are deselected, you still receive a subset_array parameter. From the Rails docs (you may have to scroll to the right to see all of this):
# The HTML specification says when +multiple+ parameter passed to select and all options got deselected
# web browsers do not send any value to server. Unfortunately this introduces a gotcha:
# if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
# the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
# any mass-assignment idiom like
#
# @user.update_attributes(params[:user])
#
# wouldn't update roles.
#
# To prevent this the helper generates an auxiliary hidden field before
# every multiple select. The hidden field has the same name as multiple select and blank value.
#
# This way, the client either sends only the hidden field (representing
# the deselected multiple select box), or both fields. 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.
EDIT: The last paragraph suggests that you shouldn't be seeing the empty one in the case when something is selected, but I think it is wrong. The person who made this commit to Rails (see https://github.com/rails/rails/commit/faba406fa15251cdc9588364d23c687a14ed6885) is trying to do the same trick that Rails uses for checkboxes (as mentioned here: https://github.com/rails/rails/pull/1552), but I don't think it can work for a multiple select box because the parameters sent over form an array in this case and so no value is ignored.
So my feeling is that this is a bug.
这篇关于为什么第一个元素在我的Rails多选中总是空白,使用嵌入式数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!