Closed (won't fix)
Project:
Drupal core
Version:
8.6.x-dev
Component:
field system
Priority:
Major
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
3 Jan 2015 at 00:59 UTC
Updated:
23 Oct 2018 at 12:42 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
plachWe have no setters so we cannot fix this in the Entity Manager, however base field definitions already take care of this, so we just need to do the same for configurable fields.
Let's try this.
Comment #3
plachHA!
Comment #4
plachWe should probably check all the property definitions instead.
Comment #5
penyaskitoI had this issue with my computed fields and it works like a charm for me. Thanks so much, plach.
Done #4, return true for isComputed() only if all the properties are computed.
Comment #7
penyaskitoOops, I did the opposite. Now for real, return true for isComputed() only if all the properties are computed, false otherwise.
Comment #8
penyaskitoTestbot, please?
Comment #9
penyaskitoIf you return an empty array in your schema, the site will break without the patch. Leaving at major because as a workaround you can define a column in the schema even if it is unused and the site won't break.
Comment #10
plachCan we get some test coverage?
Comment #11
penyaskitoI guess we cannot use unit tests as the typed data manager is not injected.
Comment #12
penyaskitoA test module which provides a computed field, and a test that 1) test that the computed field value is correct, 2) test that we can add a computed field instance to the user entity.
Comment #13
penyaskitoRemoving Needs tests tag
Comment #15
plachThe general approach looks, I've a few doubts on the implementation:
Missing PHP docs.
This looks weird, a property definition should use
DataReferenceDefinition. Moreover custom storage means nothing at property level.Is this required? Cannot we return an empty array?
Not sure this is necessary, I think we can collapse this logic into the field item class.
+1 :)
Comment #16
luismagr commentedI'm on the global sprint weekend and I'm going to work on that issue. I'm with penyaskito at the same room.
Comment #17
luismagr commentedAttending comment 15, I have done all except point 3.
Comment #18
luismagr commentedComment #20
penyaskito@luismagr When @plach said
DataReferenceDefinition, probably he meantDataDefinition.Comment #21
luismagr commentedOk, I have done again the interdiff and the patch.
Comment #22
luismagr commentedComment #24
penyaskitoThanks @luismagr for working on this!
@plach:
#15.3: for now it is necessary. If you think so, we may change that in the context of this issue or in a new one, but if you don't have the columns array the site breaks.
#15.4: I would expect then that overriding getValue() in the Item class will suffice, but test results don't agree. Should we add the class back or are we doing anything wrong? Maybe I misunderstood.
Comment #25
plachI think this should be
array('value' => 42). To be strict we should probably implement the::onChange()to make sure the property always holds 42, but since this is just a test field item I guess we can skip that.Nope, that's fine, thanks.
Comment #26
penyaskitoChanging getValue() to return array('value' => '42') gives the same failure.
Comment #27
plachThis should do the trick, time to find out what @yched thinks about this.
Comment #28
penyaskitoWaiting for @yched feedback, but IMHO having a different class as #12 has is "cleaner". For now, AFAIK the only computed field in core is ShortcutItem, and it is quite special (because it extends from StringItem). Having a clean implementation at one test can be helpful for pointing people looking for an example.
Comment #29
plachWell, IMHO creating a new data type just to return a fixed value is not cleaner. If I had a real use case I would not try to implement it that way :)
Having a good example in tests was exactly one of my goals. Anyway I'm not an expert in this area, I guess @yched will enlighten us.
Comment #30
yched commentedSo, yeah, computed fields...
We've had a running discussion with @fago in the past couple months about what those mean exactly. "Computed property" is fairly clear, but "Computed field" is much more blurry. Current code isn't really clear about what happens or should happen when a *field definition* uses "setComputed(TRUE)", and no use case was really formalized so far. The fact that the only core example (ShortcutItem) is kinda weird doesn't really help.
We opened #2392845: Add a trait to standardize handling of computed item lists about that, but didn't update it with our latest discussions so far :-/. I just did.
First conclusion over there is : "a computed field" is not the same than "a field with computed properties", which directly invalidates this patch here :-)
Comment #31
plachOk, we could then move the current implementation of
FieldStorageConfig::isComputed()directly toFieldStorageConfig::hasCustomStorage(), so we can fix at least the storage issue. It should be fairly easy to update the current code once #2392845: Add a trait to standardize handling of computed item lists is fixed.Comment #32
yched commentedI'm wondering if having the storage ignore "isComputed" and rely solely on "hasCustomStorage" is the right approach.
Maybe it should account for isComputed in itself ?
- If a property is computed, do not try to save it (and maybe also do not try to create a column - not sure, the field type schema() is not supposed to expose a column for a computed property)
- If a field is computed, then ignore it completely (no schema, no column, save nothing)
No definite opinion here, just wondering. As explained above, computed fields are still largely in design :-)
Maybe trying to imagine what a Mongo storage would need to do about computed fields and properties would help figure out more generally if and how "entity storages" should reason about computed fields and properties ?
Comment #33
plachAre you suggesting to change the storage schema handler directly to account also for computed properties?
Comment #34
yched commentedYes, possibly. But that's merely a question, just wondering.
A Mongo storage would definitely have to reason on computed *properties* (since it has no schema to exclude the property from being stored). Would it also have to reason on computed *fields*, or would it just treat them the same as "fields with custom storage" ?
Comment #35
plachLet's postpone this on #2392845: Add a trait to standardize handling of computed item lists.
Comment #40
jibran#2392845: Add a trait to standardize handling of computed item lists is in now.
Comment #41
wim leersI think you meant #2392845: Add a trait to standardize handling of computed item lists :)
Queued test, back to NR!
Comment #42
wim leersUgh, that is the issue @jibran linked to, but in #35 it's still showing the old title, which is how I got confused :P Sorry!
Comment #44
claudiu.cristeaI applied the patch and tried to create a computed field as the one from the test. Then I tried to add a new field from UI but that is throwing an exception. This is because Drupal is still creating the storage tables. The field storage tables have only the standard columns (bundle, deleted, entity_id, revision_id, langcode, delta).
On the other hand, I see that now we have a 'custom_storage' property in FieldStorageConfig but I wonder how we set this on field type, so that when creating a new FieldStorageConfig this is read from the field type and saved in the config entity.
The exception:
Comment #45
amateescu commentedI opened an issue to discuss if the "computed field" concept makes sense for configurable fields: #2932273: Figure out how to implement configurable computed fields
Comment #46
wim leersComment #47
alan d. commentedI bypassed the error in #44(without having applied the patch) using a quick hack on countFieldData()
Looking at this issue from the field system for a few hours and I'm still not the wiser on the right way to workaround it....
It was this comment on Drupal\Core\Field\FieldItemInterface::schema() that suggested to me that nothing else would be required.
With the patch from #27, maybe extend this with
And trivial mute point, shouldn't TestComputedFieldItem::schema() happily work as per the doc comment? i.e. no columns array.
Comment #50
geek-merlinMy first reaction for this issue was, yes, totally makes sense. Today i stumbled across an example in the wild that uses a computed field that must live in the DB to suit views: https://github.com/Gizra/og/blob/8.x-1.x/src/Plugin/Field/FieldType/OgGr...
As OTOH all computed fields living out there i have seen set their custom_storage, i'd say this is a wontfix or at most documentation issue.
Comment #51
tstoecklerI think we should close this in favor of #2986836: Support computed bundle fields by adding the notion of computed field storage definitions. I think the notion of having custom storage is a different one than the notion of computed. And we should avoid mixing two concepts which are already complicated on their own.
Comment #52
wim leers#51 sounds sensible to me.
Comment #53
geek-merlin> And we should avoid mixing two concepts which are already complicated on their own.
A wholehearted sigh on this too.
That said, +1 for #51.
Comment #54
tstoecklerOK, 2 +1's is enough for me. If there is strong pushback we can always re-open.