class PostRepresenter
def represent(post)
{
id: post.id,
title: post.title,
comments: post.comments.order(created_at: :desc).map {
|c| CommentRepresenter.new.represent(c)
}
}
end
end
class PostsRepresenter
def represent(posts)
posts.map { |p| PostRepresenter.new.represent(p) }
end
end
Can you notice the problem?
class PostsRepresenter
def represent(posts)
posts.includes(:comments).map {
|p| PostRepresenter.new.represent(p)
}
end
end
class MessageRepresenter
def represent(message, user)
{
title: message.title,
author_name: author_name(message, user)
}
end
def author_name(message, user)
# Complex logic required
if author_visible?(message, user)
message.author.name
else
"Placeholder"
end
end
end
class Superuser::MessageRepresenter
def represent(message)
{
title: message.title,
author_name: message.author_name
}
end
end
class PageRepresenter
def initialize
@redis = Redis.new
end
def represent(page)
{
views: MagicCounter.new(page, @redis).unique_since(10.days.ago)
}
end
end
class PagesRepresenter
def represent(pages)
pages.map { |page| PageRepresenter.new.represent(page) }
end
end
What possibly could go wrong?
You should not do any DB queries in representers
The most important thing to me is that Representer shouldn't represent your database structure but it should return appropriate set of data for your endpoint
© by @jcieslar_
Related: AR vs PORO Entities, How to do REST
Like templates representers should be dumb
Just do simple transformation
Output and input format it's the whole world
If you really need any dependencies - inject them
class SomethingRepresenter
def represent(something)
{
foo: something.foo,
bar: something.bar
}
end
end
design pattern that allows behavior to be added to an individual object without affecting the behavior of other objects from the same class
Subtype of decorator pattern which adds behavior for object transformation into different format
Homemade definition
class SomethingRepresenter < DelegateClass(Something)
def to_json
to_hash.to_json
end
def to_hash
{
foo: foo,
bar: bar
}
end
# TODO: to_xml, to_whatever
end
class SomethingRepresenter < Representable::Decorator
include Representable::JSON
property :foo
property :bar
end
SomethingRepresenter.new(something).to_json