Create relationship betweeen content type and custom entity on specific field

I want to create a two-way relationship between a field in a custom entity (package_date) and the field in a content type (package).

I have been able to add a relationship from a view for package_date, but it only allows me to add the linked field to the view, not any other package_date field. When the view is saved, I get this error.

No entity type for field field_package_id on view package_dates in DrupalviewsPluginviewsHandlerBase->getEntityType() (line 697 of coremodulesviewssrcPluginviewsHandlerBase.php)

The package_date entity definition is the following.

namespace Drupalmy_moduleEntity;  use DrupalCoreEntityEntityStorageInterface; use DrupalCoreFieldBaseFieldDefinition; use DrupalCoreEntityContentEntityBase; use DrupalCoreEntityEntityTypeInterface; use DrupalCoreEntityEntityChangedTrait;  /**  * Defines the PackageDate entity.  *  * @ingroup package_date  *  * @ContentEntityType(  *   id = "package_date",  *   label = @Translation("Package Date"),  *   handlers = {  *     "view_builder" = "DrupalCoreEntityEntityViewBuilder",  *     "views_data" = "DrupalviewsEntityViewsData",  *   },  *   base_table = "package_date",  *   entity_keys = {  *     "id" = "id",  *     "uuid" = "uuid",  *   },  *   admin_permission = "administer package_date entity",  *   fieldable = true,  * )  */  class PackageDate extends ContentEntityBase {      use EntityChangedTrait;    /**    * {@inheritdoc}    *    * Define the field properties here.    *    */   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {          // Standard field, used as unique if primary index.         $fields['id'] = BaseFieldDefinition::create('integer')             ->setLabel(t('ID'))             ->setDescription(t('The ID of the Term entity.'))             ->setReadOnly(TRUE);          // Standard field, unique outside of the scope of the current project.         $fields['uuid'] = BaseFieldDefinition::create('uuid')             ->setLabel(t('UUID'))             ->setDescription(t('The UUID of the Contact entity.'))             ->setReadOnly(TRUE);      $fields['package_id'] = BaseFieldDefinition::create('integer')       ->setLabel(t('Package ID'))       ->setDisplayOptions('view', array(         'label' => 'above',         'type' => 'integer',         'weight' => 0,       ))       ->setDisplayConfigurable('view', TRUE);          $fields['start_datetime'] = BaseFieldDefinition::create('datetime')         ->setLabel('Package Start Time')         ->setDisplayOptions('view', array(             'label' => 'above',                 'type' => 'datetime',                 'weight' => 1,         ))         ->setSetting('datetime_type', 'datetime')         ->setSetting('timezone_override', '');          $fields['end_datetime'] = BaseFieldDefinition::create('datetime')         ->setLabel('Package End Time')         ->setDisplayOptions('view', array(             'label' => 'above',                 'type' => 'datetime',                 'weight' => 2,         ))         ->setSetting('datetime_type', 'datetime')         ->setSetting('timezone_override', '');      $fields['price'] = BaseFieldDefinition::create('decimal')       ->setLabel(t('Package Price'))       ->setSettings(array(           'precision' => 10,           'scale' => 4,           'decimal_separator' => '.',       ))       ->setDisplayOptions('view', array(         'label' => 'above',         'type' => 'decimal',         'weight' => 0,       ))       ->setDisplayConfigurable('view', TRUE);      $fields['capacity'] = BaseFieldDefinition::create('integer')       ->setLabel(t('Capacity'))       ->setDisplayOptions('view', array(         'label' => 'above',         'type' => 'integer',         'weight' => 0,       ))       ->setDisplayConfigurable('view', TRUE);      $fields['availability'] = BaseFieldDefinition::create('integer')       ->setLabel(t('Availability'))       ->setDisplayOptions('view', array(         'label' => 'above',         'type' => 'integer',         'weight' => 0,       ))       ->setDisplayConfigurable('view', TRUE);      $fields['created'] = BaseFieldDefinition::create('created')       ->setLabel(t('Created'))       ->setDescription(t('The time that the entity was created.'));      $fields['changed'] = BaseFieldDefinition::create('changed')       ->setLabel(t('Changed'))       ->setDescription(t('The time that the entity was last edited.'));      return $fields;   } } 

The hook_view_data() implementation uses the following code.

function my_module_views_data() {   $data['package_date']['table']['group'] = t('Package Dates');    $data['package_date']['table']['join'] = array(     // Index this array by the table name to which this table refers.     // 'left_field' is the primary key in the referenced table.     // 'field' is the foreign key in this table.     'node__field_package_id' => array(       'left_field' => 'field_package_id_value',       'field' => 'package_id',     ),   );    $data['package_date']['package_id'] = array(     'title' => t('Package ID'),     'relationship' => array(       'base' => 'node__field_package_id', // The name of the table to join with.       'base field' => 'field_package_id_value', // The name of the field on the joined table.       // 'field' => 'package_id' -- see hook_views_data_alter(); not needed here.       'handler' => 'views_handler_relationship',       'label' => t('Relationship between Package and Package Dates'),       'title' => t('Package to Package Dates Relationship'),       'id' => 'standard',     ),   );    return $data; } 

The exported view is the following one.

langcode: en status: true dependencies:   config:     - system.menu.admin   module:     - datetime     - pve     - user id: _package_dates label: 'Package Dates' module: views description: 'Display current cache of  Package Dates' tag: '' base_table: _package_date base_field: id core: 8.x display:   default:     display_plugin: default     id: default     display_title: Master     position: 0     display_options:       access:         type: perm         options:           perm: 'access site reports'       cache:         type: tag         options: {  }       query:         type: views_query         options:           disable_sql_rewrite: false           distinct: false           replica: false           query_comment: ''           query_tags: {  }       exposed_form:         type: basic         options:           submit_button: Apply           reset_button: false           reset_button_label: Reset           exposed_sorts_label: 'Sort by'           expose_sort_order: true           sort_asc_label: Asc           sort_desc_label: Desc       pager:         type: full         options:           items_per_page: 50           offset: 0           id: 0           total_pages: null           tags:             previous: ‹‹             next: ››             first: '« First'             last: 'Last »'           expose:             items_per_page: false             items_per_page_label: 'Items per page'             items_per_page_options: '5, 10, 25, 50'             items_per_page_options_all: false             items_per_page_options_all_label: '- All -'             offset: false             offset_label: Offset           quantity: 9       style:         type: table       row:         type: fields       fields:         _package_id:           table: _package_date           field: _package_id           id: _package_id           entity_type: null           entity_field: _package_id           plugin_id: field           relationship: none           group_type: group           admin_label: ''           label: 'Package ID'           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: number_integer           settings: {  }           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false         start_datetime:           id: start_datetime           table: _package_date           field: start_datetime           relationship: none           group_type: group           admin_label: ''           label: 'Package Start Time'           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: datetime_default           settings:             timezone_override: ''             format_type: medium           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false           entity_type: _package_date           entity_field: start_datetime           plugin_id: field         end_datetime:           id: end_datetime           table: _package_date           field: end_datetime           relationship: none           group_type: group           admin_label: ''           label: 'Package End Time'           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: datetime_default           settings:             timezone_override: ''             format_type: medium           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false           entity_type: _package_date           entity_field: end_datetime           plugin_id: field         availability:           id: availability           table: _package_date           field: availability           relationship: none           group_type: group           admin_label: ''           label: Availability           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: number_integer           settings:             thousand_separator: ''             prefix_suffix: true           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false           entity_type: _package_date           entity_field: availability           plugin_id: field         capacity:           id: capacity           table: _package_date           field: capacity           relationship: none           group_type: group           admin_label: ''           label: Capacity           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: number_integer           settings:             thousand_separator: ''             prefix_suffix: true           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false           entity_type: _package_date           entity_field: capacity           plugin_id: field         created:           id: created           table: _package_date           field: created           relationship: none           group_type: group           admin_label: ''           label: Created           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: timestamp           settings:             date_format: medium             custom_date_format: ''             timezone: ''           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false           entity_type: _package_date           entity_field: created           plugin_id: field         changed:           id: changed           table: _package_date           field: changed           relationship: none           group_type: group           admin_label: ''           label: Changed           exclude: false           alter:             alter_text: false             text: ''             make_link: false             path: ''             absolute: false             external: false             replace_spaces: false             path_case: none             trim_whitespace: false             alt: ''             rel: ''             link_class: ''             prefix: ''             suffix: ''             target: ''             nl2br: false             max_length: 0             word_boundary: true             ellipsis: true             more_link: false             more_link_text: ''             more_link_path: ''             strip_tags: false             trim: false             preserve_tags: ''             html: false           element_type: ''           element_class: ''           element_label_type: ''           element_label_class: ''           element_label_colon: true           element_wrapper_type: ''           element_wrapper_class: ''           element_default_classes: true           empty: ''           hide_empty: false           empty_zero: false           hide_alter_empty: true           click_sort_column: value           type: timestamp           settings:             date_format: medium             custom_date_format: ''             timezone: ''           group_column: value           group_columns: {  }           group_rows: true           delta_limit: 0           delta_offset: 0           delta_reversed: false           delta_first_last: false           multi_type: separator           separator: ', '           field_api_classes: false           entity_type: _package_date           entity_field: changed           plugin_id: field       filters: {  }       sorts: {  }       title: 'Package Dates'       header: {  }       footer: {  }       empty:         area_text_custom:           id: area_text_custom           table: views           field: area_text_custom           relationship: none           group_type: group           admin_label: ''           empty: true           tokenize: false           content: '<p>There is currently no data to display.</p>'           plugin_id: text_custom       relationships:         _package_id:           id: _package_id           table: _package_date           field: _package_id           relationship: none           group_type: group           admin_label: 'Relationship between Package and Package Dates'           required: false           entity_type: _package_date           entity_field: _package_id           plugin_id: standard       arguments: {  }       display_extenders: {  }     cache_metadata:       max-age: 0       contexts:         - 'languages:language_content'         - 'languages:language_interface'         - url.query_args         - user.permissions       tags: {  }   _package_dates_report:     display_plugin: page     id: _package_dates_report     display_title: 'Package Dates'     position: 1     display_options:       display_extenders: {  }       path: admin/-package-dates       menu:         type: normal         title: 'Package Dates'         description: ''         expanded: false         parent: system.admin_reports         weight: 0         context: '0'         menu_name: admin       display_description: ''     cache_metadata:       max-age: 0       contexts:         - 'languages:language_content'         - 'languages:language_interface'         - url.query_args         - user.permissions       tags: {  } 

It looks like the relationships property is the wrong way around, but I’m not sure.

I’d also like to be able to create a view for the package content type, and link this to the package_date entity. When trying to do so, I don’t have a relationship I can add.

I expect I’m missing one or more things to get this working, but I’m not sure what. At the very least, I think I need the inverse of the defined relationship, but I’m sure that’s not the only issue.

Sponsored by SupremePR
This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Create relationship betweeen content type and custom entity on specific field

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.