[Seaside] How do you handle constraints on persisted collections?

Miguel Enrique Cobá Martínez miguel.coba at gmail.com
Tue May 19 00:27:26 UTC 2009


Pat Maddox wrote:
> I'm trying to make the leap from RDBMS/ORM thinking to pure objects,
> and am running into some problems.  The first is how to handle
> constraints on collections, when the objects inside of that collection
> are mutable.  Quick example, ensuring that only one user exists with a
> certain username.  It's trivial to check that a username is available
> before adding the user to a UserRepository.  If a user can update his
> own username though, it'll bypass any check on the UserRepository and
> invalidate that constraint.  A couple options...

Maybe there should be fields that the user is not allowed to modify if 
it means so much for your app logic/consistency.

> 
> 1. Have a ChangeUsername command that reserves that username in the
> repo, tells the user object to change its username, and then tells the
> repo to free the original username
> 2. When user username: is called, publish a UsernameChanged event that
> the repository subscribes to.  The repo can choose to reject the
> change if it would violate the repo's constraints.
> 
I use the Memento pattern or some variation of it. The idea is to allow 
the user to modify some copy of the object and not the real object. Then 
after the proper valitation is done, the old object is discarded and 
replaced by the new object or the old object it is applied the same 
changes as the copy the user operated on. Something like this:

modifyUser: anUser
| user editor |
editor := UserEditor newFor: anUser copy. "check this method on Object"
editor validate
	ifTrue: [ ^ editor object ] "returns new object, after validation"
^ anUser "user not modified"

The method returns either the same object without modifications or a new 
object that passed validation and is now the new user object.
Of course, you can make the validation message to log errors somewhere 
to be shown to the user to retry the user modification.

Cheers,
Miguel Cobá



> The first is just a bit ugly and procedural.  The second requires the
> User object to publish events whenever something happens - which is
> easy to forget to do, or you're left with determining which method
> calls warrant the publishing of events.  Also you'd have to roll back
> the change if the event is rejected.
> 
> You could handle that stuff by writing some framework code to manage
> the tedious stuff...I don't love either approach though.  How do you
> guys tackle this sort of problem?
> 
> Pat
> _______________________________________________
> seaside mailing list
> seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
> 



More information about the seaside mailing list