「has_many」アドレス (Address クラス) を持つ Mongoid「ノード」モデルがあります。
ネストされたフォームを使用してアドレスを管理していますが、ノードのアドレスを正常に作成、更新、破棄できます。
問題はアドレス バリデータにあります。新しいアドレスで検証が失敗すると、update_attributes が失敗し、エラーが表示されます。ただし、既存のアドレスを無効な値で更新しようとすると、アドレスバリデーターがトリガーされて失敗します (ログを介してチェックされます) が、ノードの 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
アドレス クラス (クラス メソッドはスキップされます) (オーバーロードされたゲッターとセッターがあることに注意してください。ただし、それらが原因ではないようです):
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 の update メソッド:
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 コールバックに置き換えてみましたが、同じ問題がありました。
Rails v3.2.6 / Mongoid v3.0.1
更新: params[:node] コンテンツ
新しい有効な住所を送信する場合 (エラーなし):
{"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"=>""}}}