Skip to content

Commit 9d528ca

Browse files
committed
Utilise ActiveModel::Serializers::JSON in Her models
This makes as_json and to_json behave like they do under ActiveRecord, excluding associations unless they are explicitly included. This is necessary to avoid infinite loops. Unfortunately this caused Her's include_root_in_json code to collide with ActiveModel's include_root_in_json code. I removed Her's getter/setter method in favour of ActiveModel's class attribute but also provided a compatibility fix.
1 parent cad9a0e commit 9d528ca

File tree

5 files changed

+43
-30
lines changed

5 files changed

+43
-30
lines changed

lib/her/model.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require "active_model"
12
require "her/model/base"
23
require "her/model/deprecated_methods"
34
require "her/model/http"
@@ -7,9 +8,9 @@
78
require "her/model/parse"
89
require "her/model/associations"
910
require "her/model/introspection"
11+
require "her/model/serialization"
1012
require "her/model/paths"
1113
require "her/model/nested_attributes"
12-
require "active_model"
1314

1415
module Her
1516
# This module is the main element of Her. After creating a Her::API object,
@@ -33,6 +34,7 @@ module Model
3334
include Her::Model::HTTP
3435
include Her::Model::Parse
3536
include Her::Model::Introspection
37+
include Her::Model::Serialization
3638
include Her::Model::Paths
3739
include Her::Model::Associations
3840
include Her::Model::NestedAttributes

lib/her/model/parse.rb

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def to_params(attributes, changes={})
4343

4444
embed_params!(attributes, filtered_attributes)
4545

46-
if include_root_in_json?
46+
if include_root_in_json
4747
if json_api_format?
4848
{ included_root_element => [filtered_attributes] }
4949
else
@@ -93,18 +93,6 @@ def embed_params!(read_attributes, write_attributes)
9393
Thread.current[:her_embedded_params_objects] = nil if first
9494
end
9595

96-
# Return or change the value of `include_root_in_json`
97-
#
98-
# @example
99-
# class User
100-
# include Her::Model
101-
# include_root_in_json true
102-
# end
103-
def include_root_in_json(value, options = {})
104-
@_her_include_root_in_json = value
105-
@_her_include_root_in_json_format = options[:format]
106-
end
107-
10896
# Return or change the value of `parse_root_in_json`
10997
#
11098
# @example
@@ -168,7 +156,7 @@ def root_element_included?(data)
168156

169157
# @private
170158
def included_root_element
171-
include_root_in_json? == true ? root_element : include_root_in_json?
159+
include_root_in_json == true ? root_element : include_root_in_json
172160
end
173161

174162
# Extract an array from the request data
@@ -225,11 +213,6 @@ def request_new_object_on_build?
225213
@_her_request_new_object_on_build || (superclass.respond_to?(:request_new_object_on_build?) && superclass.request_new_object_on_build?)
226214
end
227215

228-
# @private
229-
def include_root_in_json?
230-
@_her_include_root_in_json || (superclass.respond_to?(:include_root_in_json?) && superclass.include_root_in_json?)
231-
end
232-
233216
# @private
234217
def parse_root_in_json?
235218
@_her_parse_root_in_json || (superclass.respond_to?(:parse_root_in_json?) && superclass.parse_root_in_json?)

lib/her/model/serialization.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module Her
2+
module Model
3+
module Serialization
4+
extend ActiveSupport::Concern
5+
include ActiveModel::Serializers::JSON
6+
7+
def serializable_hash(options = nil)
8+
options = options.try(:dup) || {}
9+
10+
options[:except] = Array(options[:except]).map(&:to_s)
11+
options[:except] |= self.class.association_names.map(&:to_s)
12+
13+
super(options)
14+
end
15+
16+
included do
17+
# Rails 3 defaulted to true but Her has always defaulted to
18+
# false. This can be dropped when Rails 3 support is dropped.
19+
self.include_root_in_json = false
20+
21+
class << self
22+
alias_method :include_root_in_json_getter, :include_root_in_json
23+
24+
# Rails creates include_root_in_json as a class attribute
25+
# but Her previously had its own implementation combining
26+
# the getter and setter. This provides compatibility.
27+
def include_root_in_json(value = nil)
28+
if value.nil?
29+
include_root_in_json_getter
30+
else
31+
self.include_root_in_json = value
32+
end
33+
end
34+
end
35+
end
36+
end
37+
end
38+
end

spec/support/extensions/array.rb

Lines changed: 0 additions & 5 deletions
This file was deleted.

spec/support/extensions/hash.rb

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)