2

在我的 Rails 应用程序中,我有这个模型:

class Project < ActiveRecord::Base

  attr_accessible :name, :person_ids

  belongs_to :user

  has_many :people_projects
  has_many :people, :through => :people_projects

end

我不明白的是:

person_ids当我创建一个新项目时,为什么我的数组开头总是有一个空元素:

Parameters: {"utf8" => "✓", "project" => {"name" => "Testproject", "person_ids" => ["", "1", "2", "3"]}, "commit" => "Create", "id"=>"77"}

这不仅发生在我的Project班级,而且在所有其他班级has_many through也发生,这给我带来了很多(主要是与验证相关的)麻烦。

这是我的表格:

<div class="field">
  <%= f.label "People" %>
  <%= f.select(:person_ids, current_user.people.map { |p| [ p.name, p.id ] }, {}, {:multiple => true}) %>
</div>

感谢任何可以对此有所了解的人。

4

1 回答 1

4

我想也许我找到了问题所在。看起来它来自Mike A.这个答案{:multiple => true}中指出的:

select文档

明白了

HTML 规范说,当多个参数传递给 select 并且所有选项都被取消选择时,Web 浏览器不会向服务器发送任何值。不幸的是,这引入了一个陷阱:如果一个用户模型有许多角色并且有 role_ids 访问器,并且在编辑用户角色的表单中,用户从 role_ids 多选框中取消选择所有角色,则不会发送任何 role_ids 参数。所以,任何像

@user.update_attributes(params[:user])

不会更新角色。

为了防止这种情况,助手在每次多选之前生成一个辅助隐藏字段。隐藏字段与多选和空白值具有相同的名称。

这样,客户端要么只发送隐藏字段(代表取消选中的多选框),要么发送两个字段。由于 HTML 规范规定键/值对必须以它们在表单中出现的相同顺序发送,并且参数提取获取查询字符串中任何重复键的最后一次出现,这适用于普通表单。

所以这是一个有意义的计划功能,但是它可能有一个黑暗的一面(就像你的情况一样) - 显然,根据同一个链接问题的这个答案,这在 Rails 4 中正在改变。

您将能够通过:include_hidden选项。https://github.com/rails/rails/pull/5414/files

同一篇文章提供了这个解决方案,它删除了模型级别的所有空白值:

before_validation do |model|
  model.subset_array.reject!(&:blank?) if model.subset_array
end
于 2013-11-03T08:54:40.973 回答