Home > Net >  How to get validation messages for all nested records
How to get validation messages for all nested records

Time:10-26

Given this models:

class Foo < ApplicationRecord
  has_many :bars
  accepts_nested_attributes_for :bars
end

class Bar < ApplicationRecord
  validates :title, presence: true
end

I want to get the validation message for each nested Bar I create, because ...

Foo.create(bars_attributes: [, { title: nil }, { title: "foo" }, { title: nil }])

... results in @errors=[#<ActiveModel::NestedError attribute=bars.title, type=blank, options={}>], but I don't know which records (in this case, records at index 0 and 2) have failed. Is this possible at all?

CodePudding user response:

Break it down. Instead of trying to do everything in one command (which can only give you a success/failure response), try something like this (assumes it's being passed the details of your required Bar records in the params as an Enumerable (i.e. array or hash)).

@foo = foo.create(field_1: foo_params[:field_1], field_2: foo_params[:field_2])
_failed_bar_records = []
foo_params[:bar_data].each do |_bar_data|
  _bar = Bar.new(foo_id: @foo.id, title: _bar_data[:title])
  _failed_bar_records.push(_bar_data[:title]) unless _bar.save
end

Then, you'll have an array _failed_bar_records that contains data about each failed record. You could obviously push more to this array, like the actual error message.

CodePudding user response:

you could dig down to nested record's errors instead of checking the parent record's errors

@problem = Problem.new(problem_params)

@problem.solutions
# [<Solution:0x0000565379c46170 id: nil, description: "a solution", problem_id: nil, ...>,
#  <Solution:0x0000565379cc2248 id: nil, description: "", problem_id: nil, ...>]

@problem.save

@problem.errors
# <ActiveModel::Errors:..
# @base= <Problem:0x0000565379c33890 ...>,
# @errors=[
#  <ActiveModel::NestedError attribute=solutions.description, type=blank, options={}>
# ]>

@problem.solutions.map(&:errors)
# [
#   <ActiveModel::Errors:...
#    @base= <Solution:0x0000565379c46170 ...>,
#    @errors=[]>,
#
#   <ActiveModel::Errors:...
#    @base= <Solution:0x0000565379cc2248 ...>,
#    @errors=[
#     <ActiveModel::Error attribute=description, type=blank, options={}>
#    ]>
# ]
  • Related