I don't want to bolt on a new API for this without thinking a bit more carefully about what we're doing.
Right now the way you write an object is to call the write method on the object itself:
$list = $something->SomeManyManyRelation();
$object = $list->First();
$object->SomeField = "value";
$object->SomeManyManyExtraField = "value";
$object->write();
This is fine for regular fields but breaks down with many_many_extraFields:
$list = $something->SomeManyManyRelation();
$object = $list->First();
$object->SomeManyManyExtraField = "value";
$object->write(); // nothing happens
Rather than have a special way of dealing with many_many_extraFields, I'd prefer to have a generalised API that classes like GridField can "just use" without worrying about the details. This would work:
$list = $something->SomeManyManyRelation();
$object = $list->First();
$object->SomeManyManyExtraField = "value";
$list->update($object); // calls $object->write() as well as updating the many-many list
This could be extended to things other than many-many list:
$openIssues = Issue::get()->filter(array("Status" => "Open"));
// This new API would define what happens when an record is added to this list
$openIssues->setFieldUpdatingHints(array("Status" => "Open"));
$i = new Issue;
$i->Title = "Something";
$openIssues->update($i); // Status would be set to "Open" as well as $i being written to the database.
If used consistently, the DataObjects wouldn't need to worry about their own persistence nearly as much, which would make it easier to swap in different persistence back-ends.
It's in this context that I think we should solve the problem that Howard has identified. As I've spec'ed it out, it would mean:
DataList::update($object)
as a new way of writing $object.$object->write()
calls in GridField, etc, in favour of $list->update($object)
.ManyManyList::update()
in a manner similar to Howard's suggestions.setFieldUpdatingHints()
, or even look at automatically inferring this fromfilter()
commands.However, we'd need to agree on the API first.