Representers
The Bad, The Ugly and The Worst
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
endclass PostsRepresenter
  def represent(posts)
    posts.map { |p| PostRepresenter.new.represent(p) }
  end
endCan you notice the problem?
git commit -am "Fiksik"
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
endclass Superuser::MessageRepresenter
  def represent(message)
    {
      title: message.title,
      author_name: message.author_name
    }
  end
endclass 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
endWhat possibly could go wrong?
 
        
Query less
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
Logic less
Like templates representers should be dumb
Just do simple transformation
Knowledge less
Output and input format it's the whole world
If you really need any dependencies - inject them
Bonus
What's wrong with this code?
class SomethingRepresenter
  def represent(something)
    {
      foo: something.foo,
      bar: something.bar
    }
  end
endThe Representer
Decorator
design pattern that allows behavior to be added to an individual object without affecting the behavior of other objects from the same class
The Representer
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
endclass SomethingRepresenter < Representable::Decorator
  include Representable::JSON
  property :foo
  property :bar
end
SomethingRepresenter.new(something).to_jsonRepresenters
By Jan Dudulski
Representers
- 137
 
   
   
  