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

Michael Forster mike at sharedlogic.ca
Tue May 19 21:59:18 UTC 2009


On Mon, May 18, 2009 at 6:50 PM, Pat Maddox <pat.maddox at gmail.com> 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...

Two aspects.

First, expressing the constraint itself, to which you alluded.  In
loose Relational Model parlance you're talking about a table
constraint, specifically, a key constraint.  From the OO perspective,
I think of these as constraints on the class.  However, I implement
them as instance methods to allow reference of the instance itself
and, thus, use of a single method for both insert and update checks.
For example:

MyClass>>checkUniqueName: aString
    | count |
    count := self repository count: [ :each | each name = aString and
each ~= self ].
    (count = 0) ifFalse: [ self error: 'Constraint violation: ',
aString, ' is not unique.' ]

Second, where to send the constraint check message.  For updates, I
just send it as a guard message in every accessor that mutates the
variable in question.  For inserts, it depends on how intimately you
tie instantiation and insertion. #checkUniqueName above works
correctly whether the instance is already in the repository or not.

Cheers,

Mike


More information about the seaside mailing list