使用嵌套属性

时间:2016-03-13 22:09:47

标签: ruby-on-rails 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以进行更新,如下所示:

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

如何避免空白?

如果用户仅选择1种颜色,则第2次和第3次下拉仍为空白。嵌套哈希的提交方式如下(没有"id"属性,因为此时它是一条新记录,但除此之外它会有一个)

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

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

有没有一种很好的方法来过滤掉或避免空白?我可以通过循环和删除空白来明显地破解它,但是有更多的“轨道方式”接受处理这个方法吗?

2 个答案:

答案 0 :(得分:1)

使用: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

答案 1 :(得分:1)

reject_if使用accepts_nested_attributes选项。

将此行放在User模型中。

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