Ruby on Rails: how to get error messages from a child resource displayed? Ruby on Rails: how to get error messages from a child resource displayed? ruby ruby

Ruby on Rails: how to get error messages from a child resource displayed?


Add a validation block in the School model to merge the errors:

class School < ActiveRecord::Base  has_many :students  validate do |school|    school.students.each do |student|      next if student.valid?      student.errors.full_messages.each do |msg|        # you can customize the error message here:        errors.add_to_base("Student Error: #{msg}")      end    end  endend

Now @school.errors will contain the correct errors:

format.xml  { render :xml => @school.errors, :status => :unprocessable_entity }

Note:

You don't need a separate method for adding a new student to school, use the following syntax:

school.students.build(:email => email)

Update for Rails 3.0+

errors.add_to_base has been dropped from Rails 3.0 and above and should be replaced with:

errors[:base] << "Student Error: #{msg}"


Update Rails 5.0.1

You can use Active Record Autosave Association

class School < ActiveRecord::Base    has_many :students, autosave: true    validates_associated :studentsendclass Student < ActiveRecord::Base    belongs_to :school    validates_format_of :email,                  :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i,                  :message => "You must supply a valid email"end@school = School.new@school.build_student(email: 'xyz')@school.save@school.errors.full_messages ==> ['You must supply a valid email']

reference: http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html


This is not a public API yet, but Rails 5 stable seems to have ActiveModel::Errors#copy! to merge errors between two models.

user  = User.new(name: "foo", email: nil)other = User.new(name: nil, email:"foo@bar.com")user.errors.copy!(other.errors)user.full_messages #=> [ "name is blank", "email is blank" ] 

Again, this is not officially published yet (I accidentally find this one before monkey-patching Errors class), and I'm not sure it will be.

So it's up to you.