Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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???

like image 914
Emmanuel Mtali Avatar asked Mar 11 '23 22:03

Emmanuel Mtali


2 Answers

You could just test for the length of the array and simply do:

validates :questions, length: {minimum: 1, message: 'should have at least 1 question defined.'}
like image 87
David Avatar answered Mar 28 '23 19:03

David


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.

like image 43
Andrey Deineko Avatar answered Mar 28 '23 19:03

Andrey Deineko