diff --git a/README.md b/README.md index 39c1ade6..012b3782 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,18 @@ end BlogSerializer.new(object, key_format: :lower_camel) ``` +## Changing the default association key type + +You can specify that serializers use unsuffixed names as association keys by default. + +`````ruby +ActiveModel::Serializer.setup do |config| + config.default_key_type = :name +end +```` + +This will build association keys like `comments` or `author` instead of `comment_ids` or `author_id`. + ## Getting the old version If you find that your project is already relying on the old rails to_json diff --git a/lib/active_model/serializer/association/has_many.rb b/lib/active_model/serializer/association/has_many.rb index d1b8d8eb..52d66d26 100644 --- a/lib/active_model/serializer/association/has_many.rb +++ b/lib/active_model/serializer/association/has_many.rb @@ -5,7 +5,11 @@ module ActiveModel def initialize(name, *args) super @root_key = @embedded_key - @key ||= "#{name.to_s.singularize}_ids" + @key ||= case CONFIG.default_key_type + when :name then name.to_s.pluralize + else "#{name.to_s.singularize}_ids" + end + end def serializer_class(object, _) diff --git a/lib/active_model/serializer/association/has_one.rb b/lib/active_model/serializer/association/has_one.rb index 3b9acddf..38c8b9bc 100644 --- a/lib/active_model/serializer/association/has_one.rb +++ b/lib/active_model/serializer/association/has_one.rb @@ -5,7 +5,10 @@ module ActiveModel def initialize(name, *args) super @root_key = @embedded_key.to_s.pluralize - @key ||= "#{name}_id" + @key ||= case CONFIG.default_key_type + when :name then name.to_s.singularize + else "#{name}_id" + end end def serializer_class(object, options = {}) diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index fae44cb3..410481fd 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -148,3 +148,25 @@ module TestNamespace class ProfileSerializer < ::ProfileSerializer; end class UserSerializer < ::UserSerializer; end end + +ActiveModel::Serializer.setup do |config| + config.default_key_type = :name +end + +class NameKeyUserSerializer < ActiveModel::Serializer + attributes :name, :email + + has_one :profile +end + +class NameKeyPostSerializer < ActiveModel::Serializer + attributes :title, :body + + has_many :comments +end + +ActiveModel::Serializer.setup do |config| + config.default_key_type = nil +end + + diff --git a/test/unit/active_model/serializer/has_many_test.rb b/test/unit/active_model/serializer/has_many_test.rb index 2e5d212f..f8b2c738 100644 --- a/test/unit/active_model/serializer/has_many_test.rb +++ b/test/unit/active_model/serializer/has_many_test.rb @@ -242,6 +242,24 @@ module ActiveModel } }, @post_serializer.as_json) end + + def test_associations_name_key_embedding_ids_serialization_using_serializable_hash + @association = NameKeyPostSerializer._associations[:comments] + @association.embed = :ids + + assert_equal({ + title: 'Title 1', body: 'Body 1', 'comments' => @post.comments.map { |c| c.object_id } + }, NameKeyPostSerializer.new(@post).serializable_hash) + end + + def test_associations_name_key_embedding_ids_serialization_using_as_json + @association = NameKeyPostSerializer._associations[:comments] + @association.embed = :ids + + assert_equal({ + 'name_key_post' => { title: 'Title 1', body: 'Body 1', 'comments' => @post.comments.map { |c| c.object_id } } + }, NameKeyPostSerializer.new(@post).as_json) + end end end end diff --git a/test/unit/active_model/serializer/has_one_test.rb b/test/unit/active_model/serializer/has_one_test.rb index 52fac88d..9f7e393c 100644 --- a/test/unit/active_model/serializer/has_one_test.rb +++ b/test/unit/active_model/serializer/has_one_test.rb @@ -216,6 +216,24 @@ module ActiveModel } }, @user_serializer.as_json) end + + def test_associations_name_key_embedding_ids_serialization_using_serializable_hash + @association = NameKeyUserSerializer._associations[:profile] + @association.embed = :ids + + assert_equal({ + name: 'Name 1', email: 'mail@server.com', 'profile' => @user.profile.object_id + }, NameKeyUserSerializer.new(@user).serializable_hash) + end + + def test_associations_name_key_embedding_ids_serialization_using_as_json + @association = NameKeyUserSerializer._associations[:profile] + @association.embed = :ids + + assert_equal({ + 'name_key_user' => { name: 'Name 1', email: 'mail@server.com', 'profile' => @user.profile.object_id } + }, NameKeyUserSerializer.new(@user).as_json) + end end end end