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

Many to Many Associations #120

Closed
wyaeld opened this issue Feb 26, 2012 · 38 comments
Closed

Many to Many Associations #120

wyaeld opened this issue Feb 26, 2012 · 38 comments
Labels
🏷️ feat This PR introduces a new feature
Milestone

Comments

@wyaeld
Copy link

wyaeld commented Feb 26, 2012

@wycats since you're cleaning up issues atm, wondering if you can just shed some light on the teams intentions.

We are mid-way through porting an application build with SpineJS over to Ember. Uses a Rails backend with server push to keep everything in sync. We've moved to ActiveModelSerialisers since thats what you seem to be targetting.

However we use ManyToMany (specifically Rails hasManyThrough) and also a couple of polymorphic entities. We could refactor out the polymorphism if we had to, but not the manyToMany.

Is Data intending to support ManyToMany and Polymorphic relationships being created / manipulated client side? If so, any sort of rough idea of how far along the roadmap it would be?

@wycats
Copy link
Member

wycats commented Feb 26, 2012

We definitely want to add support for ManyToMany associations. So far, the plan is to have a memberships model (a la Twitter's friendship model).

The client-side API would probably look a lot like Rails' (friends: DS.hasMany(User, { through: 'friendships' })). Changes in membership (adding or removing an item from the association) would be persisted as POSTs and DELETEs on the friendship association itself.

It's on the roadmap for sure. We know it's needed before the feature-set is considered complete.

@skurfuerst
Copy link

+1, I'd also definitely need such relations :-) I guess I'd have a look on how to implement it. It seems this could be done today by explicitely modelling the many-to-many relationship as one-to-many X many-to-one?

@sly7-7
Copy link
Contributor

sly7-7 commented Sep 13, 2012

@wycats Do you have any idea when this will be implemented ? At least how could we find a workaround ? We are currently totally stucked with ember-data and relationships... I must admit we feel constently uncomfortable with ember-data, and we are doing stinking code each time we want to do some little advanced things.
Are we the only ones to encounter this kind of problems or are we just too bad programmers to play with advnaced ember-data ?

@fxposter
Copy link

fxposter commented Nov 1, 2012

Any news for this?

@wagenet
Copy link
Member

wagenet commented Nov 2, 2012

@fxposter I think this is on the radar for @wycats and @tomdale.

@rickard2
Copy link

rickard2 commented Nov 2, 2012

I'd just like to note that we're also using ember-data and have some many-to-many relationships in our app. Any further info on this issue would be helpful.

@wyaeld
Copy link
Author

wyaeld commented Nov 5, 2012

Just noting I'm still watching this issue.

FYI, we never found a Ember-based workaround we were happy with in my application, so ended up writing our own client-side MVC framework for the specific application... but don't ever do that unless you really have a high tolerance for frustration, and want to understand the hard way how certain design decisions come about.

Once the Ember team has this in I'll happily use their framework in future.

@rickard2
Copy link

My project is closing in on the point where we will have to find a workaround for this issue. Any pointers as to how the thoughts about the future implementation would be helpful so that our workaround would be as close to the final feature as possible.

Things like which HTTP verb is considered, URL structure, stuff like that..

@wagenet
Copy link
Member

wagenet commented Nov 15, 2012

@wycats, what's the status on this?

@ryanjm
Copy link

ryanjm commented Feb 23, 2013

+1

1 similar comment
@darthdeus
Copy link
Member

+1

@willemdewit
Copy link

+1 too...

@sly7-7
Copy link
Contributor

sly7-7 commented Feb 25, 2013

Hum, this has been one month I've no look about ember and ember-data, but I was thinking that since about 2 month this should work using hasMany on each side.

@rudi911
Copy link

rudi911 commented Mar 4, 2013

+1 as this would be an important one for me too.

@seanrucker
Copy link

+1.

We can't wait any longer for this feature, we're going to have to try and find a workaround. Has anyone found any suitable alternatives?

@AshesOfOwls
Copy link

+1

@bobbus
Copy link
Contributor

bobbus commented Mar 26, 2013

As @sly7-7 said Many to Many associations are now working, we just need to use hasMany on each side.
For now, I use a hack in the serializer to make it possible to send an array of the associated ids to the server, I can give more details if someone is interested.

@seanrucker
Copy link

@bobbus I would love details if you don't mind. Thanks!

@dcalhoun
Copy link

@bobbus Definitely interested in details.

@AshesOfOwls
Copy link

@bobbus I am interested as well please.

@anguyen-elc
Copy link

@bobbus Me too

@rickard2
Copy link

My solution to this was to model many to many as another entity with two one to many and lots of manual handling. Not pretty but works OK for now, and they're automatically generated from server side models.

An example would look like this:

User: 
  groups: hasMany Group
  groupsMap: hasMany: UserGroupMap

Group:
  users: hasMany User
  usersMap: hasMany UserGroupMap

UserGroupMap:
  user: belongsTo User
  group: belongsTo Group

@bobbus
Copy link
Contributor

bobbus commented Mar 28, 2013

@seanrucker , @dcalhoun , @mcpants I'm off this week but will give you more details next week.

@AshesOfOwls
Copy link

@bobbus Thanks for the update.

@superlou
Copy link

superlou commented Apr 1, 2013

I think I'm missing something. According to the guide at http://emberjs.com/guides/models/defining-models/, many-to-many is supported, though not polymorphic. It seems to work fine from fixtures, but not on the createRecord method. I've been trying to figure out why the following, where a Task has many Tags and a Tag has many Tasks, doesn't work:

newTask = App.Task.createRecord {
            name: "I'ma task"
            details: "Details for the task"
            tags: [1]  # Known extant Tag ID
            }

Is there a manual work around to handle this, and if that's what @bobbus is talking about, I'd be interested in looking at that solution too.

@igorT
Copy link
Member

igorT commented Apr 6, 2013

@superlou You would pass in an actual record object and not the id in the tags. ManyToMany have been working for a while by having a hasMany on two sides and there is a new commit with some polymorphic support so I am closing this issue. Please open new ones if there are specific bugs you encountered.

@igorT igorT closed this as completed Apr 6, 2013
@pzuraq
Copy link

pzuraq commented Apr 10, 2013

I'm not sure why this has been closed. I'm using hasMany on both sides of my models, but they are not sending any additional info via json. Ember-data doesn't seem to have a way to save two-sided hasMany relationships, which is the cruz of the issue here.

Sure, Ember itself can handle many-to-many associations no problem. But with ember-data it appears as though we have to use intermediate objects which becomes very messy.

@seanrucker
Copy link

@pzuraq I agree. I'm using an intermediate object that represents the join table in the database. It is a very messy solution. There is still work to be done here. For example, what happens when you delete an object on one side of the relationship? The intermediate objects are not automatically deleted and doing it manually will cause multiple calls to the server.

@wyaeld
Copy link
Author

wyaeld commented Apr 10, 2013

I would suggest you guys just write a failing test based on your situation, and raise a separate issue. I don't think this issue has been looked at seriously by the core team in over a year. I've given up on it, and successful projects like Discourse have avoided using Data entirely.

@igorT
Copy link
Member

igorT commented Apr 10, 2013

@pzuraq I think the problem is that the default rest adapter does not send the has_many side of a dirty relationship. Try overwriting the dirtyRecordsForHasMany to add the hasmany side.

@wyaeld I added support for the many-many relationships in January and it is working well for us, so this issue had been one of the priorities on the ember-data roadmap.

@wyaeld
Copy link
Author

wyaeld commented Apr 10, 2013

@igorT Could you add integration tests showing this working. I would expect to see something in https://github.com/emberjs/data/blob/master/packages/ember-data/tests/integration/has_many_test.js, but the discussed structure isn't present.

@igorT
Copy link
Member

igorT commented Apr 10, 2013

@wyaeld
Copy link
Author

wyaeld commented Apr 10, 2013

Fair enough, I was looking in the wrong place. Why is everything but the first test commented out?

Can I suggest when you add a feature, to comment on the relevant issue, since it appears quite a few developers have been waiting on it.

@igorT
Copy link
Member

igorT commented Apr 10, 2013

I need to delete those tests. They are now in other places in the tests/integration/relationships .

Sounds good, we are trying to go through pull requests/issues and close them so they are easier to manage. I was mostly implementing manyToMany because I needed it so I completely missed this issue.

@KeKs0r
Copy link

KeKs0r commented Nov 27, 2013

is there any progress on that? I would really like to see a clean solution for ManyToMany Relationships

@pzuraq
Copy link

pzuraq commented Nov 27, 2013

@KeKs0r On the current Ember-Data beta it's possible to do it by overriding serialize functions. I overrode serializeHasMany() on the ActiveModelSerializer. Note that the code below replaces the default embedded functionality (which may or may not be working, don't remember...) so I wouldn't copy it without first making sure it's right for your use case.

App.Model = DS.Model.extend({
  relations: DS.hasMany('relation', { embedded: 'ids' });
});

App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
  serializeHasMany: function(record, json, relationship) {
    var key   = relationship.key,
        attrs = get(this, 'attrs'),
        embed = relationship.options.embedded == 'ids';

    if (embed) {
      json[this.keyForRelationship(key,'hasMany')] = get(record, key).mapBy(get(this, 'primaryKey'))
    }
  }
});

This isn't as clean as I'd like it, will be working on something better eventually.

@bradleypriest
Copy link
Member

@pzuraq that looks like a great implementation, is there something in particular you'd like to be cleaner about it?
I personally wouldn't include anything so specific directly into the ApplicationSerializer, but it looks pretty simple to me

@pzuraq
Copy link

pzuraq commented Nov 28, 2013

@bradleypriest Thanks! I threw it together without much thought and I wanted to go over it it again. I know I want to implement full record embedding as well, when I get around to that I'll throw it up somewhere.

@runspired runspired added 🏷️ feat This PR introduces a new feature and removed Improvement labels Sep 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ feat This PR introduces a new feature
Projects
None yet
Development

No branches or pull requests