This question has been asked twice before in on SO:
- https://stackguides.com/questions/10244753/extjs-many-to-many-association-how
- Extjs 4.1 many-to-many model association
BUT neither of these questions have an actual answer, so I'm going to try again!
Let's say I have two models, User
and Group
. A user can be in many groups, and groups can contain many users. Here's the model code for User
:
Ext.define('User', {
extend: 'Ext.data.Model',
alias: 'model.User',
fields: [
{name: 'username', type: 'string'},
...
],
proxy: {
// Omitted for brevity...
},
});
And Group
:
Ext.define('Group', {
extend: 'Ext.data.Model',
alias: 'model.Group',
fields: [
{name: 'name', type: 'string'},
...
],
proxy: {
// Omitted for brevity...
},
});
Now, let's say I wanted a Grid which lists my groups, and allows me to double-click a group and edit which users are in that group in second grid.
Let's also say there's a lot of users per group, so I don't want to load all the associated users when I load the groups.
I want to be able get a store of users for a particular group, and give that to my grid, which will load data as needed (using the usual pagination that a grid does).
I see two potential approaches here. There may another better way, but I will outline what I've tried do so far below.
Intermediate model
- Add another joining model
- Add
hasMany
associations fromUser
andGroup
to that model - Add
belongsTo
associations from my joining model back the way toUser
andGroup
.
Joining model code:
Ext.define('GroupUsers', {
extend: 'Ext.data.Model',
alias: 'model.GroupUsers',
fields: [
{name: 'group_id', type: 'int'},
{name: 'user_id', type: 'int'},
],
associations: [
{type: 'belongsTo', model: 'User'},
{type: 'belongsTo', model: 'Group'}
],
...
});
Association in Group
:
associations: [
{type: 'hasMany', model: 'GroupUsers', name: 'group_users'}
],
I will now be able to access a store of GroupUsers
for a particular Group
:
group.group_users()
The problem with this approach, is that I can't just bind a store of GroupUsers
to my second grid, because I want to display things like the user's name. I could iterate the store's items, fetch each User
object with getUser()
, add them to another store, and use that for my Grid, but that results in a server request per item! Alternatively, I could use my store of GroupUsers
directly, but then would need to do something with renderers and I still need to fetch each User
individually.
Direct association
- Associate
User
andGroup
directly with ahasMany
association on each
Associations on Group
:
associations: [
{type: 'hasMany', model: 'User', name: 'users', foreignKey: '???'}
],
I can now get a store of actual User
objects for a given group:
group.users()
Which would be great, except there's nothing for me to set the foreignKey
of the association to. User
can't have a group_id
field, because a User
can have many Group
s!