Skip to content

Commit

Permalink
Partially fix extra db hit with belongs_to.
Browse files Browse the repository at this point in the history
  • Loading branch information
beauby committed Sep 8, 2015
1 parent c03427d commit 41ed97c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 13 deletions.
39 changes: 31 additions & 8 deletions lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ def resource_identifier_type_for(serializer)
end
end

def resource_identifier_type_for_belongs_to(parent_object, association_key)
type = parent_object.class.reflections[association_key].class_name
if ActiveModel::Serializer.config.jsonapi_resource_type == :singular
type = type.singularize
else
type = type.pluralize
end
type.underscore
end

def resource_identifier_id_for(serializer)
if serializer.respond_to?(:id)
serializer.id
Expand All @@ -70,13 +80,24 @@ def resource_identifier_id_for(serializer)
end
end

def resource_identifier_id_for_belongs_to(parent_object, association_key)
parent_object.send("#{association_key}_id")
end

def resource_identifier_for(serializer)
type = resource_identifier_type_for(serializer)
id = resource_identifier_id_for(serializer)

{ id: id.to_s, type: type }
end

def resource_identifier_for_belongs_to(parent_object, association_key)
type = resource_identifier_type_for_belongs_to(parent_object, association_key)
id = resource_identifier_id_for_belongs_to(parent_object, association_key)

{ id: id.to_s, type: type } unless id.nil?
end

def resource_object_for(serializer, options = {})
options[:fields] = @fieldset && @fieldset.fields_for(serializer)

Expand All @@ -96,20 +117,22 @@ def primary_data_for(serializer, options)
end
end

def relationship_value_for(serializer, options = {})
if serializer.respond_to?(:each)
serializer.map { |s| resource_identifier_for(s) }
def relationship_value_for(parent_object, association)
if association.serializer.respond_to?(:each)
association.serializer.map { |serializer| resource_identifier_for(serializer) }
else
if options[:virtual_value]
options[:virtual_value]
elsif serializer && serializer.object
resource_identifier_for(serializer)
if association.options[:virtual_value]
association.options[:virtual_value]
elsif parent_object.class.respond_to?(:reflections) && parent_object.class.reflections[association.key.to_s].belongs_to?
resource_identifier_for_belongs_to(parent_object, association.key.to_s)
elsif association.serializer && association.serializer.object
resource_identifier_for(association.serializer)
end
end
end

def relationships_for(serializer)
Hash[serializer.associations.map { |association| [association.key, { data: relationship_value_for(association.serializer, association.options) }] }]
Hash[serializer.associations.map { |association| [association.key, { data: relationship_value_for(serializer.object, association) }] }]
end

def included_for(serializer)
Expand Down
21 changes: 21 additions & 0 deletions test/adapter/json_api/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,27 @@ def test_include_linked_resources_with_type_name
]
assert_equal expected, linked
end

def test_ar_belongs_to_doesnt_load_record
author = ARModels::User.create(name: 'Name 1')
post = ARModels::Post.create(author_id: author.id)

class << post
def author
fail "should use author_id"
end
end

hash = ActiveModel::SerializableResource.new(post, adapter: :json_api).serializable_hash
assert_equal({ data: { id: author.id.to_s, type: 'users' } }, hash[:data][:relationships][:author])
end

def test_ar_belongs_to_empty
post = ARModels::Post.create

hash = ActiveModel::SerializableResource.new(post, adapter: :json_api).serializable_hash
assert_equal({ data: nil }, hash[:data][:relationships][:author])
end
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions test/fixtures/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
t.references :author
t.timestamps null: false
end
create_table :authors, force: true do |t|
create_table :users, force: true do |t|
t.string :name
t.timestamps null: false
end
Expand All @@ -23,15 +23,15 @@
module ARModels
class Post < ActiveRecord::Base
has_many :comments
belongs_to :author
belongs_to :author, class_name: 'User'
end

class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :author
belongs_to :author, class_name: 'User'
end

class Author < ActiveRecord::Base
class User < ActiveRecord::Base
has_many :posts
end

Expand All @@ -49,7 +49,7 @@ class CommentSerializer < ActiveModel::Serializer
belongs_to :author
end

class AuthorSerializer < ActiveModel::Serializer
class UserSerializer < ActiveModel::Serializer
attributes :id, :name

has_many :posts
Expand Down

0 comments on commit 41ed97c

Please sign in to comment.