[issue] Unable to add a relationship in a embedded object stored in an array

Hi,

This seems to be a limitation (bug) on the Realm interace.
Consider a collection “Person” containing an embedded objet “Address”.
“Address” is made of several fields (strings, boolean,…) and one reference to an object in the “City” collection.

In that case, when creating the Realm schema there is no issue to create a relationship between Address.City and the related City._id.

That been said, if you want to update the schema to allow several addresses to be stored by placing them into an array, then it is not possible to create the relationship anymore.

Note that, switching to Development Mode and declare the same structure in your client app seems to work but then edition of the schema become impossible via the Realm web console.

 cannot define relationship for property "Address.city" which does not exist in schema for collection "Person"

Is there any workaround to this issue ?

thanks by advance.
regards
bruno

Hi @bruno_levx,

I’ve think that I’ve recreated what you’re seeing through the Realm UI. This is my (failed) relationship:

{
  "Address.city": {
    "foreign_key": "_id",
    "ref": "#/relationship/mongodb-atlas/forum/City",
    "is_list": true
  }
}

When you run in development mode, what shows up in the “Relationships” tab (or in the “Advanced Mode” doc?)

Hi Andrew,

If it’s created in dev mode, what is shown in the interface is exactly the same. That’s why I said we can’t modify the schema.
When switching in advanced mode, the relationship is simply not shown at all.

regards
Bruno

Hi Bruno, I was hoping to see what the relationship definition looked like when it was inferred from the app code in development mode – is that visible? Also, could you please share your application object definitions?

Andrew,
I remade the test.

here the code used in C#

public class Target : RealmObject
    {
        [PrimaryKey]
        [MapTo("_id")]
        public ObjectId Id { get; set; }
        [MapTo("__partition")]
        public string Partition { get; set; }
        [MapTo("data")]
        public string data { get; set; }
    }

    public class Parent_Emb : EmbeddedObject
    {
        [MapTo("_id")]
        public ObjectId Id { get; set; }
        [MapTo("__partition")]
        public string Partition { get; set; }
        [MapTo("createdOn")]
        public DateTimeOffset CreatedOn { get; set; }
        [MapTo("target")]
        public Target target  { get; set; }
    }

    public class Parent :RealmObject
    {
        [PrimaryKey]
        [MapTo("_id")]
        public ObjectId Id { get; set; }
        [MapTo("__partition")]
        public string Partition { get; set; }
        [MapTo("embedded")]
        public IList<Parent_Emb> embedded { get; }
    }
...
...
            Target target = new Target();
            target .Id = ObjectId.GenerateNewId();
            target .Partition = user.Id;
            target .data = "test";

            Parent p = new Parent();
            p.Id = ObjectId.GenerateNewId();
            p.Partition = user.Id;
            Parent_Emb pe = new Parent_Emb();
            pe.Id = ObjectId.GenerateNewId();
            pe.Partition = user.Id;
            pe.CreatedOn = DateTime.Now;
            p.embedded.Add(pe);

            realm.WriteAsync((realmt) =>
            {

                realmt.Add(target);
                realmt.Add(p);
                p.embedded[0].target = target;
            });

here is the relation created automatically :

{
  "embedded.[].target": {
    "ref": "#/relationship/mongodb-atlas/Establishment/Target",
    "foreign_key": "_id",
    "is_list": false
  }
}

if i switch in advanced mode, relation completly vanish:

{
  "roles": [],
  "filters": [],
  "schema": {
    "title": "Parent",
    "bsonType": "object",
    "required": [
      "_id"
    ],
    "properties": {
      "_id": {
        "bsonType": "objectId"
      },
      "__partition": {
        "bsonType": "string"
      },
      "embedded": {
        "bsonType": "array",
        "items": {
          "title": "Parent_Emb",
          "bsonType": "object",
          "required": [
            "_id",
            "createdOn"
          ],
          "properties": {
            "_id": {
              "bsonType": "objectId"
            },
            "__partition": {
              "bsonType": "string"
            },
            "createdOn": {
              "bsonType": "date"
            },
            "target": {
              "bsonType": "objectId"
            }
          }
        }
      }
    }
  }
}

if I try to modify the schema ( I.e. just adding a “s” to “target” property name ) , I got this message.

error validating rule relationships: cannot define relationship for property "embedded.[].target" which does not exist in schema for collection "Parent"

regards,
bruno

Thanks.

The UI allowed me to add this relationship:

{
  "Address.[].city": {
    "foreign_key": "_id",
    "ref": "#/relationship/mongodb-atlas/forum/City",
    "is_list": false
  }
}

The relationship doesn’t show in the “Advanced Mode” view for me either, but if I export the app then I can see that it is in the rules.json file rather than schema.json and so I think all is OK.

This is my Person schema:

{
  "title": "Person",
  "properties": {
    "Address": {
      "bsonType": "array",
      "items": {
        "bsonType": "object",
        "properties": {
          "city": {
            "bsonType": "string"
          },
          "Street": {
            "bsonType": "string"
          }
        }
      }
    },
    "Name": {
      "bsonType": "string"
    },
    "_id": {
      "bsonType": "objectId"
    }
  }
}

What happen if you try to change ‘Street’ to “Streets” in the UI.
Will I allow you to make the change ?

On my side it won’t. In other words, it works technically but it is impossible to do it in the UI only in dev mode.
This means, if a change is required, there is no other ways than turning dev mode on again then update the schema thru an app, what is a bit annoying if the app is already in production.

I think the issue is only in the schema validation rules that refuses the .[]. part of the relationship.

regards,
Bruno.

It lets me change Street to Streets without a problem. I set up the relationship before enabling sync, but I was still able to edit it after turning on sync (and without needing to use development mode). I get a warning when editing the schema and it restarts sync, but it seems to accept the change.

So this means I may miss something somewhere. On my side, it doesn’t even want to save the change.

error validating rule relationships: cannot define relationship for 
property "embedded.[].target" which does not exist in schema for collection "Parent"

Edit: After stoping dev mode and turning off/on the sync it seems to accept the change now…
I don’t exactly understand were i made a mistake but in the end, it seams to work.

Thanks for your time !

1 Like

@Andrew_Morgan
Just an additionnal question:
Is there any plan to add the possibility to create such link via the [Add Relationship] wizzard ?

for now, field declared in embedded object are not shown in the dropdown list.

thanks in advance.
regards

Hi @bruno_levx, I agree that this would be a good enhancement for the UI – I’d suggest up-voting this request (I just did :slight_smile: ) https://feedback.mongodb.com/forums/923521-realm/suggestions/40378120-allow-deeper-relationships-under-rules

1 Like