I'm building views on custom Entities. One of my Entities has a field which is an entity_reference with unlimited cardinality:
$fields['subjects'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Subjects'))
->setSetting('target_type', 'pw_subject')
->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED)
->setdisplayOptions('view', array(
'type' => 'entity_reference_entity_label'))
->setDisplayOptions('form', array(
'type' => 'entity_reference_autocomplete'));
Entity API creates a join table:
+--------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+------------------+------+-----+---------+-------+
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | NO | MUL | NULL | |
| langcode | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| subjects_target_id | int(10) unsigned | NO | MUL | NULL | |
+--------------------+------------------+------+-----+---------+-------+
When I try to add a views relationship to subjects views adds a left join to subjects using the non-existant subjects column rather than subjects_target_id
LEFT JOIN {pw_subject} pw_subject_pw_contact__subjects ON pw_contact__subjects.subjects = pw_subject_pw_contact__subjects.id
[I have also asked about this on stackexchange]
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | views_does_not_add_relationship_2795455_25.patch | 1.07 KB | jefuri |
| #13 | views_does_not_add_relationship_2795455_13.patch | 1023 bytes | tahirmus |
| #8 | views_does_not_add-2795455-8.patch | 960 bytes | gabesullice |
| #4 | views_can_t_make_a-2795455-4.patch | 974 bytes | gabesullice |
Comments
Comment #2
skitten commentedAfter a lot of time with XDebug I think the issue is in mapFieldDefinition() (EntityViewsData.php) - if I set $views_field_name = $schema_field_name (rather than $field_name) I get a query that works.
I'd love if someone who understands the views (and schema) code could tell me if this makes sense...
Comment #3
skitten commentedComment #4
gabesulliceI have replicated this issue (by having it myself ;) ) and can confirm that the suggestion in #2 resolves the problem.
Comment #6
gabesulliceAfter a lot more digging, I think the previous patch is simply a coincidental fix (obviously since it failed). I think the root cause is that the views module is only adding 'relationship field' data for entity_reference config fields, not base fields on entities.
If you look in views.views.inc, you'll notice an implementation of
hook_field_views_data, which adds this relationship data for all entity reference fields. The issue is that it is only called for fields which are defined in config, i.e., the code is not called for any entity_reference fields added on any custom entity types or added usinghook_entity_base_field_info.Comment #7
dawehnerYeah, this gap between the way how we generate configurable fields and base fields is just sad.
I could totally imagine that this is the right fix, but yeah we need some test coverage to ensure it happens.
Comment #8
gabesulliceOkay, I think I've found a more appropriate solution.
Comment #9
gabesulliceKicking tests.
Comment #10
lendudeMaybe use $field_definition->getFieldStorageDefinition()->getMainPropertyName() instead of hardcoding target_id?
Setting back to needs work for the test coverage.
Comment #11
geekygnr commented#8 solves the problem for me.
Comment #12
skitten commentedYeah, I also came to the conclusion of #6 that configurable fields do it right and base fields don't. So in the end I just had to add this field afterwards as a configurable field. Thanks for investigating!
Comment #13
tahirmus commentedAdded
$field_definition->getFieldStorageDefinition()->getMainPropertyName()as suggested in #10Comment #15
Roensby commentedPatch in #13 works for me. Thank you everyone for the work!
My test case:
Three entity types, A, B and C.
Entity type A has the following fields:
- entity reference field for B with a cardinality of 1
- entity reference field for C with unlimited cardinality
Create a view for A.
Add relationship to B.
Add a field with relationship to B.
This works both before and after patch.
Add relationship to C.
Add a field with relationship to C.
This fails before patch and works after patch.
Comment #17
grubshka_v2 commentedWhy the patch is only for fields with multiple values ?
I have the same problem with a single value field #2903687: Can't create referencing entities relationship on custom entity (See also #2895578: Views does not add reverse relationship data for entity_reference fields not defined in configuration)
Comment #18
sdrong commentedConfirming Patch #13 addresses CARDINALITY_UNLIMITED reference id issue when custom entity is defined in the class vs type/bundle db configuration. Please add to core or document preferred method of defining custom BaseFieldDefinitions for view compatibility.
Comment #19
gabesulliceMarking as RTBC by @sdrong
Comment #20
tacituseu commentedPer #10 it still needs test coverage,
Comment #21
benjy commentedThe patch doesn't align with the issue title here? It's not only multi cardinality fields that are an issue, any ER field that isn't defined in configuration is ignored by
core_field_views_data()#2895578: Views does not add reverse relationship data for entity_reference fields not defined in configuration could be a duplicate or we could rename the issue title here?Comment #22
borisson_I agree with @benjy, this patch doesn't do enough to fix the problem for single-value entity reference base fields. I think it's best to re title this issue and keep #2895578: Views does not add reverse relationship data for entity_reference fields not defined in configuration to do the other work.
We do have a views data unit test, but this looks like something that we would want to test with at least a kernel test. Is there a kernel test we could use to do this with or is a functional test sufficient?
Comment #24
jefuri commentedMissing an option for $views_field['filter']['argument'] here. This will still throw an SQL error when using contextual filters.
Comment #25
jefuri commentedComment #26
joachim commentedComment #28
acbramley commentedThis issue also applies to other non entity reference fields as well. For example I have an custom entity type with a file field. The views_views_data() function invokes hook_field_views_data but only for fields defined by a field_storage_config entity, so file_field_views_data() isn't called for my custom entity's file field, therefore the relationship isn't added.
Comment #29
joachim commentedI’m not quite sure what you mean by ‘non entity reference fields’ — isn’t a file field a type of entity reference field?
Comment #30
acbramley commented@joachim I guess you could argue that it is, but they're their own field type which is used as a prefix for hook_field_views_data() (e.g file_field_views_data()).
Comment #32
nicxvan commentedI believe I am encountering this issue.
The patch applies to 8.7.5 but does NOT fix the issue.
In my case I have a view that uses contextual filters to grab the user id.
It then creates a relationship to a entity reference field on that user for organizations and from that org entity it grabs a list of products referenced on the org entity.
The preview shows the proper list of products for a given user.
When I create an entity reference field that uses the view to populate itself the list is just organizations not the products.
Comment #34
bojanz commentedThe problem from the issue description was fixed in #2846614: Incorrect field name is used in views integration for multi-value base fields / Drupal 8.5.
#28 is about #2337515: Allow @FieldType to customize views data.
#32 sounds unrelated.