Skip to content

Commit c41e243

Browse files
authored
Merge pull request #2218 from rails-api/opt_in_belongs_to_uses_foreign_key
Fix 0.10.6 regression; make using belongs_to on self opt-in
2 parents 00a47d3 + b41451c commit c41e243

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

docs/general/configuration_options.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ still prefer the render option `:key_transform` over this setting.
5757
application, setting `config.key_transform` to `:unaltered` will provide a performance boost.*
5858

5959
##### default_includes
60+
6061
What relationships to serialize by default. Default: `'*'`, which includes one level of related
6162
objects. See [includes](adapters.md#included) for more info.
6263

@@ -162,6 +163,21 @@ Default: `{}`.
162163

163164
*Used when `jsonapi_include_toplevel_object` is `true`*
164165

166+
##### jsonapi_use_foreign_key_on_belongs_to_relationship
167+
168+
When true, the relationship will determine its resource object identifier
169+
without calling the association or its serializer. This can be useful when calling
170+
the association object is triggering unnecessary queries.
171+
172+
For example, if a `comment` belongs to a `post`, and the comment
173+
uses the foreign key `post_id`, we can determine the resource object
174+
identifier `id` as `comment.post_id` and the `type` from the association options.
175+
Or quite simply, it behaves as `belongs_to :post, type: :posts, foreign_key: :post_id`.
176+
177+
Note: This option has *no effect* on polymorphic associations as we cannot reliably
178+
determine the associated object's type without instantiating it.
179+
180+
Default: `false`.
165181

166182
## Hooks
167183

lib/active_model/serializer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ def config.array_serializer
142142
# Make JSON API top-level jsonapi member opt-in
143143
# ref: http://jsonapi.org/format/#document-top-level
144144
config.jsonapi_include_toplevel_object = false
145+
config.jsonapi_use_foreign_key_on_belongs_to_relationship = false
145146
config.include_data_default = true
146147

147148
# For configuring how serializers are found.

lib/active_model_serializers/adapter/json_api/relationship.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ def meta_for(association)
9494
end
9595

9696
def belongs_to_id_on_self?(association)
97-
association.belongs_to? &&
97+
parent_serializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship &&
98+
association.belongs_to? &&
9899
parent_serializer.object.respond_to?(association.reflection.foreign_key)
99100
end
100101
end

test/serializers/associations_test.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,14 @@ def blog_id
159159
end
160160
end
161161

162-
actual = serializable(post, adapter: :json_api, serializer: BelongsToBlogModelSerializer).as_json
162+
actual =
163+
begin
164+
original_option = BelongsToBlogModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship
165+
BelongsToBlogModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship = true
166+
serializable(post, adapter: :json_api, serializer: BelongsToBlogModelSerializer).as_json
167+
ensure
168+
BelongsToBlogModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship = original_option
169+
end
163170
expected = { data: { id: '1', type: 'posts', relationships: { blog: { data: { id: '5', type: 'blogs' } } } } }
164171

165172
assert_equal expected, actual
@@ -189,7 +196,14 @@ def test_belongs_to_allows_id_overwriting
189196
}
190197
post = BelongsToExternalBlogModel.new(attributes)
191198

192-
actual = serializable(post, adapter: :json_api, serializer: BelongsToExternalBlogModelSerializer).as_json
199+
actual =
200+
begin
201+
original_option = BelongsToExternalBlogModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship
202+
BelongsToExternalBlogModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship = true
203+
serializable(post, adapter: :json_api, serializer: BelongsToExternalBlogModelSerializer).as_json
204+
ensure
205+
BelongsToExternalBlogModelSerializer.config.jsonapi_use_foreign_key_on_belongs_to_relationship = original_option
206+
end
193207
expected = { data: { id: '1', type: 'posts', relationships: { :'external-blog' => { data: { id: '6', type: 'external-blogs' } } } } }
194208

195209
assert_equal expected, actual

0 commit comments

Comments
 (0)