Emmanuel Mtali Emmanuel Mtali - 1 month ago 9
Ruby Question

How to validate presence of at least one nested object?

Code

class Survey < ApplicationRecord
has_many :questions, inverse_of: :survey, :dependent => :destroy
accepts_nested_attributes_for :questions
validates_associated :questions
end

class Question < ApplicationRecord
belongs_to :survey, inverse_of: :questions
validates_presence_of :survey
end


My Surveys Controller

def new
@survey = Survey.new
2.times {@survey.questions.build}
end


Form

<%= form_for @survey do |f|%>
<p>
<%= f.label :name%>
<%= f.text_field :name%>
</p>
<%= f.fields_for :questions do |builder|%>
<p>
<%= builder.text_area :content, rows: 3%>
</p>
<% end %>

<p><%= f.submit %></p>

<% end %>


As you can see when user creates a survey the form provides two questions, i want user to supply at least one question when creating the survey. How can it be achieve???

Answer

One of the options is to use custom validation:

validate :questions_count

private

# or something more explicit, like `at_least_one_question` (credits to @MrYoshiji)
def questions_count
  errors.add(
    :base,
    'You can not save a survey without questions. Add at least one question'
  ) if questions.none?
end

Basically, the validation will be fired every time you create or "touch" (update) the survey object, and it will fail, if survey will not have at least one question associated.