Skip to content

Edge cases with key transformations #449

@summera

Description

@summera

Describe the bug

I've noticed a few interesting bugs/edge cases related to transforming keys:

Case 1 - Nested inline associations

Using #transform_keys! does not seem to work on nested inline associations, whereas #transform_keys does. Here's an example. Note that valueCents is still camel case when calling #transform_keys!(:dash).

class MySerializer
  include Alba::Resource

  transform_keys :lower_camel

  many :budget_lines do
    attributes :operating_budget_id

    many :budget_amounts do
      attributes :value_cents
    end
  end
end


> MySerializer.new(object).as_json
=>
{"budgetLines" =>
  [{"operatingBudgetId" => 1,
    "budgetAmounts" => [{"valueCents" => 100}]}]}

> MySerializer.transform_keys!(:dash).new(object).as_json
=>
{"budget-lines" =>
  [{"operating-budget-id" => 1,
    "budget-amounts" => [{"valueCents" => 100}]}]}

Case 2 - transform_keys! side effects remain

Note that the final call to as_json is a mix of dash and camel case. This might be related to inline associations?

> MySerializer.new(object).as_json
=>
{"budgetLines" =>
  [{"operatingBudgetId" => 1,
    "budgetAmounts" => [{"valueCents" => 100}]}]}

> MySerializer.transform_keys!(:dash).new(object).as_json
=>
{"budget-lines" =>
  [{"operating-budget-id" => 1,
    "budget-amounts" => [{"valueCents" => 100}]}]}

> MySerializer.new(object).as_json
=>
{"budgetLines" =>
  [{"operating-budget-id" => 1,
    "budget-amounts" => [{"valueCents" => 100}]}]}

Case 3 - JSONB does not have keys transformed

I have a column with a JSONB array of objects that has snakecase keys. If included in the serializer, I'd like to have those keys transformed as well. Is there a good way to achieve this? Right now, I'm doing the following as a workaround:

  attribute :periods do |object|
    object.periods.map do |p|
      p.deep_transform_keys { |key| transform_key(key) }
    end
  end

To Reproduce

See examples above.

Expected behavior

  • Case 1: #transform_keys! expected to propagate to nested relations
  • Case 2: #transform_keys! expected to not have side effects beyond using the class returned from it. Do you think it would be possible to pass the key type to the #serialize or #as_json methods if we want to change keys at the time of serialization? Example would be: MySerializer.new(object).as_json(transform_keys: :lower_camel).
  • Case 3: It would be nice to be able to transform hash/jsonb attributes

Actual behavior

See examples above.

Environment

  • Ruby version: 3.4.4

Thanks in advance for any help!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions