Docs Menu

Define a Realm Object Schema - Flutter SDK

On this page

An object schema is a configuration object that defines the properties and relationships of a Realm object. Realm client applications define object schemas with the native class implementation in their respective language using the Realm Object Model.

Object schemas specify constraints on object properties such as the data type of each property and whether or not a property is required. Schemas can also define relationships between object types in a realm.

1

Import the Realm SDK package at the top of your file.

2

Add a part directive to include the RealmObject file that you generate in step 4 in the same package as the file you're currently working on.

schemas.dart
part 'schemas.g.dart';
3

Create the model for your Realm schema in a private class. You must include the annotation RealmModel at the top of the class definition. Prepend the class name with an underscore to make it private. You'll generate the public RealmObject in step 4.

Add fields to the RealmModel. You can add all supported data types. Include additional behavior using property annotations.

schemas.dart
@RealmModel()
class _Car {
@PrimaryKey()
late String make;
late String? model;
late int? miles;
}
Tip
See also:
4

Generate the RealmObject, which you'll use in your application:

This command generates the file in the same directory as your model file. It has the name you specified in the part directive of step 2.

Tip
Track the generated file

Track the generated file in your version control system, such as git.

Example
File structure after generating model
.
├── my_model.dart
├── my_model.g.dart // newly generated file
├── myapp.dart
└── ...rest of application
5

Use the RealmObject that you generated in the previous step in your application. Since you included the generated file as part of the same package where you defined the RealmModel in step 2, access the RealmObject by importing the file with the RealmModel.

myapp.dart
import './schemas.dart';
final hondaCivic = Car('Honda', model: 'Civic', miles: 99);

You can reference other Realm models from your Realm model. This lets you create the following types of relationships between Realm objects:

Important
No directly embedding objects

You cannot directly embed one Realm object in another with the Flutter SDK at this time. You can only reference another Realm object.

To set up a many-to-one or one-to-one relationship, create a property in your model whose type is another model. Multiple objects can reference the same object.

Note
To-one relationships must be optional

When you declare a to-one relationship in your object model, it must be an optional property. If you try to make a to-one relationship required, Realm throws an exception at runtime.

@RealmModel()
class _Bike {
@PrimaryKey()
late int id;
late String name;
late _Person? owner;
}
@RealmModel()
class _Person {
@PrimaryKey()
late int id;
late String firstName;
late String lastName;
}

You can create a relationship between one object and any number of objects using a property of type List<T> in your application, where T is a Realm model class.

@RealmModel()
class _Scooter {
@PrimaryKey()
late int id;
late String name;
late _Person? owner;
}
@RealmModel()
class _ScooterShop {
@PrimaryKey()
late int id;
late String name;
late List<_Scooter> owner;
}

Use annotations to add functionality to properties in your Realm object models.

In Dart, value types are implicitly non-nullable, but can be made optional (nullable) by appending ?. Include ? to make properties optional.

class _Vehicle {
@PrimaryKey()
late int id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('wheels') // 'wheels' is property name in the RealmObject
late int numberOfWheels;
}

You can use the built-in language features to assign a default value to a property. Assign a default value in the property declaration.

class _Vehicle {
@PrimaryKey()
late int id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('wheels') // 'wheels' is property name in the RealmObject
late int numberOfWheels;
}

The PrimaryKey annotation indicates a primary key property. The primary key is a unique identifier for an object in a realm. No other objects of the same type may share an object's primary key.

Important aspects of primary keys:

  • You cannot change a primary key after adding an object to a realm.
  • Only add a primary key to one property in a RealmModel.
  • Only String and int can be primary keys.
  • Realm automatically indexes primary keys.
class _Vehicle {
@PrimaryKey()
late int id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('wheels') // 'wheels' is property name in the RealmObject
late int numberOfWheels;
}

If you add the Ignored annotation to a property in your RealmModel, the realm object generator doesn't include the property in the RealmObject schema.

class _Vehicle {
@PrimaryKey()
late int id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('wheels') // 'wheels' is property name in the RealmObject
late int numberOfWheels;
}

Add the Indexed annotation to create an index on the field. Indexes slightly slow down insertion, but can greatly speed up queries.

class _Vehicle {
@PrimaryKey()
late int id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('wheels') // 'wheels' is property name in the RealmObject
late int numberOfWheels;
}

The MapTo annotation indicates that a property should be persisted under a different name. It's useful when opening a Realm across different bindings where code style conventions can differ.

class _Vehicle {
@PrimaryKey()
late int id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('wheels') // 'wheels' is property name in the RealmObject
late int numberOfWheels;
}

Once you've completed your Realm model, you must generate the RealmObject class to use it in your application.

Run the following command to generate RealmObjects:

Running this creates a public class in a new file in the directory where you defined the RealmModel class per the Create Model section.

The generated file has the same base name as the file with your RealmModel, ending with .g.dart. For example if the file with your RealmModel is named my_model.dart, the generated file will be my_model.g.dart.

Note

Remember to include the generated file in a part directive in your RealmModel definition file.

my_model.dart
// ...import packages
part 'my_model.g.dart';
@RealmModel()
// ...model definition

If you'd like to watch your data models to generate RealmObject``s whenever there's a change, include the ``--watch flag in your command.

To clean the generator caches, include the --clean flag in your command. Cleaning the generator cache can be useful when debugging.

←  Realm Database Overview - Flutter SDKOpen & Close a Realm - Flutter SDK →
Give Feedback
© 2022 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.