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={}>
# ]>
# ]