Discussion:
[Modeling-users] Newbie question =)
Tom Hallman
2004-02-25 18:06:08 UTC
Permalink
Hi all,

Here's a situation I have, and I'm trying to figure out how best to do it
using Modeling.

I have a Person entity, and it has a ToMany relationship with BankAccount
entities. One of the attributes of BankAccount is "isDefault", which is 1 if
the particular account is (duh) the default one, and 0 otherwise.

So part of the validation logic for validateIsDefault(), I figure, should
make all other BankAccounts' isDefaults set to 0 if this new account is set
to 1.

The problem is that I'd like to get at the editing context which is
calling validateIsDefault in the first place, so that changing the other
isDefaults to 0 would *only* happen if the entire new account gets correctly
saved. (In other words, the ec I create in this function, I think, should be
a nested ec of the calling ec.)

Is there a way to do this? Or am I going about this in the wrong way?

Thanks for any insight!

~Tom

___________________________________________________________
Tom Hallman DiscipleMakers, Inc
***@dm.org http://www.dm.org/~hallmant
531 Brittany Dr * State College * PA * 16803 * 814-861-4591
Go therefore and make disciples of all nations (Matt 28:19)
Sebastien Bigaret
2004-02-25 19:29:05 UTC
Permalink
Hi,
Post by Tom Hallman
Hi all,
Here's a situation I have, and I'm trying to figure out how best to do it
using Modeling.
I have a Person entity, and it has a ToMany relationship with BankAccount
entities. One of the attributes of BankAccount is "isDefault", which is 1 if
the particular account is (duh) the default one, and 0 otherwise.
So part of the validation logic for validateIsDefault(), I figure, should
make all other BankAccounts' isDefaults set to 0 if this new account is set to
1.
Well, I would advise you not to change anything in the validation logic.
Even if nothing prevents you from doing this, there isn't much situation
which requires modification of the objects graph in validation methods.
To put it differently, i'd say that the validation logic is here to
prevent any bug or unhandled situations to be able to corrupt objects /
database invariants in any ways (just an advice, really, nothing in the
framework would prevent you to change objects during the validation
process)

In your case, I would rather:

- make a to-one relationship from Person to BankAcct,
named defaultBankAcct, with no inverse. This way, you have a dedicated
getter and setter for the default bank account.

- If you need to know if a BankAcct is a default, then add something
like this to BankAcct:

def isDefault(self):
return self is self.getPerson().getDefaultBankAcct()

(I'm here assuming that a BankAcct always have a related Person, which
is probably the case)

- Add the following validation method to Person:

def validateDefaultBankAcct(self, value):
if not self.value or self.value not in self.bankAccounts():
raise Validation.ValidationException

assuming here that you want to make sure that a default bank account
is always defined (*) --in addition to making sure that a default bank
acct is one of the person's; of course, you can additionally make sure
that the default bank account is part of the registered bank accounts
of a person in the setter setDefaultBankAcct().

(*) this also implies that a Person has at least one bank acct, btw.


I'll finally add that this is just a proposal, not the only way to do
it. You could have very good reasons to make it your way --for example,
if you have to use an already existing database. In this case, I'd
suggest however to keep the same API, with class Person controlling its
default bank acct; or alternatively to make BankAcct.setDefault() reset
the other getPerson().getBankAccts() --even if as for me, this option
seems really awkward :)
Post by Tom Hallman
The problem is that I'd like to get at the editing context which is calling
validateIsDefault in the first place, so that changing the other isDefaults to
0 would *only* happen if the entire new account gets correctly saved. (In
other words, the ec I create in this function, I think, should be a nested ec
of the calling ec.)
Is there a way to do this? Or am I going about this in the wrong way?
I'm not sure I fully understand your question here, so, to make it
clear:

- if you're only concerned by the data consistency, ie that a newly
created bank account, made the default one, cannot be saved in
database while other changes in the EC are saved, you only need one
EC: when an EditingContext savesChanges(), *all* changes are saved, or
*none* are saved.

- if you want to be able to cancel the process of:
- getting new properties for a new bank account,
- creating a new bank account with these properties,
- assigning it to a person,
- make it the default bank account,

at any point, without having to remember (in the code) whether you
already created the bank acct (in which case you need to delete() it),
or if it was already assigned to the person as the default (in which
case you need to restore the old default, hence you'll have to store
it before changing it), etc., well, if you do not want that, then yes!
an child EditingContext is your friend:

- create it,

- use it to create the new bank acct, etc.

- when finished, saveChanges(), then do not forget to saveChanges()
on its parent as well (the first one save the changes to the
parent, the second, to the database), OR simply delete it to
discard any changes made in the child EC.


Hope this helps!

-- Sébastien.
Sebastien Bigaret
2004-02-25 19:42:00 UTC
Permalink
Post by Sebastien Bigaret
Well, I would advise you not to change anything in the validation logic.
Even if nothing prevents you from doing this, there isn't much situation
which requires modification of the objects graph in validation methods.
To put it differently, i'd say that the validation logic is here to
prevent any bug or unhandled situations to be able to corrupt objects /
database invariants in any ways (just an advice, really, nothing in the
framework would prevent you to change objects during the validation
process)
However, in most cases you just cannot decide what to do if the
validation fails: suppose your validation logic fails because a person
has two default bank account, what should be done then? Randomly choose
one of them to be the default? Sounds awkward as well, doesnt it :))

-- Sébastien.

Loading...