Hey folks,
There's been a sort of pandemic that's arisen in #datamapper over the
past couple days that needs to be addressed regarding the behaviors of
#save and #valid?.
## Problem Description
The symptom that people are seeing is that their records fail to save
(returning false) while their records return true for #valid?. This
is caused when an object has a parent or child that fails validation
and thus refuse to save, thereby also blocking the object which #save
was called on from saving. Unsurprisingly users find this behavior
maddening due to the opacity of the issue, and lack of warning/
notification.
The root problem here is that #save is aware of and dependent upon the
state of the entire graph of objects that an object belongs to (see
code excerpted from dm-core's resource.rb), while #valid? and #dirty?
are not aware of the states of parent & child objects.
def _save(execute_hooks = true)
run_once(execute_hooks) do
save_parents(execute_hooks) && save_self(execute_hooks) &&
save_children(execute_hooks)
end
end
## Analysis
The validation and dirtiness APIs need to be brought in line with the
API for saving. So far as i can tell the behavior for #save can't
change. The Object Graph does need to be interrogated in order to
make sure objects are saved in the proper order (so foreign keys and
the like will be available for children to record).
That only leaves changing #valid? and #dirty? in line with #save.
There may be some objections to altering their behavior which
currently have the meaning "are this object's properties valid?" for
valid? and "have this object's properties been changed?", to also
incorporate knowledge of the state of child or parent objects (which i
am certainly sympathetic to).
## A suggested solution
What we need is something like a #saveable? method, which in turn
calls a validator for in-object properties, and one for other
associated objects. Whether that method is called #saveable? or
#valid? doesn't much bother me (though i lean towards altering the
behavior of #valid?).
In keeping with that idea, the current behavior for #valid? and
#dirty? could easily be moved to #valid_self? and #dirty_self? or
#valid_properties? and #dirty_properties?
## Open problems
* Should we rename #valid? or create a new #saveable? method?
* What should validation errors for a child or parent object actually
say? Should they actually have references to the invalid objects?
## Additional discussion
This email is the result of a discussion i had with solnic, so if
there are other suggestions or things he or i may have overlooked,
please let us know. This issue has been a serious problem for users
so it really is necessary to make sure we address it prior to the next
release.
Cheers!
-knowtheory
(P.S. please forgive the rambling, it's 7 am and i haven't slept yet!)
--
You received this message because you are subscribed to the Google Groups
"DataMapper" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/datamapper?hl=en.