-
Notifications
You must be signed in to change notification settings - Fork 821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Improve behaviour of unsaved has_one / belongs_to relations #7818
Comments
Partly implemented with #7819 (4.1, non-breaking changes only). |
Yeah that's a big omission in our API, and probably surprises every SS dev at least once.
That's a pretty big change in terms of API use. I agree that it'd be more elegant, but that'll break lots of code in subtle ways that we can't auto-upgrade. I've written hundreds of unguarded statements relying on the current behaviour over the years, e.g.
Many implementations will have explicitly written the relationship instead of using the
Yes, please! This one is probably a bit easier to auto-detect in an upgrader - basically warn whenever a |
I would probably see this as a case of errors silently failing to check assertions (e.g. checking email matching for a member that doesn't exist). As a developer, I would prefer the ORM failed early rather than silently allow possible errors to exist. The biggest problem I have is that these "new" blank records ambiguously need to persist; The fact that you have to specify the $writeComponents arg on write() is a poor solution to this; My preference is that if a component isn't intended to be written (never explicitly assigned) it should never be created. Big change, yes, hence a 5.0 major breaking change. :)
The important thing is that we can lazy-write the "wiring" up of the relations, not so much the data on the record themselves; The users will write these records up front because you HAVE to explicitly write them. Having auto-wiring frees the developers from having to manage write-order dependencies of trees of data.
We can make those writes conditional; I.e. ONLY write if records are changed, or if wiring is necessary but un-assigned. :P The idea is that we only ever need one write for each object, and the ORM will "magic" the order for these trees automatically to ensure this. |
Definitely in favour of this change. It’s frankly bizarre behaviour which newcomers to SilverStripe don’t expect (I’ve had to explain to people before why |
I'm also in favour of that API, but how much upgrade disruption is it worth? You'll have to go through every line of your project code that queries a has_one relationship, and check if they're guarded correctly. If you forget one, you'll likely deal with fatal errors and quite impactful logic failures. I'd only feel comfortable doing that if we can auto-parse all uses of has_one relationships and at least list their source code locations for easy review in |
I think most examples would be safe. Of course if you were just doing |
I wouldn't assume that everyone is as strict on code use as you are Damian ;) Once you're used to the idioms and peculiarities of an API, you're likely exploiting them if it means less code - case in point: I've done |
We can't be changing the has_one methods to return non-objects in the 4.x line |
No that's right. It'd be 5.x only. This RFC is for master (mostly), although I've added a few things to the last 4.1 release. |
This RFC proposes improvements and simplification to the has_one component behaviour on dataobjects, especially in relation to unsaved records.
Note: The below more or less apply to
belongs_to
as well.Current state
At the moment saving of relations works this way, with the following notes
$obj->SomeRelation()
->exists()
/->isInDB()
on this object; More expensive and error prone than simple falsey check.$obj->SomeRelationID = $obj->ID
return $obj->SomeRelation
$obj->SomeRelation = $obj
$obj->write()
doesn't save any related objects.Proposal
$obj->SomeRelation
/$obj->SomeRelation()
$obj->setComponent($componentName, $item)
$obj->SomeRelation = $item
$obj->write()
5.0 breaking changes
$obj->write()
Links
Related: #3832
The text was updated successfully, but these errors were encountered: