Skip to content

Commit 7820869

Browse files
author
Mohammad Hunan Chughtai
authored
(DOCSP-26992): @realm/react-ify "Relationships - React Native SDK" (#2473)
1 parent ee416d7 commit 7820869

37 files changed

+1630
-163
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Realm from 'realm';
2+
// :snippet-start: js-inverserelationshippost-schema
3+
class Post extends Realm.Object {
4+
static schema = {
5+
name: 'Post',
6+
properties: {
7+
_id: 'objectId',
8+
title: 'string',
9+
user: {
10+
type: 'linkingObjects',
11+
objectType: 'User',
12+
property: 'posts',
13+
},
14+
},
15+
primaryKey: '_id',
16+
};
17+
}
18+
// :snippet-end:
19+
20+
export default Post;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Realm from 'realm';
2+
3+
// :snippet-start: js-pet-schema
4+
class Pet extends Realm.Object {
5+
static schema = {
6+
name: 'Pet',
7+
properties: {
8+
name: 'string',
9+
age: 'int',
10+
animalType: 'string?',
11+
},
12+
};
13+
}
14+
// :snippet-end:
15+
export default Pet;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Realm from 'realm';
2+
3+
// :snippet-start: js-petowner-schema
4+
class PetOwner extends Realm.Object {
5+
static schema = {
6+
name: 'PetOwner',
7+
properties: {
8+
name: 'string',
9+
birthdate: 'date',
10+
pet: 'Pet?',
11+
},
12+
};
13+
}
14+
// :snippet-end:
15+
export default PetOwner;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Realm from 'realm';
2+
// :snippet-start: js-post-schema
3+
class Post extends Realm.Object {
4+
static schema = {
5+
name: 'Post',
6+
properties: {
7+
_id: 'objectId',
8+
title: 'string',
9+
},
10+
primaryKey: '_id',
11+
};
12+
}
13+
// :snippet-end:
14+
15+
export default Post;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Realm from 'realm';
2+
3+
// :snippet-start: js-user-schema
4+
class User extends Realm.Object {
5+
static schema = {
6+
name: 'User',
7+
properties: {
8+
_id: 'objectId',
9+
name: 'string',
10+
birthdate: 'date?',
11+
posts: 'Post[]',
12+
},
13+
primaryKey: '_id',
14+
};
15+
}
16+
// :snippet-end:
17+
18+
export default User;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import React, {useMemo} from 'react';
2+
import {View, Text} from 'react-native';
3+
import {render, waitFor} from '@testing-library/react-native';
4+
import Realm from 'realm';
5+
import {createRealmContext} from '@realm/react';
6+
import User from '../../Models/User';
7+
import Post from '../../Models/Post';
8+
9+
const realmConfig = {
10+
schema: [User, Post],
11+
deleteRealmIfMigrationNeeded: true,
12+
};
13+
14+
const {RealmProvider, useObject, useQuery} = createRealmContext(realmConfig);
15+
16+
let realm;
17+
18+
// test describe block for the relationship page
19+
describe('relationships tests', () => {
20+
beforeEach(async () => {
21+
// we will use this Realm for assertions to access Realm Objects outside of a Functional Component (like required by @realm/react)
22+
realm = await Realm.open(realmConfig);
23+
24+
// delete every object in the realmConfig in the Realm to make test idempotent
25+
realm.write(() => {
26+
realm.delete(realm.objects(User));
27+
realm.delete(realm.objects(Post));
28+
29+
const user1 = realm.create(User, {
30+
_id: new Realm.BSON.ObjectId(),
31+
name: 'John Doe',
32+
birthdate: new Date(1990, 0, 1),
33+
});
34+
const user2 = realm.create(User, {
35+
_id: new Realm.BSON.ObjectId(),
36+
name: 'Jane Doe',
37+
birthdate: new Date(1993, 6, 3),
38+
});
39+
const user3 = realm.create(User, {
40+
_id: new Realm.BSON.ObjectId(),
41+
name: 'Billy Bob',
42+
birthdate: new Date(2002, 9, 14),
43+
});
44+
45+
const post1 = realm.create(Post, {
46+
_id: new Realm.BSON.ObjectId(),
47+
title: 'My First Post',
48+
});
49+
const post2 = realm.create(Post, {
50+
_id: new Realm.BSON.ObjectId(),
51+
title: 'My Second Post',
52+
});
53+
user1.posts.push(post1);
54+
user1.posts.push(post2);
55+
56+
const post3 = realm.create(Post, {
57+
_id: new Realm.BSON.ObjectId(),
58+
title: 'Row Row Row Your Boat',
59+
});
60+
const post4 = realm.create(Post, {
61+
_id: new Realm.BSON.ObjectId(),
62+
title: 'Life is but a dream',
63+
});
64+
user2.posts.push(post3);
65+
user2.posts.push(post4);
66+
67+
const post5 = realm.create(Post, {
68+
_id: new Realm.BSON.ObjectId(),
69+
title: 'I am not a child but I am not old either',
70+
});
71+
const post6 = realm.create(Post, {
72+
_id: new Realm.BSON.ObjectId(),
73+
title: 'My favorite food is pizza',
74+
});
75+
user3.posts.push(post5);
76+
user3.posts.push(post6);
77+
});
78+
});
79+
80+
afterAll(() => {
81+
if (!realm.isClosed) {
82+
realm.close();
83+
}
84+
});
85+
86+
it('Query Backlinks with Realm.Object.linkingObjects()', async () => {
87+
// :snippet-start: dynamically-obtain-inverse-relationship
88+
// :replace-start: {
89+
// "terms": {
90+
// " testID='postTitle'": "",
91+
// " testID='userName'": ""
92+
// }
93+
// }
94+
const PostItem = ({_id}) => {
95+
const post = useObject(Post, _id);
96+
const user = post?.linkingObjects('User', 'posts')[0];
97+
98+
if (!post || !user) return <Text>The post or user could not be found</Text>;
99+
return (
100+
<View>
101+
<Text testID='postTitle'>Post title: {post.title}</Text>
102+
<Text testID='userName'>Post created by: {user.name}</Text>
103+
</View>
104+
);
105+
};
106+
// :replace-end:
107+
// :snippet-end:
108+
const postId = realm.objects(Post)[0]._id;
109+
110+
const App = () => (
111+
<RealmProvider>
112+
<PostItem _id={postId} />
113+
</RealmProvider>
114+
);
115+
116+
const {getByTestId} = render(<App />);
117+
118+
await waitFor(() => {
119+
expect(getByTestId('postTitle')).toHaveTextContent('Post title: My First Post');
120+
expect(getByTestId('userName')).toHaveTextContent('Post created by: John Doe');
121+
});
122+
});
123+
124+
it('Query Backlinks with @links.<Type>.<Property>', async () => {
125+
// :snippet-start: query-backlinks
126+
// :replace-start: {
127+
// "terms": {
128+
// " testID={`Post ${i}`}": "",
129+
// ", i": ""
130+
// }
131+
// }
132+
const PostsByYoungUsers = () => {
133+
const posts = useQuery(Post);
134+
const postsByYoungUsers = useMemo(() => {
135+
return posts.filtered('@links.User.posts.birthdate >= 2000-01-01@00:00:00:0');
136+
}, [posts]);
137+
138+
if (!posts) return <Text>The post was not found.</Text>;
139+
return (
140+
<View>
141+
<Text>Posts By Young Users</Text>
142+
{postsByYoungUsers.map((post, i) => (
143+
<Text testID={`Post ${i}`} key={post._id.toHexString()}>
144+
{post.title}
145+
</Text>
146+
))}
147+
</View>
148+
);
149+
};
150+
// :replace-end:
151+
// :snippet-end:
152+
153+
const App = () => (
154+
<RealmProvider>
155+
<PostsByYoungUsers />
156+
</RealmProvider>
157+
);
158+
159+
const {getByTestId} = render(<App />);
160+
161+
await waitFor(() => {
162+
expect(getByTestId('Post 0')).toHaveTextContent('I am not a child but I am not old either');
163+
expect(getByTestId('Post 1')).toHaveTextContent('My favorite food is pizza');
164+
});
165+
});
166+
167+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Realm from 'realm';
2+
import User from './User';
3+
4+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
5+
// :snippet-start: ts-inverserelationshippost-schema
6+
class Post extends Realm.Object<Post> {
7+
_id!: Realm.BSON.ObjectId;
8+
title!: string;
9+
user!: Realm.Results<User>;
10+
11+
static schema = {
12+
name: 'Post',
13+
properties: {
14+
_id: 'objectId',
15+
title: 'string',
16+
user: {
17+
type: 'linkingObjects',
18+
objectType: 'User',
19+
property: 'posts',
20+
},
21+
},
22+
primaryKey: '_id',
23+
};
24+
}
25+
// :snippet-end:
26+
27+
export default Post;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Realm from 'realm';
2+
3+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
4+
// :snippet-start: ts-pet-schema
5+
class Pet extends Realm.Object<Pet> {
6+
name!: string;
7+
age!: number;
8+
animalType!: string;
9+
10+
static schema = {
11+
name: 'Pet',
12+
properties: {
13+
name: 'string',
14+
age: 'int',
15+
animalType: 'string?',
16+
},
17+
};
18+
}
19+
// :snippet-end:
20+
export default Pet;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Realm from 'realm';
2+
import Pet from './Pet';
3+
4+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
5+
// :snippet-start: ts-petowner-schema
6+
class PetOwner extends Realm.Object<PetOwner> {
7+
name!: string;
8+
birthDate?: Date;
9+
pet?: Pet;
10+
11+
static schema = {
12+
name: 'PetOwner',
13+
properties: {
14+
name: 'string',
15+
birthdate: 'date',
16+
pet: 'Pet?',
17+
},
18+
};
19+
}
20+
// :snippet-end:
21+
export default PetOwner;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Realm from 'realm';
2+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
3+
// :snippet-start: ts-post-schema
4+
class Post extends Realm.Object<Post, "_id" | "title"> {
5+
_id!: Realm.BSON.ObjectId;
6+
title!: string;
7+
8+
static schema = {
9+
name: 'Post',
10+
properties: {
11+
_id: 'objectId',
12+
title: 'string',
13+
},
14+
primaryKey: '_id',
15+
};
16+
}
17+
// :snippet-end:
18+
19+
export default Post;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Realm from 'realm';
2+
import Post from './Post';
3+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
4+
// :snippet-start: ts-user-schema
5+
class User extends Realm.Object<User, "_id" | "name"> {
6+
_id!: Realm.BSON.ObjectId;
7+
name!: string;
8+
birthdate?: Date;
9+
posts!: Realm.List<Post>;
10+
11+
static schema = {
12+
name: 'User',
13+
properties: {
14+
_id: 'objectId',
15+
name: 'string',
16+
birthdate: 'date?',
17+
posts: 'Post[]',
18+
},
19+
primaryKey: '_id',
20+
};
21+
}
22+
// :snippet-end:
23+
24+
export default User;

examples/react-native/__tests__/ts/realm-database/schemas/mixed-test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {Text, View} from 'react-native';
33
import {render, waitFor} from '@testing-library/react-native';
44
import Realm from 'realm';
55
import {createRealmContext} from '@realm/react';
6-
import Cat from '../../models/Cat';
6+
import Cat from '../../Models/Cat';
77

88
jest.setTimeout(30000);
99

0 commit comments

Comments
 (0)