Skip to content

Commit cdcd04c

Browse files
authored
Merge pull request #746 from seako/fix-serialization-of-two-relationships-with-same-primary-key
use resource value instead of model attribute to get relationship model id for one to many relationships
2 parents 3e0e104 + 61d46d8 commit cdcd04c

3 files changed

Lines changed: 176 additions & 2 deletions

File tree

lib/jsonapi/resource_serializer.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ def foreign_key_types_and_values(source, relationship)
327327
end
328328
end
329329
else
330-
source.public_send(relationship.foreign_key).map do |value|
331-
[relationship.type, @id_formatter.format(value)]
330+
source.public_send(relationship.name).map do |value|
331+
[relationship.type, @id_formatter.format(value.id)]
332332
end
333333
end
334334
end

test/fixtures/active_record.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ class Person < ActiveRecord::Base
263263

264264
has_and_belongs_to_many :books, join_table: :book_authors
265265

266+
has_many :even_posts, -> { where('posts.id % 2 = 0') }, class_name: 'Post', foreign_key: 'author_id'
267+
has_many :odd_posts, -> { where('posts.id % 2 = 1') }, class_name: 'Post', foreign_key: 'author_id'
268+
266269
### Validations
267270
validates :name, presence: true
268271
validates :date_joined, presence: true
@@ -808,6 +811,13 @@ def self.verify_name_filter(values, _context)
808811

809812
end
810813

814+
class PersonWithEvenAndOddPostsResource < JSONAPI::Resource
815+
model_name 'Person'
816+
817+
has_many :even_posts, foreign_key: 'author_id', class_name: 'Post', relation_name: :even_posts
818+
has_many :odd_posts, foreign_key: 'author_id', class_name: 'Post', relation_name: :odd_posts
819+
end
820+
811821
class SpecialBaseResource < BaseResource
812822
abstract
813823

test/unit/serializer/serializer_test.rb

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,5 +2175,169 @@ def test_custom_links_with_lambda
21752175
assert_hash_equals(custom_link_spec, serialized_custom_link_resource)
21762176
end
21772177

2178+
def test_includes_two_relationships_with_same_foreign_key
2179+
serialized_resource = JSONAPI::ResourceSerializer
2180+
.new(PersonWithEvenAndOddPostsResource, include: ['even_posts','odd_posts'])
2181+
.serialize_to_hash(PersonWithEvenAndOddPostsResource.new(Person.first, nil))
2182+
2183+
assert_hash_equals(
2184+
{
2185+
data: {
2186+
id: "1",
2187+
type: "personWithEvenAndOddPosts",
2188+
links: {
2189+
self: "/personWithEvenAndOddPosts/1"
2190+
},
2191+
relationships: {
2192+
evenPosts: {
2193+
links: {
2194+
self: "/personWithEvenAndOddPosts/1/relationships/evenPosts",
2195+
related: "/personWithEvenAndOddPosts/1/evenPosts"
2196+
},
2197+
data: [
2198+
{
2199+
type: "posts",
2200+
id: "2"
2201+
}
2202+
]
2203+
},
2204+
oddPosts: {
2205+
links: {
2206+
self: "/personWithEvenAndOddPosts/1/relationships/oddPosts",
2207+
related: "/personWithEvenAndOddPosts/1/oddPosts"
2208+
},
2209+
data:[
2210+
{
2211+
type: "posts",
2212+
id: "1"
2213+
},
2214+
{
2215+
type: "posts",
2216+
id: "11"
2217+
}
2218+
]
2219+
}
2220+
}
2221+
},
2222+
included:[
2223+
{
2224+
id: "2",
2225+
type: "posts",
2226+
links: {
2227+
self: "/posts/2"
2228+
},
2229+
attributes: {
2230+
title: "JR Solves your serialization woes!",
2231+
body: "Use JR",
2232+
subject: "JR Solves your serialization woes!"
2233+
},
2234+
relationships: {
2235+
author: {
2236+
links: {
2237+
self: "/posts/2/relationships/author",
2238+
related: "/posts/2/author"
2239+
}
2240+
},
2241+
section: {
2242+
links: {
2243+
self: "/posts/2/relationships/section",
2244+
related: "/posts/2/section"
2245+
}
2246+
},
2247+
tags: {
2248+
links: {
2249+
self: "/posts/2/relationships/tags",
2250+
related: "/posts/2/tags"
2251+
}
2252+
},
2253+
comments: {
2254+
links: {
2255+
self: "/posts/2/relationships/comments",
2256+
related: "/posts/2/comments"
2257+
}
2258+
}
2259+
}
2260+
},
2261+
{
2262+
id: "1",
2263+
type: "posts",
2264+
links: {
2265+
self: "/posts/1"
2266+
},
2267+
attributes: {
2268+
title: "New post",
2269+
body: "A body!!!",
2270+
subject: "New post"
2271+
},
2272+
relationships: {
2273+
author: {
2274+
links: {
2275+
self: "/posts/1/relationships/author",
2276+
related: "/posts/1/author"
2277+
}
2278+
},
2279+
section: {
2280+
links: {
2281+
self: "/posts/1/relationships/section",
2282+
related: "/posts/1/section"
2283+
}
2284+
},
2285+
tags: {
2286+
links: {
2287+
self: "/posts/1/relationships/tags",
2288+
related: "/posts/1/tags"
2289+
}
2290+
},
2291+
comments: {
2292+
links: {
2293+
self: "/posts/1/relationships/comments",
2294+
related: "/posts/1/comments"
2295+
}
2296+
}
2297+
}
2298+
},
2299+
{
2300+
id: "11",
2301+
type: "posts",
2302+
links: {
2303+
self: "/posts/11"
2304+
},
2305+
attributes: {
2306+
title: "JR How To",
2307+
body: "Use JR to write API apps",
2308+
subject: "JR How To"
2309+
},
2310+
relationships: {
2311+
author: {
2312+
links: {
2313+
self: "/posts/11/relationships/author",
2314+
related: "/posts/11/author"
2315+
}
2316+
},
2317+
section: {
2318+
links: {
2319+
self: "/posts/11/relationships/section",
2320+
related: "/posts/11/section"
2321+
}
2322+
},
2323+
tags: {
2324+
links: {
2325+
self: "/posts/11/relationships/tags",
2326+
related: "/posts/11/tags"
2327+
}
2328+
},
2329+
comments: {
2330+
links: {
2331+
self: "/posts/11/relationships/comments",
2332+
related: "/posts/11/comments"
2333+
}
2334+
}
2335+
}
2336+
}
2337+
]
2338+
},
2339+
serialized_resource
2340+
)
2341+
end
21782342

21792343
end

0 commit comments

Comments
 (0)