Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded Objects #2676

Closed
2 of 4 tasks
RealmBot opened this issue Jan 7, 2020 · 12 comments
Closed
2 of 4 tasks

Embedded Objects #2676

RealmBot opened this issue Jan 7, 2020 · 12 comments
Assignees

Comments

@RealmBot
Copy link
Collaborator

RealmBot commented Jan 7, 2020

See RPM-72 for details.

  • Expand embedded object schema
  • Accessor (node.js)
  • Accessor (RN)
  • Tests

PR: #2724

@RealmBot RealmBot reopened this Jan 22, 2020
@kneth
Copy link
Contributor

kneth commented Jan 23, 2020

The schema can be extended to look like:

const Person = {
  name: 'Person',
  primaryKey: 'id',
  embeddedObject: false,   // this is the default value
  properties: {
    id: 'int',
    firstName: 'string',
    lastName: 'string',
    robots: 'Robot[]'
  }
};

const Robot = {
  name: 'Robot',
  embeddedObject: true,
  properties: {
    name: 'string',
    builder: 'string'
  }
};

The new schema attribute embeddedObject is true if a table/class can only be used as an embedded object.

Creating a nested object:

realm.create('Person', {
  id: 42,
  firstName: 'Arthur',
  lastName: 'Dent',
  robots: [{
    name: 'Marvin',
    builder: 'Sirius Cybernetics Corporation'
  }]
});

Alternatively, the object can be created in two steps:

let marvin = realm.create('Robot', {
  name: 'Marvin',
  builder: 'Sirius Cybernetics Corporation'
  }
);
realm.create('Person', {
  id: 42,
  firstName: 'Arthur',
  lastName: 'Dent',
  robots: [marvin]
});

@kraenhansen
Copy link
Member

kraenhansen commented Jan 24, 2020

I would suggest the shorter embedded over embeddedObject.

@kraenhansen
Copy link
Member

kraenhansen commented Jan 24, 2020

Also - I think the two step approach of first creating an embedded object and then embedding it should not be supported, as the scope reads:

An embedded object can only be created along with a link to it.

If it was not the case, what would happen to the embedded object if it never gets embedded?

@kraenhansen
Copy link
Member

kraenhansen commented Jan 24, 2020

Another suggestion could be to allow defining the schema of an embedded object, in the definition of the parent object:

const Person = {
  name: 'Person',
  primaryKey: 'id',
  properties: {
    id: 'int',
    firstName: 'string',
    lastName: 'string',
    robots: {
      type: 'list',
      objectType: {
        name: 'Robot',
        properties: {
          name: 'string',
          builder: 'string'
        }
      }
    }
  }
};

The user don't need to specify that the "Robot" is embedded as this is the only case where "objectType" is an object instead of a string.

A simple (not a list) link to an embedded object could be represented as:

const Person = {
  name: 'Person',
  primaryKey: 'id',
  properties: {
    id: 'int',
    firstName: 'string',
    lastName: 'string',
    robot: {
      name: 'Robot',
      properties: {
        name: 'string',
        builder: 'string'
      }
    }
  }
};

We can identify the embedded object definition as its now missing a type field and defines a properties object.

@cmelchior
Copy link
Contributor

Keep in mind that embedded Object is allowed to be embedded in multiple places (e.g the type of the parent might not be fixed)

@kneth
Copy link
Contributor

kneth commented Jan 24, 2020

Keep in mind that embedded Object is allowed to be embedded in multiple places (e.g the type of the parent might not be fixed)

The suggestion by @kraenhansen above is very natural for a JS developer - but is a restriction compared to my initial suggestion. Therefore I believe we should support both.

@kraenhansen
Copy link
Member

As @kneth's suggestion is the only one that supports the full scope of the feature, I think we should start with that and keep my suggestion as an idea for future improvements.

@blagoev
Copy link
Contributor

blagoev commented Jan 24, 2020

Can we move the discussion on the design doc. Thus having the final decision there and iterating over it at once

@blagoev
Copy link
Contributor

blagoev commented Jan 24, 2020

I think this should/will not be allowed in the other SDKs

let marvin = realm.create('Robot', {
  name: 'Marvin',
  builder: 'Sirius Cybernetics Corporation'
  }
);

@blagoev
Copy link
Contributor

blagoev commented Jan 24, 2020

UPDATE on the above: there is no consensus on that

@kraenhansen
Copy link
Member

kraenhansen commented Jan 24, 2020

Can we move the discussion on the design doc. Thus having the final decision there and iterating over it at once

Sure thing - I think @kneth's intention on his initial comment was just to kick off a discussion before we started adding stuff to the doc. I see no reason that we cannot more this into the doc.

I think this should/will not be allowed in the other SDKs

let marvin = realm.create('Robot', {
  name: 'Marvin',
  builder: 'Sirius Cybernetics Corporation'
  }
);

I agree, thats what I ment by #2676 (comment).

@reanzi
Copy link

reanzi commented Feb 15, 2022

const Person = {
  name: 'Person',
  primaryKey: 'id',
  properties: {
    id: 'int',
    firstName: 'string',
    lastName: 'string',
    robots: {
      type: 'list',
      objectType: {
        name: 'Robot',
        properties: {
          name: 'string',
          builder: 'string'
        }
      }
    }
  }
};

I having to trouble to embed data , tried above @kraenhansen approach but didn't work,
I get this error:

Error: Exception in HostFunction: Error while parsing property 'passangers' of object with name 'Permits'. Error: objectType must be of type 'string', got ([object Object])

This is My Schema :
I have used both approacht (commented out the one from the docs for now)

const PermitSchema = {
  name: 'Permits',
  properties: {
    _id: 'objectId?',
    __v: 'int?',
    _partition: 'string',
    cargo_type: 'string?',
    location: 'string?',
    passangers: {
      type: 'list',
      objectType: {
        name: 'Passanger',
        properties: {
          name: 'string?',
          phone: 'string?',
        },
      },
    },
    // quantity: {type: 'list', objectType: 'Quantity'},
    where_to: 'string?',
    updatedAt: 'date?',
  },
  primaryKey: '_id',
};

const permit_quantitySchema = {
  name: 'Quantity',
  embedded: true,
  properties: {
    amount: 'int?',
    unit: {type: 'string?', enum: ['ndoo', 'djaba', 'pieces', 'gunia']},
  },
};

export default PermitSchema;

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants