3

I'm wondering why I have to define hasMany and belongsTo in two related data sets? It seems redundant as all necessary information is in one of the arrays already and it is difficult to keep both synchronized.

It also doesn't reflect the tables in an sql database where there is only one foreign key in one table in an one-to-many relationship.

modusCell
  • 13,151
  • 9
  • 53
  • 80
TwoPi
  • 31
  • 2

1 Answers1

3

Because relationships can go one or two ways. In your SQL example, a foreign key in one table only places a restraint on that table, NOT the table to which the foreign key belongs. In a sense, this is only a one way relationship. Rows from the first table must be linked to rows of the second, but not vice-versa. If you want to emulate that behavior, you should use a null inverse, like so:

App.User = DS.Model.extend({
    posts: DS.hasMany('post', { inverse: null });
});

App.Post = DS.Model.extend({
    // No inverse relationship required
});

Having a two way relationship is different though. To stretch your SQL comparison, that would like having two foreign keys, one in each table. Rows of table A must point to rows of table B and rows of table B must point to rows of table A.

But SQL really is a bad comparison here. You're letting your data store implementation leak through to your data model if you're worried about that mismatch. Instead, you should think about Ember-Data models as graphs. Specifically, directed graphs. Once you understand directed graphs, and how to traverse them, you'll understand why most people use two-sided relationships. (Although, as I showed you above, you don't have to.)

GJK
  • 37,023
  • 8
  • 55
  • 74
  • Am I getting it right, that in a two way relationship if row 1 of table A is linked to row 3 in table B, row 3 in B must be linked to row 1 in A. If that is the case, isn't that pure redundancy? – TwoPi Aug 11 '14 at 13:11
  • It's a bit redundant in SQL because of the way foreign key constraints and queries work, but it's not redundant for graphs. Being able to traverse both way is important. In my example above, the `Post` model _knows nothing_ about the `User` model. That means that if you have a `Post` object, you can't get the author of the post unless you query the `User` objects. But if there's another relationship pointing back to the `User` object, you can now traverse the graph in that direction as well. – GJK Aug 11 '14 at 13:16