Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use active_model_serializer with a non-ActiveRecord object

I have a model object that is not descended from ActiveRecord::Base and is not stored in the database. I created a serializer for it (with the same name + "Serializer"), and in my controller I'm calling render json: object_instance.

The result is an exception from deep inside of render.

I implemented an as_json method that instantiates the serializer and calls it, but the result is then a missing method in the object, read_attribute_for_serialization.

I want my object to act like an ActiveModel-compatible object at least as far as Active Model Serializer goes, but I don't see any reference to this in their documentation.

like image 302
Robin Daugherty Avatar asked Feb 11 '14 19:02

Robin Daugherty


3 Answers

The model object needs to include it thusly:

# active_model_serializers 0.10+
class ModelName
  include ActiveModel::Serialization
end

# active_model_serializers < 0.10
class ModelName
  include ActiveModel::SerializerSupport
end

This implements the methods needed within the object, and also auto-discovers the serializer matching the object name, so it can be used transparently just like an ActiveRecord object.

This works with active_model_serializers version 0.8.1 through at least 0.9.3.

like image 70
Robin Daugherty Avatar answered Oct 23 '22 12:10

Robin Daugherty


Following on from mutexkid answer, with active_model_serializers 0.10.0.rc4, the following is required to make a plain old ruby object play nice with a serializer:

PORO:

class SearchResult
  include ActiveModel::Serialization

  attr_reader :stories, :users, :friends

  def initialize(search:)
    @stories = search.stories
    @users = search.users
    @friends = search.friends
  end
end

Serializer:

class SearchResultSerializer < ActiveModel::Serializer
  attributes :stories, :users, :friends
end
like image 13
b73 Avatar answered Oct 23 '22 12:10

b73


I ran into this yesterday while upgrading to Rails 4.2. ActiveModel::SerializerSupport has been removed for 0.10-stable. I ended up just adding an alias to my POROs which seemed to do the trick:

  alias :read_attribute_for_serialization :send

(active_model_serializers 0.10.0.rc2)

You will also need to add include ActiveModel::Model in your class.

like image 7
Karl Wilbur Avatar answered Oct 23 '22 12:10

Karl Wilbur