Showing fields with errors for nested forms in Rails 3.2 + SimpleForm
Asked Answered
O

3

10

I have a Flight model nested inside a FlightLog model. A FlightLog may contain many flights.

I'm using SimpleForm with the bootstrap installation, which makes it possible to surround form elements with errors with the error class when a validation fails.

The problem is, that even though validations are triggered for the nested model, the fields with errors inside the simple_fields_for are not being marked, so it's not possible to determine which attribute is not valid.

After examining the errors hash when calling the create action, I can see that it is correctly populated with the errors at the top level, and the errors of the nested resources inside each resource.

How could I modify the behavior of simple_form to add the errors class to the control group of each nested model to match the behavior of the parent?

Thanks in advance.

enter image description here

Octosyllable answered 2/4, 2012 at 14:43 Comment(0)
O
2

I have been using custom accessors instead of the _id fields, so that's why they weren't getting notified when they had errors. I finally resolved to use f.error :attr_name under each accessor and changing the styling manually with JS

Octosyllable answered 7/9, 2012 at 19:35 Comment(2)
can you add further code examples?Ortegal
And after hours trying to figure it out, this is it. Works fine with real fields. Not with accessors. Thanks!Adrenocorticotropic
S
21

If you are using simple_form with bootstrap, this does work - you just need to set up a few items correctly:

1 - Use the simple_form bootstrap wrappers (from simple_form 2.0) - you can find them in the github repo under config/initializers/simple_form.rb (https://github.com/rafaelfranca/simple_form-bootstrap)

2 - For nested forms to display the errors, you must be sure you provide an object. f.simple_fields_for :nested_model won't work, you need to use f.simple_fields_for parent_model.nested_model or f.simple_fields_for :nested_model, parent_model.nested_model so that the form can get the necessary object.

If you still don't get anything, verify that the form is really getting the object you think it is, with errors, by outputting the errors data on your nested object: parent_model.nested_model.errors.full_messages.to_sentence

Sarette answered 11/4, 2012 at 19:41 Comment(3)
Thanks for the suggestions, I'll give it a try and let you know how it goes!Octosyllable
parent_model.nested_model.errors.full_messages.to_sentence does not works for me, but parent_model.errors.full_messages.to_sentence is works, and displays errors from nested model. Thanks!Bandsman
this was a huge time savior I can not thank you enoughSaddle
O
2

I have been using custom accessors instead of the _id fields, so that's why they weren't getting notified when they had errors. I finally resolved to use f.error :attr_name under each accessor and changing the styling manually with JS

Octosyllable answered 7/9, 2012 at 19:35 Comment(2)
can you add further code examples?Ortegal
And after hours trying to figure it out, this is it. Works fine with real fields. Not with accessors. Thanks!Adrenocorticotropic
O
0

There might be several things wrong along the way. I had issues with this as well using bootstrap simple form. After I fixed everything in the controller, model and form it worked.

For me I had several issues, especially the commented lines where crucial in my case.

check that you have the following in place:

survey.rb:

class Survey < ApplicationRecord
  has_many :answers
  accepts_nested_attributes_for :answers, allow_destroy: true
  #errors have to come from answer validation for answer form
  validates_associated :answers
  validates :question, :answers, presence: true

answer.rb:

class Answer < ApplicationRecord
  belongs_to :survey
  # make sure there is a validation on answer
  validates :answer, presence: true
end

_form.html.slim

# make sure you have given the right attributes for .input and simple_fields_for
= f.simple_fields_for :answers, @survey.answers do |answer_form|
  = answer_form.input :answer

surveys_controller.rb

def new
 @survey = Survey.new
 #when answers are not builded it wont show any simple fields for
 @survey.answers.build
end

def create
 @survey = Survey.new(survey_params)
 @survey.user = current_backend_user
 if @survey.save
  redirect_to backend_surveys_path, notice: 'Umfrage erfolgreich erstellt'
 else
  render :new
 end
end

def survey_params
  # make sure everything is permitted correctly
  params.require(:survey).permit(:some_attribute, ..., answers_attributes: %i[id answer])
end

reject if on model validation can cause errors some times on this as well. be cautious.

Ortegal answered 13/10, 2021 at 10:17 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.