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

hasMany associations #14

Closed
hjdivad opened this issue Aug 8, 2014 · 8 comments
Closed

hasMany associations #14

hjdivad opened this issue Aug 8, 2014 · 8 comments

Comments

@hjdivad
Copy link

hjdivad commented Aug 8, 2014

I would have expected the following to work for hasMany associations:

FactoryGuy.define('province');
FactoryGuy.define('country', {
  'default': {
    provinces: {}
  }
});

Checking the implementation it looks like this feature is simply not supported. Is that right?

@hjdivad
Copy link
Author

hjdivad commented Aug 8, 2014

okay n/m i see that i'm supposed to do this with attributes whose values are functions.

@hjdivad hjdivad closed this as completed Aug 8, 2014
@swatijadhav
Copy link

Hi @hjdivad ,

I also want to implement hasMany association, in the same way as you have specified in example.

How to achieve it? Can you please provide me an example for it?

Thanks.

@shivanibhanwal
Copy link

Hi @hjdivad
I have implemented hasMany associations as follows:

 user_with_many_address: {
    name: FactoryGuy.generate("user_name"),
    addresses: FactoryGuy.buildList('address',6)
    }

Have you implemented it same way ?

Hi @danielspaniel - could you please also suggest if this is the right approach or not?

@danielspaniel Thank you for the awesome work!

@hjdivad
Copy link
Author

hjdivad commented Aug 14, 2014

The following works for me:

Duchy = DS.extend({
  kingdom: belongsTo('kingdom')
});

Kingdom = DS.extend({
  duchies: DS.hasMany('duchy')
});


FactoryGuy.define('duchy', { /*... */ });
FactoryGuy.define('kingdom', {
  'default': {
    duchies: function () {
      return FactoryGuy.buildList('duchy', 2);
    }
  }
});

FactoryGuy.build("kingdom")
// => "{"duchies":[{"id":4},{"id":5}],"id":2}"

But it's worth keeping in mind that I use factory guy only to mock API responses (using pretender): I don't try to load factoried models into the store directly.

@shivanibhanwal
Copy link

Thank you @hjdivad !

We also have similar situation we want to mock the APIs as we have separate REST API server.
I am also looking for the best solution on the similar lines. I am using mockjax. However i was also going through the Pretender.

If you have any suggestions then please do share.

Thanks
Shivani

@danielspaniel
Copy link
Collaborator

Hi Guys, I am on internet free vacation for another few days .. will get back to you on Monday ..

@hjdivad
Copy link
Author

hjdivad commented Aug 17, 2014

@shivanibhanwal I'm writing acceptance tests roughly like this

import Ember from 'ember';
import startApp from '../helpers/start-app';

var App, server;

module('Acceptance: Kingdoms', {
  setup: function () {
    App = startApp();
    server = new Pretender();
  },
  teardown: function () {
    server.shutdown();
    Ember.run(App, 'destroy');
  },
});

test('/kingdoms loads some kingdoms and their duchies', function () {
  server.get('/kingdoms', function () {
    var content = {
      kingdoms: FactoryGuy.buildList('kingdom', 2);
    }
    return [200, {}, JSON.stringify(content)];
  });

visit('/kingdoms');

andThen( /* do some assertions */ );
});

@danielspaniel
Copy link
Collaborator

@hjdivad and @swatijadhav .. thanks for the interesting ideas. I actually never thought that hasMany associations would work, but you did a simple test .. and voila .. kind of surprised me.

So, what I did was to change the FactoryGuy#assocation method to FactoryGuy#belongsTo and added a FactoryGuy#hasMay method for creating the hasMany association.

There are 2 ways to use this:

FactoryGuy.define('user', {
  user_with_projects: {
    projects: FactoryGuy.hasMany('project', 2)
  },
  traits: {
    with_projects: {
      projects: FactoryGuy.hasMany('project', 2)
    }
  }
})

traits are a nice thing to use since you then can add the projects or not when ever you want and you don't have to make a 'user_with_projects' definition,
since all you have to do is to say:

 // for this to work you have to have defined that trait ( 'with_projects' ) 
 FactoryGuy.build('user', 'with_projects'); 

So those are your two options.

As to using pretender. I am thinking that you don't need to use that at all, since this project uses mockjax and this project has a special test helper mixin called
FactoryGuyTestHelperMixin that has some methods that do the same thing
as you will get from pretender but with less effort ( ie, just a one liner )

for example, instead of what you are doing:

 server.get('/kingdoms', function () {
    var content = {
      kingdoms: FactoryGuy.buildList('kingdom', 2);
    }
    return [200, {}, JSON.stringify(content)];
  });

you could just do:

var kingdoms = FactoryGuy.buildList('kingdom',2);
this.stubEndpointForHttpRequest('/kingdoms', {kingdoms: [kingdoms]}

ok .. so its a two liner .. but this case is one where you are getting all kingdoms.
if you wanted to find just one kingdom .. then you could use the handleFind method, and it would be even easier.

If you have any questions about this .. let me know .. and I will try and point you to more ideas, and or fix up the README alittle more ( traits are not on there yet )

The FacoryGuy.hasMany method is available in version 0.6.0

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

4 participants