使用嵌套属性更新模型时避免表单中出现空白值

Avoiding blank values in form when updating a model with Nested Attributes

我有一个应用程序,用户可以在其中选择自己喜欢的颜色。

型号如下图。本质上,模型 UserColorUserColor

之间的简单映射
class User < ActiveRecord::Base
  has_many :colors, dependent: :destroy
  accepts_nested_attributes_for :colors, allow_destroy: true
end

class UserColor < ActiveRecord::base
  belongs_to :user
  belongs_to :color
end

class Color < ActiveRecord::Base
end

我有一个简单的表单,允许用户从 3 个下拉表单中选择最多 3 种颜色(假设可以重复颜色)。使用嵌套属性提交和更新表单,基本上只创建(最多)3 UserColor 条记录。

我在我的控制器中过滤参数以进行更新,如下所示:

params.require(:user).permit(
  colors_attributes: [
    :id,
    :color_id,
    :_destroy
  ]
)

如何避免出现空白?

如果用户只选择了一种颜色,第二个和第三个下拉菜单仍然是空白的。嵌套哈希如下提交(没有 "id" 属性,因为此时它是一条新记录,否则它会有一个)

{
  "colors_attributes"=> {
    "0"=>{"color_id"=>"17", "_destroy"=>""},
    "1"=>{"color_id"=>"", "_destroy"=>""},
    "2"=>{"color_id"=>"", "_destroy"=>""}
  }
}

这是不可接受的,因为最后两条记录有空白 color_id 值,这违反了该字段的非空标准并且未通过我的模型 save 验证。

有什么好的方法可以过滤掉或避免这里出现空白吗?我显然可以通过遍历和删除空白来绕过它,但是是否有更 "rails way" 接受的方式来处理这个问题?

使用 :reject_if 选项。

来自 http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html(使用您的模型):

accepts_nested_attributes_for :colors, reject_if: proc do |attributes|
  attributes['color_id'].blank?
end

accepts_nested_attributes 使用 reject_if 选项。

将此行放入您的 User 模型中。

accepts_nested_attributes_for :colors, reject_if: proc { |attributes| attributes['color_id'].blank? }, allow_destroy: true