Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft of indexed errors implementation #467

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions lib/reform/errors.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Provides the old API for Rails and friends.
# Note that this might become an optional "deprecation" gem in Reform 3.
class Reform::Contract::Result::Errors
@@index_errors = false

def initialize(result, form)
@result = result # DISCUSS: we don't use this ATM?
@form = form
Expand All @@ -10,19 +12,46 @@ def initialize(result, form)
end

# PROTOTYPING. THIS WILL GO TO A SEPARATE GEM IN REFORM 2.4/3.0.
DottedErrors = ->(form, prefix, hash) do
DottedErrors = ->(form, prefix, hash, i = nil) do
result = form.to_result
result.messages.collect { |k,v| hash[ [*prefix, k].join(".").to_sym] = v }
if indexed_errors?
result.messages.collect do |k,v|
indexed_errors(prefix, hash, k, v, i)
end
else
result.messages.collect { |k,v| hash[ [*prefix, k].join(".").to_sym] = v }
end

form.schema.each(twin: true) { |dfn|
Disposable::Twin::PropertyProcessor.new(dfn, form).() do |frm, i|
# DottedErrors.(form.send(dfn[:name])[i], [*prefix, dfn[:name], i], hash) and next if i
DottedErrors.(form.send(dfn[:name])[i], [*prefix, dfn[:name]], hash) and next if i
DottedErrors.(form.send(dfn[:name])[i], [*prefix, dfn[:name]], hash, i) and next if i
DottedErrors.(form.send(dfn[:name]), [*prefix, dfn[:name]], hash)
end
}
end

def self.indexed_errors?
@@index_errors
end

def self.index_errors=(value)
@@index_errors = value
end

def self.indexed_errors(prefix, hash, k, v, i = nil)
# if no index, means not collection, show the error
if i.nil?
hash[ [*prefix, k].join(".").to_sym] = v
# if it's a collection, index the errors
else
# create attribute prefix with all attributes joined
attribute_prefix = [ *prefix ].join(".")
# then join with index and it's attribute name
hash[ ["#{attribute_prefix}[#{i}]", k].join(".").to_sym] = v
end
end

def messages(*args)
@dotted_errors
end
Expand Down
21 changes: 21 additions & 0 deletions test/errors_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,27 @@ def good_musical_taste?(value)
end
end

describe "indexed errors" do
before { form.validate(
"hit" =>{"title" => ""},
"title" => "",
"songs" => [{"title" => ""}, {"title" => ""}]) } # FIXME: what happens if item must be filled?

after { Reform::Contract::Result::Errors.index_errors = false }

it do
Reform::Contract::Result::Errors.index_errors = true
form.errors.messages.must_equal({
:title => ["must be filled"],
:"hit.title" => ["must be filled"],
:"songs[0].title"=> ["must be filled"],
:"songs[1].title"=> ["must be filled"],
:"band.label.name"=>["must be filled"]
})
form.errors.size.must_equal(5)
end
end


describe "#validate with main form invalid" do
it do
Expand Down