Skip to content

Commit fdd9970

Browse files
committed
Enhance PORO documentation
1 parent 1dc2b74 commit fdd9970

File tree

1 file changed

+51
-4
lines changed

1 file changed

+51
-4
lines changed

docs/howto/serialize_poro.md

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
# How to serialize a Plain-Old Ruby Object (PORO)
44

5-
When you are first getting started with ActiveModelSerializers, it may seem only `ActiveRecord::Base` objects can be serializable, but pretty much any object can be serializable with ActiveModelSerializers. Here is an example of a PORO that is serializable:
5+
### Using Duck Typing
6+
When you are first getting started with ActiveModelSerializers, it may seem only `ActiveRecord::Base` objects can be serializable, but pretty much any object can be serializable with ActiveModelSerializers.
7+
Here is an example of a PORO that is serializable just by implementing the needed methods:
8+
69
```ruby
710
# my_model.rb
811
class MyModel
912
alias :read_attribute_for_serialization :send
1013
attr_accessor :id, :name, :level
11-
14+
1215
def initialize(attributes)
1316
@id = attributes[:id]
1417
@name = attributes[:name]
@@ -21,12 +24,56 @@ class MyModel
2124
end
2225
```
2326

24-
Fortunately, ActiveModelSerializers provides a [`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb) which you can use in production code that will make your PORO a lot cleaner. The above code now becomes:
27+
### Inheriting ActiveModelSerializers::Model
28+
Fortunately, ActiveModelSerializers provides a [`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb) which you can use in production code that will make your PORO a lot cleaner.
29+
The above code now becomes:
2530
```ruby
2631
# my_model.rb
2732
class MyModel < ActiveModelSerializers::Model
2833
attr_accessor :id, :name, :level
2934
end
3035
```
3136

32-
The default serializer would be `MyModelSerializer`.
37+
The default serializer would be `MyModelSerializer`.
38+
39+
### Serializing an instance
40+
Sometimes you don't want to create yet another class just to serialize an object.
41+
Well, athough it is recommended to have defined classes for what you serialize,
42+
this is possible as well:
43+
44+
Given the following serializer:
45+
46+
```ruby
47+
class Api::V1::UserSerializer
48+
type :user #this is necessery, otherwise AMS will show your instance class name
49+
50+
attributes :id, :name
51+
```
52+
53+
```ruby
54+
class Api::V1::UsersController
55+
def show
56+
#this is just an example
57+
an_instance = OpenStruct.new(id: 1, name: 'Just an example')
58+
59+
an_instance.singleton_class.send(:alias_method, :read_attribute_for_serialization, :send)
60+
61+
render jsonapi: an_instance, serializer: Api::V1::UserSerializer
62+
end
63+
end
64+
```
65+
66+
If your object is just a hash you can do the following trick:
67+
```ruby
68+
class Api::V1::UsersController
69+
def show
70+
#this is just an example
71+
an_instance = {id: 1, name: 'Just an example'}
72+
an_instance.singleton_class.send(:alias_method, :read_attribute_for_serialization, :[])
73+
74+
render jsonapi: an_instance, serializer: Api::V1::UserSerializer,
75+
end
76+
end
77+
```
78+
Note however that if your hash keys are strings then you will need to convert them
79+
to symbols first (or just wrap it in `HashWithIndifferentAccess`).

0 commit comments

Comments
 (0)