To cut a long story short: Working on a nested form we decided not to go with nested_attributes. In fact, we wanted a form with validations, rendering and processing completely decoupled from the model. I mean, why would a form wanna know about the database layout?

So we, that is one of my lovely co-workers Garrett Heinlen and myself, came up with Reform – a framework-agnostic, anti-database form object.

What Does It Look Like?

Let’s assume for now our form was to create a song request for a radio station – for whatever reason this implies creating both a row in the songs and in the artists table. We use an ActiveRecord example here, however, reform is not database-dependent at all.

class SongRequestForm < Reform::Form
  include DSL
 
  property :title,  on: :song
  property :name,   on: :artist
 
  validates :name, :title, presence: true
end

As you can see, this is pretty straight-forward. Define the layout and throw in some validations.

What Is The Difference?

The form doesn’t know anything about your database. All you do is specifying what fields you want and where to map those. Also, note we’re using ActiveModel’s validations in the class and thus have per-form validations that don’t get in the way in our models.

For a better understanding, here’s how you would instantiate your reform.

@form = SongRequestForm.new(song:   Song.new, 
                             artist: Artist.new)

This would usually happen in your controller action.

Basically, from the key-object hash Reform will create a Composition object that simply delegates accessors to the underlying objects. How does it know how to do that? Well, you just defined it!

  property :title,  on: :song

Calls to #title or #title= will be delegated.

  @form.title #=> @form.song.title

Note that this doesn’t involve any database-magic – it is simple delegation based on your specification.

Rendering.

This simple trick makes it super-easy to use that form with Rails’ form helpers, simple_form or whatever form rendering you fancy.

= simple_form_for @form do |f|
 
  = f.input :name
  = f.input :title

I don’t cover the details here but the form object will even expose the necessary ActiveModel-compliant methods when you tell it to do so.

Processing Evil Input.

Now how do we update our form with incoming data, process it, validate it and display possible errors?

if @form.validate(params[:song_request])

The form comes with a #validate method which accepts a hash of data. Validations you defined will be run and form.errors will return potential errors from your confusing input.

Speaking of confusing: You no longer need attr_accessible or strong_parameters anymore. Why is that? Well, again, you defined the form layout earlier!!! Therefore, the form knows its fields and will simply ignore unsolicited input.

Another sweet feature is that the form will display the user’s input in the fields after a validation – without even touching your models.

@form.title => "Sunlit Nights" # from model.
@form.validate(title: "Scarified")
@form.title => "Scarified" # from user input.

Saving Safe Input.

When you decided that the input is alright you can let Reform save the data.

if @form.validate(title: "Scarified")
  @form.save # @form.song.title = "Scarified"

It will pass the incoming data to the respective models. This is nice, but often you want more control. That’s where a block to #save kicks in.

@form.save do |data, nested|
  data.title #=> "Scarified"
  nested[:song] #=> {title: "Scarified}

The block yields two handy arguments. The first data is a plain list of the incoming and validated data (currently implemented as an OpenStruct instance).

The second nested is a hash keyed following your mapping instructions from earlier – remember, the calls to ::property?

Makes it really easy to use ActiveRecord’s magic without the horror.

@form.save do |data, nested|
  Song.find(params[:id]).update(
    nested[:song]
  )

Why Another Form Object?

I read several blog posts that were really inspiring, however, they were either implementing a create form or an edit form, only. Also, we didn’t like the hard-core ActiveRecord wiring.

Reform gives you all the goodies like validation, parameter filtering and even rendering in a dedicated class. That keeps your UI logic where it should be. Hell yes, forms are part of your UI and shouldn’t be configured in your database models.

In addition to that, Reform gives you all the flexibility to change internals. If you don’t like the automatically created Composition object, use your own. If you don’t like the representable based mapper, make your own. It’s just 100 lines of code so far. Give it a try!

Until today, extend was the only way to inject a representer into a model to render or consume representations. Many people criticised this approach as it adds methods to an object which should rather be treated immutuable. Besides that, using extend seems to affect the performance due to caching invalidation.

song = Song.find(1)
song.extend(SongRepresenter).to_json

As a result, people who actually liked the representer idea declined using it because they were worried about extend. No longer should this keep you from using roar and representable!

Use Decorator Over Extend.

A minor refactoring brought us Representable::Decorator.

class SongRepresenter < Representable::Decorator
  include Representable::JSON
 
  property :title
  property :track
end

Instead of a module, derive a class that exposes the very same DSL that you know from the “old” module representers. BTW, you can also include representer modules into Decorator classes.

SongRepresenter.new(song).to_json

Just pass the represented object into the constructor and let representable do the work. Your models won’t get hurt anymore – promised!

Use the :decorator option where you used :extend in a nested setup.

class AlbumRepresenter < Representable::Decorator
  include Representable::JSON
 
  collection :songs, decorator: SongRepresenter
end

In roar, you might use the Roar::Decorator base class. Pretty cool: roar-rails already supports decorators.

Speed Is Relative.

Several on-going discussions debate whether heavy usage of extend slows down your app. I did a quick benchmark myself where I render an Album instance containing 10,000 Song instances which results in 10,000 calls to extend when rendering the album.

Album.new(songs: 10000.times.collect { Song.new }).
  extend(AlbumRepresenter).
  to_json

I did the same with a Decorator class.

alb = Album.new(songs: 10000.times.collect { Song.new })
AlbumDecorator.new(alb).to_json

Here are the results. I leave it up to you to judge these metrics.

# time with extend   : 0.780000
# time with decorate : 0.600000

It looks as if Decorator is faster – go figure! ;)

Using Decorator With Hypermedia.

There’s a tiny pitfall when using a decorator on a hypermedia-consuming object in roar.

class SongRepresenter < Roar::Decorator
  include Roar::Representer::JSON::HAL
  include Roar::Decorator::HypermediaConsumer
 
  property :title
  link(:self) { song_url(self }
end

Be sure to include the Roar::Decorator::HypermediaConsumer module which will propagate parsed links to the represented object by calling it’s link= writer. You have to provide that as well.

class Song
  attr_accessor :links
end

Now, consuming an incoming representation will set links on the client object.

SongRepresenter.new(song).from_json("..hypermedia json")
 
song.links[:self] #=> "http:songs/1"

Conclusion

Go and use decorators and tell us how you like it. Never shall anyone anymore complain about dirty extendings!

A recent release of representable made it very easy to pass user options like the current_user into the representer.

Basically, you can do things like

@song.to_json(current_user: current_user)

and use those dynamic user options in your representer.

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

See how you can inject data from outside?

User Options In Roar-Rails.

This now also works with roar-rails, too! Update to 0.0.13 and feel the ease of passing options to #respond_with.

class SongsController < ApplicationController
  def show
    respond_with @song, user: current_user
  end

As usual, this works both ways, for rendering and parsing. #consume! also accepts options now.

class SongsController < ApplicationController
  def create
    consume! Song.new, user: current_user
  end

Injecting dynamic runtime data into your representers is no longer a pain in roar-rails Several people already reported how useful this new feature is. Thanks!

Overriding Read And Write In Representable.

In representable 1.3.5 we got two new options :reader and :writer for overriding the compilation of the document and parsing a property from an incoming document.

Using the :writer option gives you access to the entire compiled document (e.g. a hash or a Nokogiri::Node). The lambda also has access to the user options, if there were any passed.

property :title, writer: lambda do |doc, args| 
  doc["title"] = title || original_title
end

As you can see it’s up to you as the lambda author to fill in the necessary fragments into the document – representable won’t do it for you when using the :writer option.

This is especially helpful when you need to decide the document key – like "title" – at runtime.

The same works for parsing using :reader!

property :title, reader: lambda do |doc, args| 
  self.title = doc["title"] || doc["name"]
end

Here, it’s your job to assign whatever property you extract from the incoming document. Useful when a property needs to be computed from different fields.

Those features were requested from users in the growing roar/representable community. Thanks for the feedback!

After decades of struggling with myself, and after a fantastic RubyConf Australia with lots of love I finally managed to give cells users support for a global (brrr) #content_for helper.

Using It.

The new helper is added by including the cells-capture gem into your Gemfile.

gem 'cells-capture'

Cells need to declare explicitly that they want #content_for to access the global buffer by including Cell::Rails::Capture. This is meant to remind users that they’re kinda breaking their encapsulation (although it feels handy, I admit).

class BassistCell < Cell::Rails
  include Cell::Rails::Capture
 
  def show
    render
  end
end

You can now use the helper in your views – it will append passed content to the global buffer.

%div
  - content_for :javascripts
    $('#pick').append("Yo!")

Now What Is Your Problem?

We want cells users to have maximum comfortability, that is why the new helper is here. However, there are two problems with this approach.

  • You’re changing state of a global variable from a well-encapsulated cell.
  • A cached cell will mess up the global as you expect the cell to append something but it actually doesn’t (remember, there’s a cache hit).

Especially the latter is a problem: Imagine you’re rendering a page with a cached cell: the JavaScript of this component will be lost as the #content_for block is never called! This is a well-known problem in traditional Rails views where people call #content_for in a #cache block.

A Way Out?

A more explicit way of collection JavaScript from view components could help.

render_cell(:bassist, :play) do |cell|
  content_for(:global_js, cell.js)
end

Here, instead of calling #content_for in the cell’s view, you dedicate an additional method to it responsible for rendering the JavaScript (or any other content).

class BassistCell < Cell::Rails
  cache :play
 
  def play
    render # usually, content_for happens here.
  end
 
  def js
    render # this could be a JS template
  end
end

The content of the #js view will be added to the :global_js buffer. The cool thing: It will be invoked even when #play is cached!

Anyway, let us know how you use it and enjoy.

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.

What Is Collection+JSON?

The Collection+JSON (Cj) specifies a hypermedia type for collections of items. It not only defines how single items or lists are represented in a document, it also comes with application semantics how to expose a standard CRUD behavior for items. In addition to that, embedded HATEOAS hyperlinks are one of the building blocks for this format.

And, hey, all that is done in lovely JSON!!!

Why not assume our music API would suddenly support the Cj media format? Here’s what I’d GET for http://songs/scarifice.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
 "collection" :
 {
  "version" : "1.0",
  "href" : "http://songs/",
  "items" :
  [
   {
    "href" : "http://songs/scarifice",
    "data" : [
     {"name": "title", "value": "Scarifice"},
     {"name": "band",  "value": "Racer X"}
    ],
    "links" : [
     {"rel": "band", "href": "http://bands/racer-x"}
    ]
   }
  ]
 }
}

The Cj format surprisingly always “speaks in” collections – even the single song is represented in a 1-item collection. The format provides a version, the hyperlink href to the collection itself, and the actual items we’re interested in (line 6).

Items in turn can have a href pointing to itself, properties of the represented object are found in the data attribute (line 10), and items may also contain additional links. Here, the song references the API endpoint of the band owning that very song (line 15).

Note that “real” collections have the same format, e.g. when grabbing http://songs the items array is be filled with millions of damn good song items.

Application Semantics Of Cj.

Apart from the standardization of representing lists this is nothing special so far. The cool thing about Cj is that it comes with specifications about the CRUD behavior of collections. Here’s an example.

If we were to create another song without knowing the API semantics we were helpless! Not with Cj! Here, a collection usually comes with a template telling us how to create or update particular items.

The template is embedded in the collection itself, in the document we were just talking about.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
 "collection" :
 {
  "version" : "1.0",
  "href" : "http://songs/",
  "items" : 
 ...
  "template" : {
   "data" : [
     {"name": "title", "value": ""},
     {"name": "band",  "value": ""}
   ]
  }
 }
}

Normally, you’d fill out a form and submit it to create something. That’s exactly what the template does – it acts like a form which is to be POSTed to the collection’s href URL. Remember, that was http://songs/ (line 5)?

The corresponding create request would be something like the following.

1
2
3
4
5
6
7
8
9
10
POST http://songs/
------------------
{
 "template" : {
  "data" : [
   {"name": "title", "value": "Parasite"},
   {"name": "band",  "value": "Frenzal Rhomb"}
  ]
 }
}

Cj comes with more, it contains a query specification for retrieving other collections, an error structure for exposing internal errors and more. I suggest you check out the examples the creator Mike Amundsen provides on his site.

Implementing Cj Services.

Too bad media formats only describe documents and how they might be used. It is still up to you to actually implement those. To make your life simpler the roar gem now comes with a Collection+JSON representer

By the time of writing this roar gives you a representer and a bit of added DSL sugar to render and parse collection representations. I won’t go into detail in this posting as the API is not 100% stable and we’re waiting for your comments. Here’s how a full-blown representer for the songs domain would look like.

module SongCollectionRepresenter
  include Roar::Representer::JSON::CollectionJSON
  version "1.0"
  href { "//songs/" }
 
  link(:feed) { "//songs/feed" }
 
  items(:class => Song) do
    href { "//songs/scarifice" }
 
    property :title, :prompt => "Song title"
    property :length, :prompt => "Song length"
 
    link(:download) { "//songs/scarifice.mp3" }
    link(:stats) { "//songs/scarifice/stats" }
  end
 
  template do
    property :title, :prompt => "Song title"
    property :length, :prompt => "Song length"
  end
 
  queries do
    link :search do
      {:href => "//search", :data => [
        {:name => "q", :value => ""}]}
    end
  end
end

The DSL should be pretty self-explaining. However, suggestions welcome! I tried to use as much roar/representable language as possible. Those guys already familiar with roar will recognize the property and link semantics for sure. Semantics. I love this word. Although I don’t understand its semantic.

Having defined the Cj representer you may now render and parse documents.

[Song.find(1)].
  extend(SongCollectionRepresenter).
  to_json

Note that the collection representer works with enumerable objects, like arrays, only.

Parsing an incoming document, e.g. in a client is just as simple as the rendering.

[].
  extend(SongCollectionRepresenter).
  from_json("{collection: ...")

Please, play around with it! Since Rubygems is only partially working you should go with the github master of roar. Have fun!

Recently I ran into an architectural problem when parsing XML with Nokogiri. I used an xpath to find child elements in a document. Coming to the conclusion that replacing that xpath #search with a self-baked #find_all would lead to a better design I set up a quick benchmark.

The XML contains a root node with 1000 empty childs.

<root>
  <item />
  <item />
  ... 998 times
</root>

This is the code I am using now.

Nokogiri::XML(xml).root.search("./item")

Note the usage of #search which evaluates the xpath expression and returns a list of matching nodes.

The replacement code comes here.

Nokogiri::XML(xml).root.children.find_all do |c|
  c.name == "item"
end

Instead of invoking the internal search I do it myself by querying each child.

Benchmarking time.

xpath:    0.003901151
find_all: 0.014400985

Going the “official” way by using an xpath is about 3.5 times faster! Wow.

It turns out that the manual comparison in find_all is the bottleneck. I guess Nokogiri has some internal optimization which saves the creation of the child nodes.

Nokogiri::XML(xml).root.children
 
children: 0.003361085

Takes about the same amount of time than the xpath search (without having filtered matching elements).

Here’s the benchmark code. I’ll keep going with the xpath search.

Time to catch up with some improvements in the representable gem and it’s bigger brother roar. Most of the work was done on the sunny island Fuerteventura in a surf camp *grin.

Readable And Writeable Properties.

To make it a little bit easier to provide assignment security we added :readable and :writeable switches to #property. Both are true per default.

I’ll use a song to demonstrate.

song = Song.new(:title => "You're Wrong", :track => 4)

For simplicity I’ll use the Hash representer. However, the following code works just fine with JSON, XML, and YAML.

module SongRepresenter
  include Representable::Hash
 
  property :title, :readable => false
  property :track
end

Since the title property is not readable – from an outer perspective – it is not serialized anymore.

song.extend(SongRepresenter).to_hash
#=> {"track"=>4}

Vice-versa, properties can be read-only, too.

module SongRepresenter
  include Representable::Hash
 
  property :title, :writeable => false
  property :track
end

The title property is now ignored when consuming (or parsing) a document as it is not writeable.

song = Song.new.extend(SongRepresenter)
song.from_hash({:title => "Fallout", :track => 1})
puts song #=> #<Song @track=1>

Those two switches allow a declarative access control for properties without having to override accessors. BTW, they also replace the mass-assignment problem and its poor successor strong_parameters in Rails.

Polymorphic Extend.

Finally, something fuckin’ awesome. Until today, representable allowed you to specify the representer modules for parsing and rendering using the :extend option.

  property :song, :extend => SongRepresenter

To make this dynamic, both :class and :extend now also accept a lambda to compute the class or module at runtime.

Let’s assume we not only have original songs but also cover songs.

class CoverSong < Song
end

Now we set up a composition where the Album instance contains one Song and one CoverSong instance.

songs = [
 Song.new(title: "Weirdo", track: 5),
 CoverSong.new(title: "Truth Hits Everybody", track: 6, 
    copyright: "The Police")
]
album = Album.new(name: "Incognito", songs: songs)

Note that the covered song also points to the amazing band that originally wrote this song.

Two simple representers are needed to properly represent those songs.

module SongRepresenter
  include Representable::Hash
 
  property :title
  property :track
end
 
module CoverSongRepresenter
  include Representable::Hash
  include SongRepresenter
 
  property :copyright
end

I am using inheritance here – yay!

The album representer needs to distinguish between the different song types. That is why I use a dynamic :extend here.

module AlbumRepresenter
  include Representable::Hash
 
  property :name
  collection :songs, :extend => lambda { |song| 
    song.is_a?(CoverSong) ? 
      CoverSongRepresenter : SongRepresenter }
end

Check out what we get when calling the rendering.

album.extend(AlbumRepresenter).to_hash
#=> {"name"=>"INCOGNITO", "songs"=>[
 {"title"=>"Weirdo", "track"=>5}, 
 {"title"=>"Truth Hits Everybody", "track"=>6, 
  "copyright"=>"The Police"}]}

Representable uses the respective representer module depending on the type of the object passed in. It is important to understand that :extend works both ways and always receives a valid object into the lambda block.

  • When rendering, the object bound to the property (or collection) is extended using the provided module.
  • However, when parsing, representable uses the class from :class, instantiates a brand-new object, passes this into the block and then extends it.

Speaking about :class brings us to the next feature!

Dynamic Class Block For Parsing.

Now what if you need to compute the object’s class at runtime when parsing? Well, use a lambda!

module AlbumRepresenter
 include Representable::Hash
 
 property :name
 collection :songs, 
  :extend => lambda{ |song| ...,
  :class  => lambda{ |hsh| hsh.has_key?("copyright") ?
    CoverSong : Song }
end

The dynamic :class lambda allows you to decide the class right when you’re parsing the document. If you wonder how the hsh argument looks like, this would be something like

hsh #=> {"title"=>"Weirdo", "track"=>5}

Never ever complain about missing polymorphism in representable any more! Ha!

MORE! Dynamic Object Creation For Parsing!

No, I’m not finished, yet! When working on roar and its HAL feature we encountered the problem that we needed to override the object creation when parsing – in an easy way. And here comes :instance.

1
2
3
4
5
6
7
8
9
10
11
12
module AlbumRepresenter
  include Representable::Hash
 
  property :name
  collection :songs, 
    :extend   => lambda { |song| ... },
    :instance => lambda do |hsh| 
      hsh.has_key?("copyright") ? 
        CoverSong.new : 
        Song.new(original: true)
    end
end

Instead of providing a class with the :class option, I create the song instances myself using :instance. The returned value from the block will be extended and passed into the deserialize workflow where representable will call something like from_hash on it.

Note how I assign additional data for the Song object which will survive the parsing (line 10).

Isn’t that fantastic? The dynamic lambdas for :extend, :class and :instance allow you to have simple polymorphic representations without the pain of overriding representable’s internals.

BTW: all lambda blocks are executed in the represented instance context – which is the Song object here.

Last But Not Least: HAL Link Arrays In Roar.

This might sound funny, but we wrote all that in order to provide a 100% complete implementation of the HAL/JSON standard, a cool universal media format for RESTful APIs.

What was missing was support for arrays of links in HAL. Here’s an example of what people wanted.

{"_links":{
 "next":{"href":"http://next"}, 
 "self":[{"lang":"en","href":"http://en.hit"},
         {"lang":"de","href":"http://de.hit"}]
}}

For some strange reasons I still don’t understand why the HAL standard allows having “single links” (no girlfriend) and arrays of links. I am sure Mike Kelly himself will soon explain why we need this – however, here is how roar handles this since 0.11.5.

module SongRepresenter
  include Roar::Representer::JSON::HAL
 
  link :next do
    "http://next"
  end
 
  links :self do
    [{:lang => "en", :href => "http://en.hit"}, 
     {:lang => "de", :href => "http://de.hit"}]
  end
end

You can see, we still handle “single links” with the ::link class method. Arrays of links can be specified using the new ::links method which receives the rel attribute and a block. The block should return an array of link attribute hashes.

As always, that works for rendering and parsing. Be careful when you work with a link array.

song.from_json(..)
song.links[:next] #=> #<Hyperlink>
song.links[:self] #=> [#<Hyperlink>, #<Hyperlink>]

Links defined with ::links will naturally contain an array of Hyperlink instances after parsing. Does that help you, guys?

More To Come.

That was quite some work. And there’s more coming. Let me know if anything could be improved or added. But now it’s time for a surf. Keep it real!

The tiny representable gem got some improvements recently. Not only did we refactor the internals to make it easier adding new representation engines, we also used that to give you a new format: YAML!

YAML, Who Needs YAML?

I use YAML very rarely. But sometimes clients happen to require it, or an API might be based on this format. Let’s make the world a better place and support it in representable!

Consider the following domain class.

require 'ostruct'
class Song < OpenStruct
end
 
song = Song.new(:title => "Scarified", :track => 4)

To render this into YAML a simple representer is needed.

module SongRepresenter
  include Representable::YAML
 
  property :title
  property :track
end

Note the usage of the Representable::YAML module. After injecting, the domain object is fully equipped with #to_yaml and #from_yaml.

puts song.extend(SongRepresenter).to_yaml
 
# => "
---
title: Scarified
track: 4"

As always, this works also with parsing.

song = Song.new.extend(SongRepresenter)
song.from_yaml("---
title: Jackhammer
track: 5
")
 
puts song.inspect
 
#=> #<Song title="Jackhammer", track=5>

Nested Models? Not A Big Deal.

Often you may want to represent nested setups – where models contain models. This has always been a key feature in representable.

class Album < OpenStruct
end
 
module AlbumRepresenter
  include Representable::YAML
 
  property :name
  collection :songs, :extend => SongRepresenter, 
                      :class  => Song
end

Since an Album contains a list of Songs we wanna represent those embedded objects with the SongRepresenter we already wrote.

Seting up a demo album, first.

album = Album.new(:songs => [
  Song.new(:title => "Scarified",  :track => 4),
  Song.new(:title => "Jackhammer", :track => 5)
])

The YAML representer will now create a proper YAML document for the nested objects.

album.extend(AlbumRepresenter).to_yaml
#=>
"---
songs:
- title: Scarified
  track: 4
- title: Jackhammer
  track: 5"

See how easy that is?

And Finally: Flow-Style Lists.

Another cool feature is the ability to declare collections as flow-style which is an official part of the YAML specification but only very poorly implemented in available YAML gems.

Usually, lists are rendered in the block style.

class HotBands < OpenStruct
end
 
module HotBandsRepresenter
  include Representable::YAML
 
  property :for
  collection :names
end

After creating and rendering one of those HotBands, the names list is rendered in block style – the default in all YAML gems.

HotBands.new(:for => "Nick", :names => [
  "Bad Religion", 
  "Van Halen", 
  "Mozart"
]).extend(HotBandsRepresenter).to_yaml
 
#=> 
"---
for: Nick
names:
- Bad Religion
- Van Halen
- Mozart"

Now, if you don’t like that style where one list item is displayed per line, you might want to switch to the oh-so-flowing flow style.

module HotBandsRepresenter
  include Representable::YAML
 
  property :for
  collection :names, :style => :flow
end

By using the :style => :flow option in the collection you can achieve just that!

hotties.to_yaml
#=> 
"---
for: Nick
names: [Bad Religion, Van Halen, Mozart]"

Check how it flows. That is just awesome.

Introducing The Hash Representer.

We did a little bit of internal refactorings cleaning up representable. What came out is the new hash representer which gives basic functionality to most of the other representer engines. It can also be helpful if you want to parse incoming form data or use the params hash from Rails or Sinatra to fill your objects.

Consider this representer.

require 'representable/hash'
module BandRepresenter
  include Representable::Hash
 
  property :name
  property :label
end

This representer can read and write plain Ruby hashes. Sounds stupid? It is! However, what if you wanna use Rails’ params hash to update a model?

params = {"band" => 
  {"name" => "Paul Gilbert", "label" => "n/a"}}

This could be a form Rails (or Sinatra) automatically parsed for you. Now let’s use that on a new Band instance.

band = Band.new.extend(BandRepresenter).
  from_hash(params["band"])

Note that this could be an existing Band instance, too, as from Band.find(params[:id]).

Inspecting the result of our “parsing” we see that it actually works.

band.inspect
#=> #<Band name="Paul Gilbert", label="n/a">

This new hash representer is especially helpful for using representers with forms.

One Module, Multiple Representers

Another nice little cleanup lets you include different representer engines into a single module, so you can transform to and from different media types.

module BandRepresenter
  include Representable::JSON
  include Representable::XML

This would give your objects the power of both XML and JSON.

More To Come.

In the next release we’re planning readable/writeable policy support, polymorphic collections, letting you pass arguments to the represented accessors if you need that and more stuff I already forgot. Let us know if you need anything more, and ┬íSalud!

You are following the “Fat Models, Skinny Controller” pattern in Rails. Your controllers being the HTTP endpoints are nice and clean. Short action methods and brief assignments. However, your models keep growing and growing, you are losing track of its responsibilities and you are trying to figure out why.

That is a problem. Rails makes you push all your domain code into the persistance layer. Avoiding the oh so dreaded “over-abstraction”, bloating a handful of ActiveRecord classes seems to be a better strategy. Also, the idea of three – and only three – possible places for your business logic makes it easy to justify the growing model: Controllers must be “skinny” and views shouldn’t contain logic, so… if not pushing into the “model”, where else should I put it?

To make it short: Stop thinking in database tables and relations and start modeling your domain with dedicated classes and instances – that is what object-orientation was made for!

What Is My Domain?

If your concern is “I want to export a series of chat messages to a JSON document” then write a new class MessagesDocument. That is your domain. That is the problem you as the programmer are supposed to solve. So do it.

class MessagesDocument
  def to_json(messages)
    messages.collect do |msg|
      msg.to_json
    end.to_json
  end
end

We all know that this simple example will soon get bloated with code lines since we want a little message filter here and a special formatting method for dates there. So, why would you put all this logic into the Message class? It has nothing to do with your message domain at all. And, no, this ain’t no over-engineering, this reflects your concern of compiling a document.

— UPDATE: There was some discussion whether “compiling JSON” is part of “the” domain or not. Well, let’s presume we’re designing a document management tool for librarians (very interesting people, BTW!). In order to send archived files to other systems, one feature is an exporter to serialize documents to JSON – then this component is surely part of your domain.

And, The Persistance Layer?

Strictly speaking, your Message class should be responsible only for synchronizing the model instance with the corresponding row in the database. It is a persistance layer. And this layer should be free of business code. I know, it is handy to simply push in a formatter method for the created_at field – at the cost of an ever-growing class, thou. Think about it. How many methods could you move to dedicated new classes since those behaviours don’t need persistance?

But Isn’t That Over-Engineered?

If Rails and its legendary “model” layer would be good practice, I wouldn’t see dozens of projects all over the world with model files having 600 LOC each, including programmers complaining about too many responsibilites in their classes, starring at me, eyes wide open, blearily, asking where to put all that code. Rails does allow you additional assets, but the framework itself doesn’t answer those questions.

Your fat models are killing your software design. Do you know how hard it is to figure out the concern of a set of methods in a fat class? Of course you do! So why don’t you just generously push a set of logically associated methods into its own class? If that hurts too much you can still move it back into your all-mighty “model”.

What Do We Get From That?

Please don’t get me wrong – I don’t tell you to perfectly abstract your code “Java-like” (hate that comparison) into twohundredseventyfive classes. Relax, and refactor your code step by step. Parts that do not necessarily need the persistance should be separated. You will keep track of what happens where more easily with your refactorings and have faster tests that might encourage you to assert more edge cases.

In addition, that process makes you think about interfaces – the interaction of your new classes with your existing models. Interfaces are a good thing. Don’t fear the class. Hopefully, the next posts in this series can help. I want to talk about mass-assignment problems, lifecycle callbacks in ActiveRecord, form objects, and a lot more including ways to do that practically.

Several speakers were talking about the same problem: Unbloat your models in Rails and focus on your domain instead. “There’s something in the water.” – that was the conclusion of the LoneStar RubyConf 2012 last weekend, a fantastic conference in beautiful Austin, TX with even more fantastic people.