Skip to content

Instantly share code, notes, and snippets.

@dmitry
Created August 2, 2012 17:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitry/3238745 to your computer and use it in GitHub Desktop.
Save dmitry/3238745 to your computer and use it in GitHub Desktop.
Ruby on Rails extension to ActiveRecord to output nested errors for nested attributes in a right order and associate them with collection index. TODO make a better description of what it used for
def autosave_errors(params)
#valid?
errors = {}
params.each do |key, nested_params|
_, association_name = key.to_s.match(/\A(.+)_attributes\Z/).to_a
if association_name
association = association(association_name)
reflection = self.class.reflect_on_association(association_name.to_sym)
raise Exception.new('Association is not autosave or even not association at all') unless association || association.options[:autosave]
has_errors = !!self.errors.keys.find { |error| error.to_s =~ %r{#{association_name}\.} }
if has_errors
if reflection.collection?
persisted_records = association.target.select(&:persisted?)
new_records = association.target.select(&:new_record?)
new_index = -1
nested_params.each do |index, attributes|
id = (attributes['id'] || attributes[:id]).try(:to_s)
record = if id
persisted_records.detect { |r| r.id.to_s == id }
else
new_index += 1
raise 'Record have not been build' unless new_records[new_index]
new_records[new_index]
end
# TODO check that 3-rd nested level have valid? method call
unless record.errors.blank?
errors[key] ||= {}
errors[key][index] = record.autosave_errors(attributes)
end
end
else
record = send(name)
if nested_params && !record.errors.blank?
errors[key] = record.autosave_errors(nested_params)
end
end
end
else
errors[key] = self.errors[key]
end
end
errors.delete_if do |k, v|
k =~ /.+\..+/ || v.blank?
end
errors #.compact
end
@dmitry
Copy link
Author

dmitry commented Aug 2, 2012

Looks ugly, but it's only one way to get it work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment