Model.valid? == model.save Assumption


#1

Changeset #2434 [http://dev.rubyonrails.org/changeset/2434] adds back
the assumption that model.valid? == model.save.

I was attempting to change the behavior of
ActiveRecord::StaleObjectError exceptions into being a base error in the
model. This can’t be done because save_with_validation ignores any
errors codes returned by it’s call chain of aliased updates. This
assumption means that any error that is not a validateable must be an
exception, which is what StaleObjectError is. However, to turn it into
an error in the model-- it has to hit the database as an update. There
is no way around this. If it checked the database in a validator, then
something else could still update it before the update command fired.

What I want is on a StaleObjectError to show a diff of the two records
in the base errors list. I’d prefer to do this with minimal mods to the
framework such that none of the existing code has to add error handlers
or other special devices. If I catch the error at a higher level and add
a new routine into the chain, it doesn’t call any of the call backs or
other routines.

Comments? Suggestions? Ideas? Bueler?

Shawn G.


#2

Shawn G. removed_email_address@domain.invalid wrote: Changeset #2434
[http://dev.rubyonrails.org/changeset/2434] adds back the assumption
that model.valid? == model.save.

I was attempting to change the behavior of
ActiveRecord::StaleObjectError exceptions into being a base error in the
model. This can’t be done because save_with_validation ignores any
errors codes returned by it’s call chain of aliased updates. This
assumption means that any error that is not a validateable must be an
exception, which is what StaleObjectError is. However, to turn it into
an error in the model-- it has to hit the database as an update. There
is no way around this. If it checked the database in a validator, then
something else could still update it before the update command fired.

What I want is on a StaleObjectError to show a diff of the two records
in the base errors list. I’d prefer to do this with minimal mods to the
framework such that none of the existing code has to add error handlers
or other special devices. If I catch the error at a higher level and add
a new routine into the chain, it doesn’t call any of the call backs or
other routines.

Here’s the code I would prefer as an extension:
ActiveRecord::Base.class_eval do
def update_stale_errors
update_with_stale_exception
rescue
errors.add_to_base(“You have attempted to update an out of date
record.\nEither someone else has updated or the back button was used.”)
false
end
alias_method :update_with_stale_exception,:update
alias_method :update, :update_stale_errors
end

Later I would start adding diff methods. But just to get this to work
is turning into a research project.