Hi,

I am trying to implement mutual one to one relation for a node reference field. I mean that in my case, the node i reference have to be referenced just one time. Is there any way to make this sort of relation with the actual version of References?

I ve found an old module project on drupal.org wich is exactly what i am looking for, but for Drupal 6 and CCK Node Reference field :
http://drupal.org/project/cck_reference_filter

Thanks in advance for your answer.

Regards,

herve.

Comments

herve’s picture

I ve worked on this issue for my own, i share my code because i think it could be a way to implement this functionnality. At the moment, my method is to using hook_query_alter so it could be used in a custom module, and you don't need to alter the references module.

/**
 * 
 * Implementation of hook_query_alter() for my_module.
 * 
 * @param $query
 */
function my_module_query_alter($query){
  /*
   * Only for _node_reference_potential_references_standard queries
   */
  if ($query -> hasTag('node_access')
      && $query -> getMetaData('id') == ' _node_reference_potential_references_standard'){
    /*
     * Get the one to one fields list and his configuration
     */
    foreach(my_module_one_to_one_reference_fields() as $field){
      /*
       * We check the URL arguments to alter only some of references autocomplete results
       */
      if (arg(2) == $field['entity'] && 
          arg(3) == $field['bundle'] && 
          arg(4) == $field['field']){
        /*
         * We use the Drupal references convention to get field _nid and table name
         */    
        $join_field = $field['field'].'_nid';
        $join_table = 'field_data_'.$field['field'];
        /*
         * We join the actual _nid table and keep only the not referenced nodes
         */
        $query -> leftJoin($join_table, $field['alias'], 'n.nid = ' .$field['alias']. '.' .$join_field);
        $query -> isNull($join_field);
      }
    }
  }
}

/*
 * Define the one to one fields
 * This function should be turn  to a hook implementation
 *
 * @return an associative array keyed by :
 *     'entity' : the entity type where the field appears
 *     'bundle' : the bundle type where the field appears
 *     'field' : the field we ve to turn in one to one reference
 *     'alias' the table alias for leftJoin
 */
function my_module_one_to_one_reference_fields(){
  return array(
    'field_first_field' => array(
      'entity' => 'node',
      'bundle' => 'my_node_type',
      'field' => 'field_first_field',
      'alias' => '1st'
    ),
    'field_second_field' => array(
      'entity' => 'node',
      'bundle' => 'my_second_node_type',
      'field' => 'field_second_field',
      'alias' => '2nd'
    )
  );
}

Do you think this functionnality should be integrated in the references module? (in _node_reference_potential_references_standard function i suppose) Or should this functionnality should be integrated in a special module named one_to_one_references?
The data returned by my_module_one_to_one_reference_fields should be defined in a special hook, or/and with an UI.

Regards,

herve.