Search code examples
ruby-on-railsnested-attributes

Validating presence of nested attributes returns error "no method :path_base"


I have a model which accepts nested attributes. There are 4 attributes altogether and I need to verify the presence of one. the specific attribute I need to verify for is called path_base so I tried

validates_presence_of :path_base

In the model but I am getting the error

undefined method `path_base' for #<Template:0x007fa279146360> 

When saving the template record. The params getting sent look like this

Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZO+Pi3/6WwNk0H3cFhgDbRywjrAOv2RnZ7olIsenND0=", "already_saved"=>"false", "update_pages"=>"false", 
"template"=>{"type"=>"singleton", "name"=>"test", 
"template_responses_attributes"=>{"0"=>{"path_base"=>"", "liquid_code"=>"test", "indexable"=>"1", "content_type"=>"text/html"}, "1"=>{"path_base"=>"", "liquid_code"=>"", "indexable"=>"1", "content_type"=>"text/html"}}, 
"template_fields_json"=>"[\r\n\r\n]"}, "button"=>""}

So inside the template_responses_attributes array is where the value of path_base is, and that is inside the template array just like normal (template is the controller/model that is saving the record that accepts the nested attributes).

If anyone could point me in the correct direction for this it would be greatly appreciated.

I did try this, which I found here but it did not return an error when the value was empty.

reject_if: proc { |attributes| attributes['path_base'].blank? }

Solution

  • Each model should only be responsible for validating its own attributes - if you want to ensure that the nested records are valid use validates_associated.

    class Template < ApplicationRecord
      has_many :responses
      accepts_nested_attributes_for :responses
    
      # This validates all the associated records
      validates_associated :responses
    end
    
    class Response < ApplicationRecord
      validates_presence_of :path_base
      # ...
    end
    

    The reject_if option is not a validation mechanism. Rather it lets you filter out nested attributes if they do not meet a criteria, take for example a task list application where you would want to filter out the empty rows.