Ember.js and Ember Data, with their convention over configuration mindset, and JSON API make it easy to set up and manage many-to-many relationships between models. At the database and API layers, the set up can be more complex. This becomes apparent when using Ember CLI Mirage.

The key difference between the setup in the Ember models and in Mirage is that Mirage requires an extra join model and a serializer on each of the associated models. To demonstrate, create two models,  Class and Student. This demo assumes you have a working Ember App, have Ember CLI Mirage installed, and have Ember Faker installed (to populate test data using faker.js).

/app/model/class.js

/app/model/student.js

Easy enough. Assuming you load these in your route’s model, you can access the relationships in your templates like this:

Next we need to replicate this data structure in Mirage. Create one extra model ClassStudent, to connect  Class and  Student behind the scenes. The order in the class name does not matter, but I tend to put them in alphabetical order as a convention.

/mirage/models/class-student.js

Now add Mirage versions of the Class and Student models and associate to the ClassStudent model:

/mirage/models/class.js

/mirage/models/student.js

Don’t forget to add the factories and add the endpoints in the Mirage config.

/mirage/factories/class.js

/mirage/factories/student.js

/mirage/config.js

We’re almost finished, but there is one more adjustment to make. When we ask Mirage for class.students, it’s going to give us a list of ClassStudent models by default. We can use a serializer to switch these out with the Student models, and the same to grab the Class models when requesting  student.classes.

/mirage/serializers/class.js

/mirage/serializers/student.js

This completes the Mirage data structure, now it is time to populate some sample data. The factories will take care of filling in the names, but the code below will create 2 classes and 5 students. It will then semi-randomly associate some of the classes with students.

/mirage/scenarios/default.js

That’s it!

Code: https://github.com/ricog/ember-cli-mirage-many-to-many-demo
Demo: http://mirage-many-to-many.surge.sh/

Thanks to https://github.com/samselikoff/ember-cli-mirage/issues/606 for clues on how to implement a many-to-many relationship in Ember CLI Mirage. The discussion also contains a hint of a future  has_and_belongs_to_many feature to make implementation a lot easier.