Skip to content

Commit 9c65983

Browse files
committed
Evaluate ids via the specified ‘id_method_name’ when relationships are evaluated via a block
1 parent 5ff3fa9 commit 9c65983

4 files changed

Lines changed: 40 additions & 9 deletions

File tree

lib/fast_jsonapi/object_serializer.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,15 @@ def create_relationship(base_key, relationship_type, options, block)
240240
relationship_type: relationship_type,
241241
cached: options[:cached],
242242
polymorphic: fetch_polymorphic_option(options),
243-
conditional_proc: options[:if]
243+
conditional_proc: options[:if],
244+
id_method_name_for_inferred_objects: compute_object_method_name_for_inferred_objects(options[:id_method_name], block)
244245
)
245246
end
246247

248+
def compute_object_method_name_for_inferred_objects(id_method_name, block)
249+
(id_method_name.present? && block.present?) ? id_method_name : :id
250+
end
251+
247252
def compute_serializer_name(serializer_key)
248253
return serializer_key unless serializer_key.is_a? Symbol
249254
namespace = self.name.gsub(/()?\w+Serializer$/, '')

lib/fast_jsonapi/relationship.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module FastJsonapi
22
class Relationship
3-
attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc
3+
attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :id_method_name_for_inferred_objects
44

55
def initialize(
66
key:,
@@ -13,7 +13,8 @@ def initialize(
1313
relationship_type:,
1414
cached: false,
1515
polymorphic:,
16-
conditional_proc:
16+
conditional_proc:,
17+
id_method_name_for_inferred_objects:
1718
)
1819
@key = key
1920
@name = name
@@ -26,6 +27,7 @@ def initialize(
2627
@cached = cached
2728
@polymorphic = polymorphic
2829
@conditional_proc = conditional_proc
30+
@id_method_name_for_inferred_objects = id_method_name_for_inferred_objects
2931
end
3032

3133
def serialize(record, serialization_params, output_hash)
@@ -86,13 +88,11 @@ def id_hash(id, record_type, default_return=false)
8688
end
8789

8890
def fetch_id(record, params)
89-
unless object_block.nil?
91+
if object_block.present?
9092
object = object_block.call(record, params)
91-
92-
return object.map(&:id) if object.respond_to? :map
93-
return object.try(:id)
93+
return object.map { |item| item.public_send(id_method_name_for_inferred_objects) } if object.respond_to? :map
94+
return object.try(id_method_name_for_inferred_objects)
9495
end
95-
9696
record.public_send(id_method_name)
9797
end
9898
end

spec/lib/object_serializer_class_methods_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,31 @@
8787
end
8888
end
8989

90+
describe '#has_many with block and id_method_name' do
91+
before do
92+
MovieSerializer.has_many(:awards, id_method_name: :imdb_award_id) do |movie|
93+
movie.actors.map(&:awards).flatten
94+
end
95+
end
96+
97+
after do
98+
MovieSerializer.relationships_to_serialize.delete(:awards)
99+
end
100+
101+
context 'awards is not included' do
102+
subject(:hash) { MovieSerializer.new(movie).serializable_hash }
103+
104+
it 'returns correct hash where id is obtained from the method specified via `id_method_name`' do
105+
expected_award_data = movie.actors.map(&:awards).flatten.map do |actor|
106+
{ id: actor.imdb_award_id.to_s, type: actor.class.name.downcase.to_sym }
107+
end
108+
serialized_award_data = hash[:data][:relationships][:awards][:data]
109+
110+
expect(serialized_award_data).to eq(expected_award_data)
111+
end
112+
end
113+
end
114+
90115
describe '#belongs_to' do
91116
subject(:relationship) { MovieSerializer.relationships_to_serialize[:area] }
92117

spec/shared/contexts/movie_context.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def awards
8080
a.id = i
8181
a.title = "Test Award #{i}"
8282
a.actor_id = id
83+
a.imdb_award_id = i * 10
8384
end
8485
end
8586
end
@@ -110,7 +111,7 @@ def state
110111
end
111112

112113
class Award
113-
attr_accessor :id, :title, :actor_id
114+
attr_accessor :id, :title, :actor_id, :imdb_award_id
114115
end
115116

116117
class State

0 commit comments

Comments
 (0)