javascriptember-cli-miragemiragemiragejs

How to seed models with polymorphic one to one relationship in mirage js?


this is just an example, I understand that you would normally have multiple comments, but for the sake of this example, lets assume that we have

following models:

 models: {
    blogPost: Model.extend({
      comment: belongsTo(),
    }),

    picture: Model.extend({
      comment: belongsTo(),
    }),

    comment: Model.extend({
      commentable: belongsTo({ polymorphic: true }),
    }),
  },

and following factories:

  factories: {
    blogPost: Factory.extend({
      title: "Whatever",
      withComment: trait({
        comment: association(),
      }),
  }),

Now when trying to seed server with:

seeds(server) {
  server.create("blogPost", "withComment");
}

It does seed it but when checking console.log(server.db.dump()); the commentable is null... commentableId: null.

enter image description here

Why?

EDIT:

This is a tricky one. I changed

comment: Model.extend({
  commentable: belongsTo({ polymorphic: true }),
}),

to:

comment: Model.extend({
  blogPost: belongsTo({ polymorphic: true }),
}),

just to see if commentable part is causing the issue. This time I got a different error: Mirage: You're using the association() helper on your comment factory for blogPost, which is a polymorphic relationship. This is not currently supported."

So, it is currently not possible to use association() on polymorphic relationship. I wish this was announced in documentation...

Still, I cannot find a way to seed it even without shorthand association().


Solution

  • Here's one way to do it:

    import { Server, Model, Factory, belongsTo, trait, association, RestSerializer } from "miragejs"
    
    export default new Server({
      serializers: {
        blogPost: RestSerializer.extend({
          include: ['comment']
        }),
      },
    
      models: {
        blogPost: Model.extend({
          comment: belongsTo(),
        }),
    
        picture: Model.extend({
          comment: belongsTo(),
        }),
    
        comment: Model.extend({
          commentable: belongsTo({ polymorphic: true }),
        }),
      },
      
      factories: {
        blogPost: Factory.extend({
          title: "Whatever",
          withComment: trait({
            afterCreate(blogPost, server) {
              server.create('comment', {
                commentable: blogPost
              });
            }
          }),
        })
      },
    
      seeds(server) {
        server.create("blog-post", "withComment");
        console.log(server.db.dump())
      },
      
      routes() {
        this.resource('blog-post')
      }
    
    })
    

    And here's the working REPL: http://miragejs.com/repl/v1/144

    If you click the Database tab then click Comments, you should see the polymorphic ID referencing blog-post:1.

    You can also send a GET to /blog-posts and you should see that the comment is included, or send a GET to /comments and see the polymorphic commentable included.