Index: relation.field.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/relation/relation.field.inc,v
retrieving revision 1.1
diff -u -p -r1.1 relation.field.inc
--- relation.field.inc	24 Nov 2010 20:57:49 -0000	1.1
+++ relation.field.inc	2 Dec 2010 10:56:23 -0000
@@ -27,34 +27,45 @@ function relation_field_info() {
 /**
  * Implements hook_field_is_empty().
  */
-function relation_field_is_empty() {
+function relation_field_is_empty($item, $field) {
+  if (empty($item['entity_id'])) {
+    return TRUE;
+  }
   return FALSE;
 }
 
 /**
- * Implements hook_field_insert().
+ * Implements hook_field_presave().
  */
-function relation_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  list($entity_id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
-  $insert1 = db_insert('relation')->fields(array('predicate'));
-  $insert2 = db_insert('relation_data')->fields(array('relation_id', 'entity_type', 'entity_id'));
+function relation_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
+  $field_name = $field['field_name'];
+  $eids = entity_extract_ids($entity_type, $entity);
   foreach ($items as $item) {
-    if (!empty($item['entity_id'])) {
-      $relation_id = $insert1->values(array($field['field_name']))->execute();
-      $insert2->values(array($relation_id, $item['entity_type'], $item['entity_id']));
-      $insert2->values(array($relation_id, $entity_type, $entity_id));
+    //get target entities individually, because they may be of different types.
+    $target = entity_load($item['entity_type'], array($item['entity_type']));
+    $ids = entity_extract_ids($item['entity_type'], $target);
+    $exists = FALSE;
+    //check to see if this relationship already exists, and which field value contains it.
+    foreach ($target->{$field_name}[$langcode] as $key => $value) {
+      if ($value['entity_id'] = $entity[$ids[0]]) {
+        $exists = TRUE;
+        $index = $key;
+      }
     }
-  }
-  $insert2->execute();
-  $items = array();
-}
+    if ($exists = TRUE) {
+      //update field value
+      $target->{$field_name}[$langcode][$index] = $item;
+      $target->{$field_name}[$langcode][$index]['entity_type'] = $entity_type;
+      $target->{$field_name}[$langcode][$index]['entity_id'] = $eids[0];
 
-/**
- * Implements hook_field_update().
- */
-function relation_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  relation_field_delete($entity_type, $entity, $field, $instance, $langcode, $items);
-  relation_field_insert($entity_type, $entity, $field, $instance, $langcode, $items);
+    }
+    else {
+      $target->{$field_name}[$langcode][] = $item;
+      $target->{$field_name}[$langcode][]['entity_type'] = $entity_type;
+      $target->{$field_name}[$langcode][]['entity_id'] = $eids[0];
+    }
+    entity_save($item['entity_type'], $target);
+  }
 }
 
 /**
@@ -114,7 +125,7 @@ function relation_field_widget_form(&$fo
   $element['entity_type'] = array(
     '#type' => 'select',
     '#title' => t('Entity type'),
-    '#options' => drupal_map_assoc(array_keys(entity_get_info())),
+    '#options' => drupal_map_assoc(relation_get_possible_targets($field['field_name'])),
     '#default_value' => isset($items[$delta]) ? $items[$delta]['entity_type'] : '',
   );
   $element['entity_id'] = array(
@@ -122,6 +133,10 @@ function relation_field_widget_form(&$fo
     '#type' => 'textfield',
     '#default_value' => isset($items[$delta]) ? $items[$delta]['entity_id'] : '',
   );
+  $element['relation_id'] = array(
+    '#type' => 'hidden',
+    '#value' => !empty($items[$delta]['relation_id']) ? $items[$delta]['relation_id'] : db_next_id(),
+  );
   return $element;
 }
 
@@ -172,3 +187,14 @@ function relation_field_formatter_prepar
     }
   }
 }
+
+/**
+ * Helper function to get all entity types with given field attached.
+ */
+function relation_get_possible_targets($field_name) {
+  $instances = field_read_instances(array("field_name" => $field_name));
+  foreach ($instances as $instance) {
+    $entity_types[$instance['entity_type']] = TRUE;
+  };
+  return array_keys($entity_types);
+}
Index: relation.info
===================================================================
RCS file: /cvs/drupal/contributions/modules/relation/relation.info,v
retrieving revision 1.3
diff -u -p -r1.3 relation.info
--- relation.info	24 Nov 2010 21:12:52 -0000	1.3
+++ relation.info	2 Dec 2010 10:56:23 -0000
@@ -1,6 +1,7 @@
 ; $Id: relation.info,v 1.3 2010/11/24 21:12:52 sun Exp $
 name = Relation
 description = Describes relationships between entities.
+dependencies[] = entity
 core = 7.x
 files[] = relation.module
 files[] = relation.field.inc
