首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在双层嵌套表单上使用:reject_if => :all_blank

在双层嵌套表单上使用:reject_if => :all_blank
EN

Stack Overflow用户
提问于 2014-10-29 09:03:31
回答 1查看 850关注 0票数 2

因此,我有以下模型

宠物

代码语言:javascript
运行
复制
class Pet < ActiveRecord::Base

  # Associations
  has_and_belongs_to_many :owners

  accepts_nested_attributes_for :owners, :reject_if => :all_blank
end

所有者

代码语言:javascript
运行
复制
class Owner < ActiveRecord::Base

  # Associations
  has_and_belongs_to_many :pets
  has_one :phone_number, :as => :callable, :dependent => :destroy
  has_one :address, :as => :addressable, :dependent => :destroy

  accepts_nested_attributes_for :phone_number
  accepts_nested_attributes_for :address
end

电话号码

代码语言:javascript
运行
复制
class PhoneNumber < ActiveRecord::Base
  belongs_to :callable, polymorphic: true
end

地址

代码语言:javascript
运行
复制
class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
end

我有一个嵌套了f.fields_for :owners的顶级form_for @petf.fields_for :phone_numberf.fields_for :address都嵌套在f.fields_for :owners块中。这意味着我的params.require看起来像这样。

代码语言:javascript
运行
复制
params.require(:pet).permit(:name, :breed, :color, :neutered, :microchip, :flee_control,
        :heartworm_prevention, :date_of_birth, :gender, :species_id, :avatar,
        :owners_attributes => [ :first_name, :last_name, :email,
            :phone_number_attributes => [:number],
            :address_attributes => [:line1, :city, :state, :zip_code] ])

我的参数都是正确的,我可以创建新的记录,一切都很好。当我尝试使用:reject_if => :all_blank拒绝空白所有者时,问题就出现了。

因为存在第二层嵌套属性,所以phone_number_attributesaddress_attributes都被认为是not_blank,因为从技术上讲,它们属于!ruby/hash:ActionController::Parameters类型,这允许在不应该使用空白属性构建对象时使用它。

我已经搜索了大约2个小时,但我找不到任何关于这个问题的信息。我是不是漏掉了什么明显的东西?我已经尝试在所有者模型上添加:reject_if => :all_blank来获取电话号码和地址,但也没有成功。

编辑:我能够让它工作,但必须有更好的内置方法来做到这一点。

代码语言:javascript
运行
复制
accepts_nested_attributes_for :owners, reject_if: proc { |attributes|
    attributes.all? do |key, value|
      if value.is_a? ActionController::Parameters
        value.all? { |nested_key, nested_value| nested_key == '_destroy' || nested_value.blank? }
      else
        key == '_destroy' || value.blank?
      end
    end
  }
EN

回答 1

Stack Overflow用户

发布于 2018-02-06 23:58:20

我还没有看到一种内置的方法来完成您想要做的事情,但我使用的一个变通方法是扩展api文档中的示例,如下所示:

代码语言:javascript
运行
复制
# Add an instance method to application_record.rb / active_record.rb
def all_blank?(attributes)
  attributes.all? { |key, value| key == '_destroy' || value.blank? || (all_blank?(value) if value.is_a?(Hash)) }
end

# Then modify your model pet.rb to call that method
accepts_nested_attributes_for : owners, reject_if: :all_blank?

api中的原始示例

代码语言:javascript
运行
复制
REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == "_destroy" || value.blank? } }

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26621177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档