I would also like to add something more to the topic, with two use cases involving a code of an application in my company.
We have several computed fields in our models, but we usually use callbacks to really compute fields since we had the same troubles regarding the fields checks.
The first example is computing the full name from two different fields (similar to your example), and we do that like this (this is weppy notation but it's easily translatable to vanilla pydal):
def _build_name(self, fields):
components = []
for key in ['first_name', 'last_name']:
val = fields.get(key)
if val:
components.append(val)
return " ".join(components)
@before_insert
def _create_name(self, fields):
fields['name'] = self._build_name(fields)
@before_update
def _store_ids_for_name_update(self, dbset, fields):
current._nameupd_contacts = dbset.select(self.id).column('id')
@after_update
def _update_name(self, dbset, fields):
if any(key in fields for key in ['first_name', 'last_name']):
ids = current._nameupd_contacts
if not all(key in fields for key in ['first_name', 'last_name']):
for rid in ids:
row = self.db(self.id == rid).select(self.first_name, self.last_name).first()
if not row:
continue
self.db(self.id == rid).update_naive(name=self._build_name(row))
else:
for rid in ids:
self.db(self.id == rid).update_naive(name=self._build_name(fields))
del current._nameupd_contacts
So here are the problems:
1) the computation should be performed if any of the fields `first_name` and `last_name` are specified (so i would ask for a `depends_on_any` and `depends_on_all` attributes instead of a `required_fields` to distinct the case
2) we need both fields even if the update specifies just one of them; would be nice to have an helper for this too, instead of the strange thing we're doing on the current object
3) all these checks should be made in a more efficient way
Another example is with financial things, for example we have a deals table with several computed columns depending on combination of other columns, eg if you specify a value we also need a discount one to compute the net_value field, but we want to reach an error when the discount is missing, not avoid to compute the net_value. So here are other problems:
1) the `depends_on_all` should take care of raising some exception if needed
2) this lead to the impossibility of handling some operations with the actual computation layer, because in this example, if I want to update several records i can only specify a single tuple of values for the value and the discount, so if I want to update several records with just the value and using the actual stored discount in each row, I need to perform single update operations. Is there any solution for this?
I hope I added some points for the discussion :)
/Giovanni