Skip to content

Commit

Permalink
Serialize nested Her::Model instances that are not associated
Browse files Browse the repository at this point in the history
We previously added serialization for ActiveModel::Serialization
instances but Her::Model instances can still be left untouched if they
do not belong to an association.

In order to serialize these safely, we have to move this block of code
into embed_params!, which guards against infinite loops. This has the
added benefit of not doing unnecessary serialization when
send_only_modified_attributes is enabled.
  • Loading branch information
chewi committed Sep 19, 2018
1 parent b1ddb12 commit 80d3ae5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 14 deletions.
5 changes: 0 additions & 5 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ Bundler/DuplicatedGem:
Exclude:
- 'Gemfile'

# Offense count: 1
Lint/EmptyWhen:
Exclude:
- 'lib/her/model/parse.rb'

# Offense count: 1
Lint/IneffectiveAccessModifier:
Exclude:
Expand Down
30 changes: 21 additions & 9 deletions lib/her/model/parse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,7 @@ def parse(data)

# @private
def to_params(attributes, changes = {})
filtered_attributes = attributes.each_with_object({}) do |(key, value), memo|
case value
when Her::Model
when ActiveModel::Serialization
value = value.serializable_hash.symbolize_keys
end

memo[key.to_sym] = value
end
filtered_attributes = attributes.symbolize_keys

if her_api.options[:send_only_modified_attributes]
filtered_attributes.slice! *changes.keys.map(&:to_sym)
Expand Down Expand Up @@ -94,6 +86,26 @@ def embed_params!(read_attributes, write_attributes)

write_attributes[assoc[:data_key]] = value if value.present?
end

write_attributes.each do |key, value|
value =
case value
when Her::Collection
value.map(&:to_params).reject(&:empty?)
when Her::Model
value.to_params
when ActiveModel::Serialization
value.serializable_hash.symbolize_keys
end

if value
if value.empty?
write_attributes.delete(key)
else
write_attributes[key] = value
end
end
end
ensure
Thread.current[:her_embedded_params_objects] = nil if first
end
Expand Down
10 changes: 10 additions & 0 deletions spec/model/parse_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ def to_params
{ fullname: "Lindsay Fünke" }
end
end

spawn_model "Foo::Comment" do
attributes :user
end
end

it "changes the request parameters for one-line resource creation" do
Expand All @@ -356,6 +360,12 @@ def to_params
@user.save
expect(@user.fullname).to eq("Lindsay Fünke")
end

it 'changes the request parameters when nested inside an unassociated resource' do
@user = Foo::User.new(fullname: "Tobias Fünke")
@comment = Foo::Comment.new(user: @user)
expect(@comment.to_params).to eq(user: { fullname: "Lindsay Fünke" })
end
end

context "when parse_root_in_json set json_api to true" do
Expand Down

0 comments on commit 80d3ae5

Please sign in to comment.