Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Update foreign key naming conventions - fixes #158 #169

Merged
merged 1 commit into from

4 participants

@dgeb

This pull request addresses the issues raised by @tchak in #158:

  • It appends an _id (or _ids) suffix to associations' keys when embedding ids. This brings AMS more in line with API conventions and the expectations of Ember Data. The name of the key can still be overridden with the key option.

  • When objects are embedded in the root, they are now named according to their serializer, instead of the key used for their associations. This can still be overridden with the root option.

Note: This PR will bring Ember Data closer to working out-of-the-box with AMS. However, Ember Data will still need to be updated to recognize the _ids suffix for HasMany associations.

@steveklabnik
Owner

/cc @wycats

@tchak

Shouldn't it be optional?

@ahawkins

This could be set if objects aren't embedded.

@dgeb

@twinturbo The _id / _ids suffixes are only appended to keys when embedding ids, not objects.

For example, when embedding ids, keys such as author_id and comment_ids will be used:

{
  "post": {
    "id": 1,
    "title": "New post",
    "body": "A body!",
    "author_id": 123,
    "comment_ids": [ 1, 2 ]
  },
  "comments": [
    { "id": 1, "body": "what a dumb post" },
    { "id": 2, "body": "i liked it" },
  ],
  "authors": [
    { "id": 123, "name": "Joseph Blow" },  
  ]
}

When embedding objects directly, keys such as author and comments will still be used:

{
  "post": {
    "id": 1,
    "title": "New post",
    "body": "A body!",
    "author": { "id": 123, "name": "Joseph Blow" },
    "comments": [
      { "id": 1, "body": "what a dumb post" },
      { "id": 2, "body": "i liked it" },
    ]
  }
}

I think these are more conventional and understandable defaults.

@ahawkins
@dgeb dgeb Append an `_id` or `_ids` suffix to associations' keys. Embed objects…
… in root according to their serializers' names.

An `_id` suffix will be appended to the name of HasOne associations, while `_ids` will be appended to the singularized name of HasMany associations. Association keys can still be overridden with the `key` option.

Furthermore, objects embedded in the root are now by default named according to their serializer, instead of the key used for their associations.
3b1d2fa
@steveklabnik steveklabnik merged commit 7f87c9b into rails-api:master

1 check passed

Details default The Travis build passed
@steveklabnik

Hey, sorry this took me so long to merge. Looks good. :shipit: :heart:

@dgeb

@steveklabnik thanks much!

Now I'll get to work on a PR for ember-data so that the _ids suffix is recognized by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 21, 2012
  1. @dgeb

    Append an `_id` or `_ids` suffix to associations' keys. Embed objects…

    dgeb authored
    … in root according to their serializers' names.
    
    An `_id` suffix will be appended to the name of HasOne associations, while `_ids` will be appended to the singularized name of HasMany associations. Association keys can still be overridden with the `key` option.
    
    Furthermore, objects embedded in the root are now by default named according to their serializer, instead of the key used for their associations.
This page is out of date. Refresh to see the latest.
View
10 README.md
@@ -386,7 +386,7 @@ Now, any associations will be supplied as an Array of IDs:
"id": 1,
"title": "New post",
"body": "A body!",
- "comments": [ 1, 2, 3 ]
+ "comment_ids": [ 1, 2, 3 ]
}
}
```
@@ -413,7 +413,7 @@ The JSON will look like this:
"comments": [
{ "id": 1, "body": "what a dumb post" }
],
- "tags": [ 1, 2, 3 ]
+ "tag_ids": [ 1, 2, 3 ]
}
}
```
@@ -444,11 +444,11 @@ this:
"id": 1,
"title": "New post",
"body": "A body!",
- "comments": [ 1, 2 ]
+ "comment_ids": [ 1, 2 ]
},
"comments": [
- { "id": 1, "body": "what a dumb post", "tags": [ 1, 2 ] },
- { "id": 2, "body": "i liked it", "tags": [ 1, 3 ] },
+ { "id": 1, "body": "what a dumb post", "tag_ids": [ 1, 2 ] },
+ { "id": 2, "body": "i liked it", "tag_ids": [ 1, 3 ] },
],
"tags": [
{ "id": 1, "name": "short" },
View
36 lib/active_model/serializer/associations.rb
@@ -51,7 +51,7 @@ def key
end
def root
- option(:root) || plural_key
+ option(:root) || @name
end
def name
@@ -92,7 +92,15 @@ def find_serializable(object)
end
class HasMany < Config #:nodoc:
- alias plural_key key
+ def key
+ if key = option(:key)
+ key
+ elsif embed_ids?
+ "#{@name.to_s.singularize}_ids".to_sym
+ else
+ @name
+ end
+ end
def serialize
associated_object.map do |item|
@@ -132,18 +140,30 @@ def polymorphic?
option :polymorphic
end
- def polymorphic_key
- associated_object.class.to_s.demodulize.underscore.to_sym
+ def root
+ if root = option(:root)
+ root
+ elsif polymorphic?
+ associated_object.class.to_s.pluralize.demodulize.underscore.to_sym
+ else
+ @name.to_s.pluralize.to_sym
+ end
end
- def plural_key
- if polymorphic?
- associated_object.class.to_s.pluralize.demodulize.underscore.to_sym
+ def key
+ if key = option(:key)
+ key
+ elsif embed_ids? && !polymorphic?
+ "#{@name}_id".to_sym
else
- key.to_s.pluralize.to_sym
+ @name
end
end
+ def polymorphic_key
+ associated_object.class.to_s.demodulize.underscore.to_sym
+ end
+
def serialize
object = associated_object
View
34 test/association_test.rb
@@ -70,7 +70,7 @@ def test_include_bang_has_many_associations
include! :comments, :value => @post.comments
assert_equal({
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}, @hash)
assert_equal({
@@ -91,7 +91,7 @@ def test_include_bang_with_embed_ids_include_false
include! :comments, :value => @post.comments, :embed => :ids, :include => false
assert_equal({
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}, @hash)
assert_equal({}, @root_hash)
@@ -101,7 +101,7 @@ def test_include_bang_has_one_associations
include! :comment, :value => @post.comment
assert_equal({
- :comment => 1
+ :comment_id => 1
}, @hash)
assert_equal({
@@ -119,7 +119,7 @@ def test_with_default_has_many
include! :comments
assert_equal({
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}, @hash)
assert_equal({
@@ -137,7 +137,7 @@ def test_with_default_has_one
include! :comment
assert_equal({
- :comment => 1
+ :comment_id => 1
}, @hash)
assert_equal({
@@ -159,7 +159,7 @@ def test_with_default_has_many_with_custom_key
}, @hash)
assert_equal({
- :custom_comments => [
+ :comments => [
{ :id => 1, :body => "ZOMG A COMMENT" }
]
}, @root_hash)
@@ -167,17 +167,17 @@ def test_with_default_has_many_with_custom_key
def test_with_default_has_one_with_custom_key
@post_serializer_class.class_eval do
- has_one :comment, :key => :custom_comment
+ has_one :comment, :key => :custom_comment_id
end
include! :comment
assert_equal({
- :custom_comment => 1
+ :custom_comment_id => 1
}, @hash)
assert_equal({
- :custom_comments => [
+ :comments => [
{ :id => 1, :body => "ZOMG A COMMENT" }
]
}, @root_hash)
@@ -207,7 +207,7 @@ def test_embed_ids_for_has_many_associations
include_bare! :comments
assert_equal({
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}, @hash)
assert_equal({}, @root_hash)
@@ -232,7 +232,7 @@ def test_embed_ids_include_true_for_has_many_associations
include_bare! :comments
assert_equal({
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}, @hash)
assert_equal({
@@ -250,7 +250,7 @@ def test_embed_ids_for_has_one_associations
include_bare! :comment
assert_equal({
- :comment => 1
+ :comment_id => 1
}, @hash)
assert_equal({}, @root_hash)
@@ -275,7 +275,7 @@ def test_embed_ids_include_true_for_has_one_associations
include_bare! :comment
assert_equal({
- :comment => 1
+ :comment_id => 1
}, @hash)
assert_equal({
@@ -333,7 +333,7 @@ def test_when_it_is_included
:post => {
:title => "New Post",
:body => "Body",
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
},
:comments => [
{ :id => 1, :body => "ZOMG A COMMENT" }
@@ -352,7 +352,7 @@ def test_when_it_is_not_included
:post => {
:title => "New Post",
:body => "Body",
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}
}, json)
end
@@ -368,7 +368,7 @@ def test_when_it_is_excluded
:post => {
:title => "New Post",
:body => "Body",
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
}
}, json)
end
@@ -384,7 +384,7 @@ def test_when_it_is_not_excluded
:post => {
:title => "New Post",
:body => "Body",
- :comments => [ 1 ]
+ :comment_ids => [ 1 ]
},
:comments => [
{ :id => 1, :body => "ZOMG A COMMENT" }
View
20 test/serializer_test.rb
@@ -281,8 +281,8 @@ def test_embed_ids
:post => {
:title => "New Post",
:body => "Body of new post",
- :comments => [1, 2],
- :author => nil
+ :comment_ids => [1, 2],
+ :author_id => nil
}
}, serializer.as_json)
end
@@ -305,8 +305,8 @@ def test_embed_ids_include_true
:post => {
:title => "New Post",
:body => "Body of new post",
- :comments => [1, 2],
- :author => nil
+ :comment_ids => [1, 2],
+ :author_id => nil
},
:comments => [
{ :title => "Comment1" },
@@ -323,8 +323,8 @@ def test_embed_ids_include_true
:post => {
:title => "New Post",
:body => "Body of new post",
- :comments => [1, 2],
- :author => 1
+ :comment_ids => [1, 2],
+ :author_id => 1
},
:comments => [
{ :title => "Comment1" },
@@ -558,7 +558,7 @@ def test_embed_id_for_has_one
:post => {
:title => "New Post",
:body => "It's a new post!",
- :author => 5
+ :author_id => 5
}
}, hash.as_json)
end
@@ -776,12 +776,12 @@ def test_embed_with_include_inserts_at_root
actual = ActiveModel::ArraySerializer.new([post], :root => :posts).as_json
assert_equal({
:posts => [
- { :title => "New Post", :body => "NEW POST", :id => 1, :comments => [1,2] }
+ { :title => "New Post", :body => "NEW POST", :id => 1, :comment_ids => [1,2] }
],
:comments => [
- { :body => "EWOT", :id => 1, :tags => [1,3] },
- { :body => "YARLY", :id => 2, :tags => [1,2] }
+ { :body => "EWOT", :id => 1, :tag_ids => [1,3] },
+ { :body => "YARLY", :id => 2, :tag_ids => [1,2] }
],
:tags => [
Something went wrong with that request. Please try again.