rails-api / active_model_serializers

ActiveModel::Serializer implementation and Rails hooks
MIT License
5.33k stars 1.39k forks source link

Deserialization excludes hash attribute contents #2219

Open coreypmurphy opened 7 years ago

coreypmurphy commented 7 years ago

Expected behavior vs actual behavior

Given a model with an attribute that is treated as a hash of options, I'm expecting AMS to deserialize the JSON payload so I can persist the "some-options" attribute (re-serialized as YAML by the ActiveRecord::Base "serialize" method) to the db as it did in AMS@0.9.3.

But ActiveModelSerializers::Deserialization.jsonapi_parse() is excluding the contents of "some-options" during deserialization. Other attributes are deserialized as expected.

Steps to reproduce

POSTed JSON payload:

{
  "data": {
    "attributes": {
      "name": "John",
      "some-options": {
    "key1": "value 1",
    "key2": "value 2"
      }
    },
    "type": "courses"
  }
}

Model:

class Course < ApplicationRecord
  validates :name, presence: true
  serialize :some_options 
end

Controller:

class Api::CoursesController < ApplicationController
  def create
    course = Course.new(course_params)
    if course.save
      render json: course
    else
      render json: course.errors, status: :unprocessable_entity
    end
  end

  def course_params
    ActiveModelSerializers::Deserialization.jsonapi_parse(params, only: [
      :name, 
      some_options: option_keys
    ])
  end

  def option_keys
    params.dig('data','attributes').fetch('some-options', {}).keys
  end
end

config/initializers/json_api.rb

ActiveSupport.on_load(:action_controller) do
  require 'active_model_serializers/register_jsonapi_renderer'
end

ActiveModelSerializers.config.adapter = :json_api
ActiveModelSerializers.config.key_transform = :unaltered

Environment

ActiveModelSerializers Version (commit ref if not on tag): 0.10.6

Output of ruby -e "puts RUBY_DESCRIPTION": ruby 2.3.4p301 (2017-03-30 revision 58214) [x86_64-darwin16]

OS Type & Version: OSX 10.12.4

Integrated application and version (e.g., Rails, Grape, etc): Rails@5.0.2

For reference this is a migration to AMS@0.10.6 and JSONAPI from AMS@0.9.3. Our Ember frontend was using "ActiveModelAdapter", so we had Ember dealing with key transforms and serialization on requests coming to Rails and our strong params implementation wasn't being "deserialized" as they are in AMS@0.10.6.

bf4 commented 7 years ago

related https://github.com/rails-api/active_model_serializers/pull/1928 https://github.com/rails-api/active_model_serializers/pull/1927

coreypmurphy commented 7 years ago

@bf4 , thanks. I had read those earlier but seeing as how long those have been open I was hoping I had just missed something. Between that and the disclaimer about "Deserialization" being an experimental feature I guess I should have known better. Real bummer since we're trying to move our project to JSON API. Any thoughts on how soon we'll see that branch hit master?

bf4 commented 7 years ago

I was hoping you could help

B mobile phone

On Nov 9, 2017, at 3:18 PM, Corey Murphy notifications@github.com wrote:

@bf4 , thanks. I had read those earlier but seeing as how long those have been open I was hoping I had just missed something. Between that and the disclaimer about "Deserialization" being an experimental feature I guess I should have known better. Real bummer since we're trying to move our project to JSON API. Any thoughts on how soon we'll see that branch hit master?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

coreypmurphy commented 7 years ago

I appreciate the offer but I'm not completely confident I could pick up where you guys have left off.