API Allow the modification of extraFields on a many_many relation #754

Closed
wants to merge 2 commits into from

4 participants

@howardgrigg

Before you could not modify the extraFields on a many_many relation without deleting and recreating the relation. This meant you would lose all saved extraFields and just have the one you added.

This is fixed with a new function modify().

Let me know what you think.

@howardgrigg howardgrigg API Allow modifying the extraFields on a many_many
Before you could not modify the extraFields on a many_many relation
without deleting and recreating the relation. This meant you would lose
all saved extraFields and just have the one you added. This is fixed
with modify().
361b865
@travisbot

This pull request fails (merged 361b865 into a71077c).

@sminnee
SilverStripe Ltd. member

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:

  • Create DataList::update($object) as a new way of writing $object.
  • Remove direct $object->write() calls in GridField, etc, in favour of $list->update($object).
  • Override ManyManyList::update() in a manner similar to Howard's suggestions.
  • Further down the line: introduce setFieldUpdatingHints(), or even look at automatically inferring this from filter() commands.

However, we'd need to agree on the API first.

@sminnee
SilverStripe Ltd. member
@travisbot

This pull request passes (merged 9efa246 into a71077c).

@chillu
SilverStripe Ltd. member

The immediate bug (removes extrafields on add) has been fixed in #810.
Sam's ideas are an ongoing discussion on the mailinglist,
and diverge quite a bit from the code changes in this pull request - so closing off.
Thanks for diving into this anyway, Howard! :)

@chillu chillu closed this Sep 22, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment