Rails / Mongoid update_attributes忽略持久的嵌套属性验证

时间:2012-07-18 13:12:49

标签: ruby-on-rails ruby-on-rails-3 mongoid

我有一个Mongoid“Node”模型,其中包含“has_many”地址(地址类)。

我正在使用嵌套表单来管理地址,并且我能够成功创建,更新,销毁节点的地址。

问题在于地址验证器:当新地址验证失败时,update_attibutes失败并显示错误。但是当尝试使用无效值更新现有地址时,会触发地址验证器并失败(通过日志检查),但Node的update_attributes返回true并且不显示错误(地址使其值保持不变)。

当尝试使用无效值更新现有地址并同时创建新的无效地址以强制update_attributes失败时,我的表单由于新地址而失败,但现有地址及其没有错误(有效) )价值恢复。

新的和持久的嵌套属性验证之间是否存在不同的行为?

这是我的Node类的标题:

class Node

  # INCLUSIONS

    include Mongoid::Document
    include Mongoid::Timestamps

  # RELATIONS

    belongs_to              :organization
    has_and_belongs_to_many :platforms
    has_many                :addresses

    accepts_nested_attributes_for :addresses, allow_destroy: true, reject_if: :all_blank

地址类(跳过的类方法)(请注意,有重载的getter和setter,但它们似乎不是原因):

class Address

  # INCLUSIONS

    include Mongoid::Document
    include Mongoid::Timestamps

  # RELATIONS

    belongs_to :node

  # FIELDS

    field :address, type: String
    field :nat,     type: String
    field :description

  # VALIDATIONS

    validates :address, :node,
      presence: true

    # Validates address and nat validity
    validate do
      [:address, :nat].each do |field|
        errors.add(field, :invalid) unless self[field].blank? || self.class.valid_hex?(self[field])
      end
    end

  # INSTANCE METHODS

    # Address getter
    def address
      return self.class.hex_to_ip(self[:address]).to_s if self.class.valid_hex? self[:address]
      self[:address]
    end

    # Address setter
    def address= value
      self[:address] = self.class.valid_ip?(value) ? self.class.ip_to_hex(value) : value
    end

    # NAT address getter
    def nat
      return self.class.hex_to_ip(self[:nat]).to_s if self.class.valid_hex? self[:nat]
      self[:nat]
    end

    # NAT Address setter
    def nat= value
      self[:nat] = self.class.valid_ip?(value) ? self.class.ip_to_hex(value) : value
    end

end

NodesController的更新方法:

def update
  @node = platform.nodes.find_by name: params[:id]
  if @node.update_attributes params[:node]
    flash[:success] = t_flash :update_success, @node
    redirect_to platforms_platform_node_path(organization, platform, @node)
  else
    flash.now[:error] = t_flash :update_error, @node, count: @node.errors.count
    render :form
  end
end

我尝试在Node类中添加validates_associated :addresses但它没有改变任何东西(并且似乎没有必要,因为没有这个验证新地址)。

我也试过更换吸气剂和放大器使用after_initialize / before_save回调的setter,我遇到了同样的问题。

Rails v3.2.6 / Mongoid v3.0.1

更新:params [:node] content

提交新的有效地址(无错误)时:

{"name"=>"Test", "addresses_attributes"=>{"0"=>{"address"=>"1.2.3.4", "description"=>"", "nat"=>""}}}

提交格式无效的新地址时(错误    成功展示):

{"name"=>"Test", "addresses_attributes"=>{"0"=>{"address"=>"fdgfdgfdgfd", "description"=>"", "nat"=>""}}}

更新具有无效值的有效地址时(无错误):

{"name"=>"Test", "addresses_attributes"=>{"0"=>{"id"=>"5007e1c26fad9db41f000008", "address"=>"dsfsdfsdf", "description"=>"", "nat"=>""}}}

1 个答案:

答案 0 :(得分:3)

检查此git commit https://github.com/jiren/mongoid/commit/9ebb8af8514ea70c66a7dbe64be20bc7407a2829

您可以使用此gem修复此问题。