The reasoning is probably that it makes it more simple to add multiple
errors. If the mutator overwrite the whole set of errors, setting multiple
errors would require explicitly dealing with arrays. I don't think that's
enough justification, but it's still probably the reasoning. Indeed here's
the snippet within active_model/errors.rb that causes this:

# Adds to the supplied attribute the supplied error message.
#
#   p.errors[:name] = "must be set"
#   p.errors[:name] # => ['must be set']
def []=(attribute, error)
  self[attribute.to_sym] << error
end

Here's one possibility to do what you want:

p1.errors[:base].each {|e| p2.errors[:base] << e }

Or if you need more control, and assuming you're working entirely with :base
errors, you can always use the set method which will set (replace) the
errors on that key:

p2.errors.set(:base, p2.errors[:base] + p1.errors[:base])

One thing you didn't mention in your original message is why you're merging
them to begin with. I've personally never come across a case where I felt
the need to copy errors from one model to another - something seems fishy
with that. If you're working with models that are related, check out using
validates_associated or accepts_nested_attributes_for (nested model errors
are handled nicely). Even aside from that, there's nothing wrong with
handling error messages for multiple model instance variables. My
message_block plugin (https://github.com/rubiety/message_block) encapsulates
this with something like this in the case that you're trying to validate
both @user and @comment:


<%= message_block :on => [:user, :comment] %>


- Ben



On Wed, Aug 24, 2011 at 3:48 PM, Glenn Little <[email protected]> wrote:

> Oh, wow... yeah, the thing I wasn't getting is that errors= is really
> behaving the way one would expect "errors+=" to behave.  That seems
> really odd to me that an assignment pattern is acting as an append.
> Do you know the reasoning behind that design?
>
> And what's the "accepted" way to merge errors from one AR object into
> the errors for another then?
>
> In actuality, it looks like some array flattening is happening in some
> of the output methods (like full_messages), so the funky nested arrays
> you might have may not matter, but that feels gross and I'm not
> convinced it won't break something somewhere.  Is there a clean way to
> merge them without actually explicitly iterating?
>
> -glenn
>
> On Wed, Aug 24, 2011 at 3:09 PM, Ben Hughes <[email protected]> wrote:
> > Glenn,
> > This is a consequence of 1) the "errors=" method accepting a string but
> > really just appending it's value (and exposing it via "errors") as an
> array,
> > and 2) a += b in Ruby being just pretty syntax for a = a + b. With that
> in
> > mind, here's what's happening:
> >> p1.errors[:base] = "p1 error"   # p1.errors[:base] => "['p1 error']"
> >> p2.errors[:base] = "p2 error"   # p2.errors[:base] => "['p2 error']"
> >
> >> p2.errors[:base] += p1.errors[:base]  # Same as: p2.errors[:base] =
> >> p2.errors[:base] + p1.errors[:base]
> > # reduced: p1.errors[:base] = ["p2 error"] + ["p1 error"]
> > # more:    p1.errors[:base] = ["p2 error", "p1 error"]
> > And since calling errors= merely appends it to the internal array, you
> get:
> > ["p2 error", ["p2 error", "p1 error"]]
> > Hope that helps explain what's going on, even if it I don't necessarily
> > agree with the ActiveModel implementation of those methods.
> > - Ben
> >
> >
> > On Wed, Aug 24, 2011 at 2:56 PM, Glenn Little <[email protected]>
> wrote:
> >>
> >> What's going on here:
> >>
> >> > p1 = Person.new
> >> > p2 = Person.new
> >>
> >> > p1.errors[:base] = "p1 error"
> >> > p2.errors[:base] = "p2 error"
> >>
> >> > p2.errors[:base] += p1.errors[:base]
> >> > p2.errors
> >>  => {:base=>["p2 error", ["p2 error", "p1 error"]]}
> >>
> >> Any ideas why I'm getting that extra array wrapper, as if I had used
> >> "<<"?  Not to mention the duplication of the p2 error?  Am I missing
> >> something dumb?
> >>
> >> Thanks for any insight...
> >>
> >> -glenn
> >>
> >> --
> >> SD Ruby mailing list
> >> [email protected]
> >> http://groups.google.com/group/sdruby
> >
> > --
> > SD Ruby mailing list
> > [email protected]
> > http://groups.google.com/group/sdruby
>
> --
> SD Ruby mailing list
> [email protected]
> http://groups.google.com/group/sdruby
>

-- 
SD Ruby mailing list
[email protected]
http://groups.google.com/group/sdruby

Reply via email to