Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

clean the erros if an object that includes validation is duped. #6284

Merged
merged 1 commit into from

4 participants

@acapilleri

If an istance that include validation is duped it keep track of errors of its 'parent', because both errors instances point to the same ActiveModel::Errors instance. This happen when before to call dup, save or valid? is called. This Fixes #5953 and it was discussed on the pull request #5958

activemodel/lib/active_model/validations.rb
@@ -177,6 +177,11 @@ def inherited(base)
super
end
end
+
+ #Clean errors if istance is duped

Minor spelling and space problem here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
activemodel/lib/active_model/validations.rb
@@ -177,6 +177,11 @@ def inherited(base)
super
end
end
+
+ #Clean the +Errors+ if instance is duped
@rafaelfranca Owner

I think that this method should have a :nodoc: mark.

# Clean the errors if instance is duped
def initialize_dup(other) # :nodoc:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@acapilleri

Thanks, done.

@carlosantoniodasilva carlosantoniodasilva commented on the diff
activemodel/lib/active_model/validations.rb
@@ -177,6 +177,11 @@ def inherited(base)
super
end
end
+
+ # Clean the +Errors+ object if instance is duped
+ def initialize_dup(other) # :nodoc:
+ @errors = nil

Make sure you call super here after doing your work. (read more).

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

I'm leaning toward actually cloning the @errors object instead of nullifying it, would look something like:

@errors = other.errors.dup
@errors.instance_variable_set(:@base, self)

Seems more what initialize_dup is supposed to do, I just dislike a bit the instance_variable_set call (although the test would break in case anything changes in Errors). And in case we go this path, the test would need to be updated to reflect that the errors stay there after calling dup.

@josevalim @rafaelfranca how does that look for you guys?

Thanks!

@acapilleri

ops... i just pushed it with super call..

@acapilleri

I disagree about errors dup, because when you dup an activerecord you not dup the id, it could be inconsistent ( id duplicate for example)

@carlosantoniodasilva carlosantoniodasilva merged commit 3d1b078 into rails:master
@acapilleri

@carlosantoniodasilva do you think this could be merged also on the current 3-2?

@carlosantoniodasilva

I think so, don't see any harm on having this fixed there as well. If you want you can send another pull to 3-2, otherwise I can just merge here later, thanks.

@acapilleri acapilleri referenced this pull request from a commit in acapilleri/rails
@acapilleri acapilleri clean the errors if an object that includes validations errors is dup…
…ed,for 3-2-stable

It Fixes #5953 in 3-2-stable, it's the same pull request of #6284
396e383
@acapilleri acapilleri referenced this pull request
Merged

Dup validation 3 2 #6324

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 13, 2012
  1. clean the erros if an object that includes validations errors is dupe…

    Angelo Capilleri authored
    …d. Fixes #5953
This page is out of date. Refresh to see the latest.
View
6 activemodel/lib/active_model/validations.rb
@@ -177,6 +177,12 @@ def inherited(base)
super
end
end
+
+ # Clean the +Errors+ object if instance is duped
+ def initialize_dup(other) # :nodoc:
+ @errors = nil

Make sure you call super here after doing your work. (read more).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ super
+ end
# Returns the +Errors+ object that holds all information about attribute error messages.
def errors
View
15 activemodel/test/cases/validations_test.rb
@@ -344,4 +344,19 @@ def test_does_not_modify_options_argument
Topic.validates :title, options
assert_equal({ :presence => true }, options)
end
+
+ def test_dup_validity_is_independent
+ Topic.validates_presence_of :title
+ topic = Topic.new("title" => "Litterature")
+ topic.valid?
+
+ duped = topic.dup
+ duped.title = nil
+ assert duped.invalid?
+
+ topic.title = nil
+ duped.title = 'Mathematics'
+ assert topic.invalid?
+ assert duped.valid?
+ end
end
Something went wrong with that request. Please try again.