Yo, just a quick heads-up on some great new features in the recent representable release.

Options From The Outer World

Often you might need to “inject” objects into your representer, like the current_user or a parameter from that very request.

module SongRepresenter
  include Representable::JSON
 
  property :rating
end
 
class Song
  attr_accessor :current_user
 
  def rating
    current_user.rate(self)
  end
end

This was a bit clumsy as people first had to set an instance variable in the represented object and then call the rendering or parsing.

song.current_user = current_user
song.extend(SongRepresenter).to_json

Setting instance variables changes the state of the object which can lead to problems. Changing state is dangerous. It’s better to do it functional by passing around the values. That is why representable now allows you to pass an options hash into the render and parse method. Hooray.

song.to_json(current_user: current_user)

Now, to process this user when rendering we got the brand-new and long-awaited `:getter` option.

module SongRepresenter
  include Representable::JSON
 
  property :rating, getter: lambda { |opts| 
    opts[:current_user].rate(self) }
end

Given this option representable will no longer call the #rating reader but the block. The lambda is executed in the represented object’s context (song) allowing us to pass the song into the user’s #rate method. And the coolest: we get the user options from the outside as the block argument!

The same works for parsing using the :setter option!

property :rating, setter: lambda { |val, opts|
  opts[:current_user].rate_song(self, val) }

Here we get two block parameters: the actual parsed value for that property and the user options hash.

What Else?

The options are also passed to :if directives!

module SongRepresenter
  include Representable::JSON
 
  property :rating, if: lambda { |opts| 
    opts[:current_user].has_rating? }
end

An additional benefit: if you don’t want to write accessor methods for your properties, you can use :setter and :getter blocks even if you’re not interested in passing around user options.

property :rating, getter: lambda { |*| @rating.to_i }

And, naturally, the user options are passed down the object tree to nested properties. Cool stuff.

5 Responses to “Representable 1.3.3 Released With User Options Support!”


  1. Yacobus reinhart

    What about if I only want use presentation as object module only, just like a context in dci? Is it possible to use represented without call to_json, XML, YAML ?


  2. nick

    How would that look like, Yacobus?


  3. Ruprict

    So, is there a way to pass in current_user (or woteva) using represent_items_with?


  4. nick

    @Rubprict: Putting it on my TODO list! Good point!


  5. nick

Leave a Reply