Search code examples
jsonruby-on-rails-4active-model-serializers

undefined method `keys' for nil:NilClass while calling to_json on arbitrary class instance


I have following classes defined

class Post
  include ActiveModel::Serializers::JSON

  attr_accessor :id,
                :title,
                :status,
                :meta
  def attributes
    { 'id' => nil, 'title' => nil, 'status' => nil, 'meta' => nil }
  end
end


class PostMeta
  include ActiveModel::Serializers::JSON

  attr_accessor :id,
                :key,
                :value,
                :description

  def attributes
    { 'id' => nil, 'key' => nil, 'value' => nil }
  end
end

When I try to call to_json it gives mentioned error. Here how I setup the data

post = Post.new
post.id = 1
post.title = 'test'
post.status = 0

meta = PostMeta.new
meta.id = 8
meta.key = 'cloud'
meta.value = 'wpengine'

post.meta = meta

post.to_json

If I don't set meta in post then it doesn't give the error. Also, If I set meta with an active record instance, it also works without error.

Can anybody suggest what I am missing in above classes?


Solution

  • I figured it out.

    PostMeta has defined attribute_accessor for description but was missing in hash returned by attributes method.

    I also refactored a bit so I don't have to worry about adding/removing attributes to attributes hash if attributes_accessor list changes.

    class Base
      include ActiveModel::Serializers::JSON
    
      def attributes
        @attributes ||= Hash[self.class::ATTRIBUTES.map(&:to_s).zip]
      end
    end
    
    class Post < Base
      ATTRIBUTES = [:id, :title, :status, :meta]
      attr_accessor *ATTRIBUTES
    
    end
    
    
    class PostMeta < Base
      ATTRIBUTES = [:id, :key, :value, description]
      attr_accessor *ATTRIBUTES
    end