jsonapi-serializers icon indicating copy to clipboard operation
jsonapi-serializers copied to clipboard

data object within relationships object

Open craigulliott opened this issue 10 years ago • 8 comments

Hello Mike,

First, thank you for this gem. I tried several before yours and this has been by far the best implementation and the easiest to work with.

I'm not entirely sure if this is user error, or a bug. But I am unable to get the data object within the relationships object to appear (as per your example output pasted below). I have tried referencing child objects as a has_one :tutorial and has_many :tutorials, and have been sure to include them with include: ['tutorials']. I do get a relationships object, but it only contains links (no data object). The included object is coming back properly and contains the expected data.

I checked out the gem source, and have started walking through the code. There are a few places where it seems that the symbol :tutorial might be incorrectly compared to the string 'tutorial'?

https://github.com/fotinakis/jsonapi-serializers/blob/master/lib/jsonapi-serializers/serializer.rb#L104 (@_include_linkages = ['tutorials] but formatted_attribute_name = :tutorials)

Am I missing something obvious and this should in fact work?

Thanks very much

{
  "data": {
    "id": "1",
    "type": "posts",
    "attributes": {
      "title": "Hello World",
      "content": "Your first post"
    },
    "links": {
      "self": "/posts/1"
    },
    "relationships": {  <--- this is rendered properly
      "author": {
        "links": {
          "self": "/posts/1/relationships/author",
          "related": "/posts/1/author"
        },
        "data": {  <--- this data object is not rendered at all
          "type": "users",    
          "id": "1"
        }
      },
      "comments": {
        "links": {
          "self": "/posts/1/relationships/comments",
          "related": "/posts/1/comments"
        },
        "data": [
          {
            "type": "comments",
            "id": "1"
          }
        ]
      }
    }
  },
  "included": [ <--- this is rendered properly
    {
      "id": "1",
      "type": "users",
      "attributes": {
        "name": "Post Author"
      },
      "links": {
        "self": "/users/1"
      }
    },
    {
      "id": "1",
      "type": "comments",
      "attributes": {
        "content": "Have no fear, sers, your king is safe."
      },
      "links": {
        "self": "/comments/1"
      },
      "relationships": {
        "user": {
          "links": {
            "self": "/comments/1/relationships/user",
            "related": "/comments/1/user"
          },
          "data": {
            "type": "users",
            "id": "2"
          }
        },
        "post": {
          "links": {
            "self": "/comments/1/relationships/post",
            "related": "/comments/1/post"
          }
        }
      }
    },
    {
      "id": "2",
      "type": "users",
      "attributes": {
        "name": "Barristan Selmy"
      },
      "links": {
        "self": "/users/2"
      }
    }
  ]
}

craigulliott avatar Feb 15 '16 16:02 craigulliott

Interesting...I looked through the code again too and I think you are probably right.

I just pushed https://github.com/fotinakis/jsonapi-serializers/commit/63e1132b67124469395cdde38a9a29c4e037eb52 to a branch named test-string-symbol-bug — can you test with this branch directly and see if it solves your problem? If it does, I will write a test for this and fix it in the mainline.

fotinakis avatar Feb 15 '16 17:02 fotinakis

Actually, it's probably something else, the line you referenced: if @_include_linkages.include?(formatted_attribute_name) compares a string, in @_include_linkages, to a string in formatted_attribute_name (the format_name method does .to_s inside it).

Probably back to the drawing board here.

fotinakis avatar Feb 15 '16 17:02 fotinakis

Forgive me for being so unscientific about this, but here is what I get when I break on that line:

screen shot 2016-02-15 at 12 11 38 pm

craigulliott avatar Feb 15 '16 18:02 craigulliott

I'll try your branch right now - thanks

craigulliott avatar Feb 15 '16 18:02 craigulliott

Have you implemented a custom format_name method by chance?

fotinakis avatar Feb 15 '16 18:02 fotinakis

Yes I am! Here is my base serializer which the others extend from.

class BaseSerializer
  include JSONAPI::Serializer

  def base_url
    ENV['API_HOST']
  end

  # By default, attribute names are dasherized per the spec naming recommendations, but
  # we prefer to keep them underscores so that it's the same from front to back
  def format_name(attribute_name)
    attribute_name
  end
  # The opposite of format_name.
  def unformat_name(attribute_name)
    attribute_name
  end

end

craigulliott avatar Feb 15 '16 19:02 craigulliott

It works!

Thank you very much for your help - sorry that it did indeed turn out to be user error.


class BaseSerializer
  include JSONAPI::Serializer

  def base_url
    ENV['API_HOST']
  end

  # By default, attribute names are dasherized per the spec naming recommendations, but
  # we prefer to keep them underscores so that it's the same from front to back
  def format_name(attribute_name)
    attribute_name.to_s
  end
  # The opposite of format_name.
  def unformat_name(attribute_name)
    attribute_name.to_s
  end

end


craigulliott avatar Feb 15 '16 19:02 craigulliott

Nice! That's an easy mistake to make, so we should just fix it by converting internally. Going to leave this open for that.

fotinakis avatar Feb 15 '16 19:02 fotinakis