Note that there are some explanatory texts on larger screens.

plurals
  1. PORails/Mongoid update_attributes ignoring persisted nested attributes validations
    primarykey
    data
    text
    <p>I've got a Mongoid "Node" model that "has_many" addresses (Address class).</p> <p>I'm using a nested form to manage addresses and I'm able to create, update, destroy node's addresses successfully.</p> <p>The problem is with Address validators : When validation fails on a new Address, update_attibutes fails and errors are displayed. But when trying to update an existing address with a invalid value, Address validators are triggered and fails (checked through log), but Node's update_attributes returns true and no error is displayed (the address keeps it's value unchanged).</p> <p>When trying to update an existing address with invalid value and create a new invalid address at the same time to force update_attributes to fail, my form fails because of the new address, but there's no error on the existing address and its (valid) value is restored.</p> <p>Is there a different behavior between new and persisted nested attributes validation ?</p> <p>Here's the header of my Node class :</p> <pre class="lang-rb prettyprint-override"><code>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 </code></pre> <p>Address class (class methods skipped) (note that there are overloaded getters &amp; setters but they doesn't seem to be the cause) :</p> <pre class="lang-rb prettyprint-override"><code>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 </code></pre> <p>update method of NodesController :</p> <pre class="lang-rb prettyprint-override"><code>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 </code></pre> <p>I've tried adding <a href="http://guides.rubyonrails.org/active_record_validations_callbacks.html#validates_associated" rel="nofollow">validates_associated :addresses</a> in Node class but it doesn't change anything (and it doesn't seem to be necessary since new addresses are validated without this).</p> <p>I've also tried replacing getters &amp; setters with after_initialize/before_save callbacks and I had the same problem.</p> <p>Rails v3.2.6 / Mongoid v3.0.1</p> <h2>Update : params[:node] content</h2> <p>When submitting a new valid address (no error) :</p> <pre><code>{"name"=&gt;"Test", "addresses_attributes"=&gt;{"0"=&gt;{"address"=&gt;"1.2.3.4", "description"=&gt;"", "nat"=&gt;""}}} </code></pre> <p>When submitting a new address with invalid format (error successfully displayed) :</p> <pre><code>{"name"=&gt;"Test", "addresses_attributes"=&gt;{"0"=&gt;{"address"=&gt;"fdgfdgfdgfd", "description"=&gt;"", "nat"=&gt;""}}} </code></pre> <p>When updating a valid address with invalid value (no error bu it should) :</p> <pre><code>{"name"=&gt;"Test", "addresses_attributes"=&gt;{"0"=&gt;{"id"=&gt;"5007e1c26fad9db41f000008", "address"=&gt;"dsfsdfsdf", "description"=&gt;"", "nat"=&gt;""}}} </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload