Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change ember data model attributes & relationships to camel case in Mirage models #2208

Open
cristinawithout opened this issue Jun 30, 2021 · 4 comments

Comments

@cristinawithout
Copy link

cristinawithout commented Jun 30, 2021

I'm looking for a solution to be able to add mirage to an existing application that has dozens of Ember Data models. It works perfectly fine on GET requests, but for POST & PATCH requests, it returns a 500 error when there is a relationship because the models have snake_cased_relationships.

Additional details are on the miragejs issue miragejs/miragejs#890

The short version is that miragejs forces camelize on the relationshipName but the Mirage model has snake cased name.
Code that does that is here:
https://github.com/miragejs/miragejs/blob/b965b8a058523dac0d6ab4792826887154e25368/lib/route-handlers/base.js#L76

Everything about Ember Data and Mirage works just fine with snake case except for this.

Since Mirage expects camel case, is there a way to have ember-cli-mirage create Mirage models with camel cased relationships/attributes when the Ember Data models are not camel case? Or a way I can override the modelClass.associationFor() method?

@cristinawithout
Copy link
Author

cristinawithout commented Jun 30, 2021

Adding this to scenarios/default.js makes it work, but it's really ugly. I'd greatly prefer a cleaner solution that also doesn't involve redefining over 2 dozen Ember Data models as Mirage models.

 Object.keys(server.schema).forEach(key => {
    let modelName = server.schema[key].camelizedModelName;
    if (modelName) {
      let model = server.schema.modelClassFor(modelName);
      if (model) {
        model.associationFor = function(key) {
          let association = this.associations[key];
          if (!association) {
            key = underscore(key);
            association = this.associations[key];
          }
          return association;
        };
      }
    }
  });

@cristinawithout
Copy link
Author

I found the server configuration docs. https://www.ember-cli-mirage.com/docs/advanced/server-configuration

If I copy discoverEmberDataModels from add/ember-data.js and change lines 79 & 81 to use attr[camelize(name)], it all works.

attrs[name] = belongsTo(r.type, r.options);

attrs[name] = hasMany(r.type, r.options);

I'd rather not have to copy & modify code from the addon, but this looks like the best option I have unless ember-cli-mirage can add camelize() to the Mirage model attributes.

import { createServer, Model, belongsTo, hasMany } from 'ember-cli-mirage';
import { getDsModels } from 'ember-cli-mirage/ember-data';
import { camelize } from '@ember/string';

function customDiscoverEmberDataModels() {
  let emberDataModels = getDsModels();
  let Models = {};

  Object.keys(emberDataModels).forEach(modelName => {
    let model = emberDataModels[modelName];
    let attrs = {};

    model.eachRelationship((name, r) => {
      if (r.kind === 'belongsTo') {
        attrs[camelize(name)] = belongsTo(r.type, r.options);
      } else if (r.kind === 'hasMany') {
        attrs[camelize(name)] = hasMany(r.type, r.options);
      }
    });

    Models[modelName] = Model.extend(attrs);
  });

  return Models;
}

export function makeServer(config) {
  let finalConfig = {
    ...config,
    models: { ...customDiscoverEmberDataModels(), ...config.models },
    routes,
  };

  return createServer(finalConfig);
}


function routes() {
...
}

@cah-brian-gantzler
Copy link
Collaborator

If changing those two lines fixes the problem, please submit a PR with that change.Possibly create another model in the dummy app to test with that has the snake case demonstrating that it works

@cristinawithout
Copy link
Author

Thanks. I likely won't have the bandwidth to do a PR for quite awhile, but if anyone else has similar needs and would like to, feel free.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants