Yo! How’s it folks? Let’s do some more REST today. I’d like to show how easy it is to have paginated REST documents with Roar while using a nifty feature introduced in version 0.10.2.

What’s In That Fruit Salad, Sir?

Since we keep having fruit salads in the last posts I wanna write a service to display the ingredients of a particular fruit bowl in a list. Not just a list of fruits, a paginated list of fruits.

Let’s GET it.

POST http://bowls/1/fruits?page=1

Considering two fruit items per page this document will be returned.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{"total_entries":5,
 "links":[
  {"rel": "self",
   "href":"http://bowls/1/fruits?page=1"},
  {"rel": "next",
   "href":"http://bowls/1/fruits?page=2"}],
 "items":[
  {"title":"Apple",
   "links":[{"rel":"self",
              "href":"http://fruits/Apple"}]},
  {"title":"Orange",
   "links":[{"rel":"self",
             "href":"http://fruits/Orange"}]}
  ]
}

Ignore the items for now, the interesting part here are the pagination elements in the first lines. What we have here is:

  • The number of total ingredients in the bowl (line 1).
  • The obligatory self link (line 3-4).
  • A link guiding us to the next page (line 5-6).

Wow! Code?

The backing code in this service endpoint could look like the following snippet. As always, the code used to create this example can be found on github.

1
2
3
4
5
6
bowl = Bowl.find(1)
page = bowl.fruits.paginate(:page => 1, 
  :per_page => 2)
 
page.extend(BowlPageRepresenter)
page.to_json(:bowl => @bowl)

First task is to retrieve the viewed bowl (line 1). I use a static id in this example, feel free to replace it with something like params[:id] in your code. Next, I use paginate from the famous will_paginate gem to get a paged subset of the included fruits. Again, the :page parameter should be refering to a variable, whatever (line 2-3).

Then I simply extend the collection (line 5) since it is a valid Ruby object and call to_json to render the list (line 6). Keep in mind that we pass the :bowl instance into the render method as an argument.

The Bowl Representer Can Do Pagination

To fully understand that example we need to look at the representer now.

module BowlPageRepresenter
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Hypermedia
 
  property :total_entries
  collection :items, :extend => FruitRepresenter
 
  link :self do |opts|
    bowl_url(opts[:bowl], :page => current_page)
  end
 
  link :next do |opts|
    bowl_url(opts[:bowl], :page => next_page) \
      if next_page
  end
 
  link :previous do |opts|
    bowl_url(opts[:bowl], :page => previous_page) \
      if previous_page
  end
 
  def items
    self
  end
end

Instead of refering to line number I’ll use code excerpts now. Do you like that better?

  property :total_entries

In a paginated collection we got the total_entries method as described in the will_paginate API docs. To give our REST consumer a hint about the total amount of ingredients we can simply define a property after that.

  collection :items, :extend => FruitRepresenter

To render the actual items in the doc we extend each fruit with the FruitRepresenter as we learned in an older post. Note that Roar will use the items method to retrieve the collection of fruits.

  def items
    self
  end

Since we are already a collection all we have to do is return self – roar will iterate the paginated collection, extend each element with the FruitRepresenter and render the items.

A Cool New Feature!

The links to the next pages are defined using Roar’s hypermedia feature.

  link :next do |opts|
    bowl_url(opts[:bowl], :page => next_page) \
      if next_page
  end

Two things happen here. First, note that this link is conditional. If next_page, another API method for a will_paginate collection, is evaluated to false, this link won’t be rendered.

Second, we use a new feature of Roar here to access variables passed into to_json. Remember how we called the render method?

page.to_json(:bowl => @bowl)

Right, we pass in some values from the outside since we don’t have access to the actual bowl instance within the represented collection. These parameters are accessible in the link block parameters. Isn’t that nice? I like it.

These few lines of code make it easy to render a paginated collection into a valid REST document.

Writing A Generic Pagination Representer

Now that all paginated documents share attributes (total entries, next and previous link, the self link, etc) why not abstract that into a generic representer? Most of the code can be reused.

module PaginationRepresenter
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Hypermedia
 
  property :total_entries
 
  link :self do |opts|
    page_url(opts[:model], :page => current_page)
  end
 
  link :next do |opts|
    page_url(opts[:model], :page => next_page) \
      if next_page
  end
 
  link :previous do |opts|
    page_url(opts[:model], :page => previous_page) \
      if previous_page
  end
 
  def items
    self
  end
 
  def page_url(*)
    raise "Implement me."
  end
end

All I did was calling a generic page_url method that must be implemented by the using representer. Also, I no longer use the :bowl keyword but a more generic :model, ok?

Nothing in this abstract representer module is related to stinky fruit salads anymore. Man, this thing could even represent a sixpack of beers (a domain I do prefer over fruits).

To inherit we just include the abstract into the concrete representer.

module BowlPageRepresenter
  include Roar::Representer::JSON
  include PaginationRepresenter
 
  collection :items, :extend => FruitRepresenter
 
  def page_url(*args)
    bowl_url(*args)
  end
end

That is cool. All we have to do is defining the concrete items collection and how to compute the pagination URLs. Come on guys, that is easy!

Remember, we changed the incoming parameter, so the rendering call must change, too.

page.to_json(:model => @bowl)

Cheers!

It is Friday eve, have a wonderful weekend and let me know how it was!

Have you ever heard of coercion? Me neither. Anyway, people kept asking for coercion support in roar so I found out that coercion means converting strings into ruby types. Tireless I added a new feature with a whopping 3 lines of code – the cool thing is that this module marries roar with a nifty coercion gem called virtus by my good friend Piotr Solnica.

All you have to do is using the latest roar release (0.10.1), use the appropriate feature and the :type option.

class ImmigrantSong
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Coercion
 
  property :composed_at, :type => DateTime, 
    :default => "May 12th, 2012"
end

This will automatically convert the composed_at property to a decent DateTime object when parsing a document. Note the working :default option, too!

document = "{\"composed_at\":\"November 18th, 1983\"}"
song = ImmigrantSong.new.from_json(document)
song.composed_at #=> 1983-11-18T00:00:00+00:00

The underlying virtus gem takes care of all the conversion work. Note that virtus also automatically adds accessors to the class.

First World Problems

A caveat is that this currently works with inline representers in classes, only. This is cause virtus doesn’t work within modules, yet. I guess we can expect a refactored virtus within days, right, solnic? As soon as this is working in virtus, you can savely use the conversion feature in modules, too. I keep you in the loop!

Oh, I forgot to thank Alex Coles who made me aware of the simplicity of combining those two gems!

A number of users (hundreds, maybe thousands) have been asking why representers are called representers and not “representations”. It is a valid question and since I spent decades to come up with this term I’d like to discuss the decision here quickly.

What Is A Representation?

A representation in the REST style – and this is what we’re talking about here – is a document describing a resource. Actually, it is illustrating the current state of that resource, usually with property/value lists, embedded resources and pointers to other resources using hypermedia. The format is not relevant in this context, it could be JSON, HTML or the accursed XML.

It is a document you can pull on your hard disk, save it and pop it out on christmas again. Did I mention that I’m writing this post in a cafe facing the beach with a cold Castle in my hand, blinded by the sun and intrigued to jump back into the waves?

What Is A Representer?

Now, on the other side, we have the representers as introduced by the roar gem. Those guys are Ruby code and out in the wild you might find them written as modules, mostly. A representer may look like the following beautiful snippet.

module FruitRepresenter
  include Roar::Representer::JSON
 
  property :title
 
  link :self do
    fruit_url(self)
  end
end

In short, injected into an object that very instance gets capable of rendering a document from its current state and updating its attributes by parsing a document – following the syntax definition from the representer module.

Isn’t That A Presenter?

Ok. A representer module enhances an object by enriching it with new methods. Isn’t that a presenter, that’s what Jason wants to know.

The idea seems interesting, but I’m confused as to how this is different from a traditional presenter or decorator?

What I learnt from the tech panel OOP vs. Rails at the fantastic Wroclove.rb conference – if I listened to Steve Klabnik correctly – is

  • Decorator is a pattern that adds methods and optional state to an object. If I write a module introducing currency conversion methods into a float object it’s a Decorator.
  • Presenter seems to be a subset of Decorator which adds functionality for, well, presenting the object. That could be an ActiveRecord row instance extended with methods to serialize to JSON.

Steve, is that true?

So why is a representer not a presenter? Well, the answer is: it is a presenter, but it is more. The rendering behaviour as found in e.g. to_json in the representer is clearly presentation logic. However, the parsing mechanics are definitely beyond the scope of a Presenter. I agree that a representer still is a Decorator (adding functionality, great).

Why Isn’t It Called Representation?

People are worried about the “ter” ending (as in Terminater). Scott got justified concerns that choosing “representer” as opposed to “representation” has roots in my Ruby hipster attitude.

So, if “Representer” is a reflection of the popularity of “Presenter”,it would seem to be an example of throwing good money after bad. If “Presenter” is already somewhat tainted with inaccuracy, then so would “Representer”.

In an email he is refering to that confusion caused by the Presenter pattern name in the Ruby community (just google presenter + ruby if you can’t follow now). So his proposal

The Fruit class is a “Representation”, not a representer.

Oh no, call it representation!

And as if that wasn’t enough critics on MY pattern name, Charles Lowell, author of rubyracer, saviour of the poor and knight of the dark, reinforces the representation argument.

personally I prefer FooRepresentation as opposed to FooRepresenter, but that’s just me. It implies that “this defines what the representation is“, as opposed to “This defines is how the representation is generated”

That sounds conclusive to me and lead me to reflecting the terms once again.

Now What, Representer or Representation?

So, maybe the the concrete representation declaration (the module using roar and defining properties and hyperlinks) is a representation whereas the underlying abstracted module is a representer?

I speaking for myself still prefer the name representer as we not only define syntax and semantic of a representational document but also add functionality to the represented object as it gets enriched with e.g. to_json and from_json. That as-it makes the FruitRepresenter module “active” and justifies the “ter” ending, just as in “Terminater”, ok?

Just a quick round-up for new things in the Roar world. Here we go!

Roar Speaks JSON-HAL Now!

In the last Ruby on REST post I explained the basics of the hypermedia type HAL which gives your document nesting and linking semantics. This promising format is now supported by Roar.

By including the Representer::JSON::HAL module in your representer it will render and parse documents according to the HAL standard.

module OrderRepresenter
  include Roar::Representer::JSON::HAL
 
  property :id
  collection :items,
    :class => Item, 
    :extend => ItemRepresenter,
    :embedded => true
 
  link :self do "http://orders/#{id}" end
end

Links will now be pushed into the _links property. Also note the new :embedded option which will key the nested property under _embedded. And all that just by including a module – that’s the power of representers.

Better Links in JSON

Some users asked for another link format when not using the HAL representer. Usually links are handled like this.

"links":[
  { "rel":  "self", 
    "href": "http://orders/42"},
  { "rel":  "items", 
    "href": "http://orders/42/items"}
]}

This is just a format I came up with when writing Roar. Now, if you include Representer::JSON::HAL::Links in your representer, links will be rendered and parsed a bit different.

"links": { 
  "self":  {"href": "http://orders/42"}, 
  "items": {"href": "http://orders/42/items"}
}

Here, links is a hash keyed by rel – very handy on the client side.

Also, you can now include more attributes in links.

link :rel => :self, :title => "That's me!"

Just provide a hash listing the attributes.

Representable Got Conditional Properties!

Last but not least, representable, the underlying mapping gem of Roar got a new option in the 1.1.6 release. :if allows you to define blocks that are evaled when parsing or rendering (“representing”, yo!) the object. If the proc returns false, the property is ignored.

property :state, :if => lambda { authorized? }

The block is executed in instance context allowing you to access instance methods and whatever else you need. Go for it!

Let me start this post by quoting something smart.

REST [is an] architectural style for distributed hypermedia systems”

That actually is the first line, chapter 5 of Roy Fielding’s thesis about REST. I gave a couple of talks last year about hypermedia and the misunderstandings in REST in the Rails world and this post tries to sum up with that by focusing on the hypermedia aspect of this architectural concept.

Challenge: Make Fruit Salad!

In the last posts we discussed using the Roar gem for designing and implementing REST systems in Ruby. We were using fruits and bowls as an exemplary domain – let’s keep up with that and fix a fruit salad today.

As a first step it makes sense getting a bowl for all the ingredients. In our REST system, we just POST to the bowls URL.

POST http://bowls
Content-type: application/json
------------------------------
{"location": "desk"}

The request body contains a minimal document specifying the location for the created bowl. Here’s what we get back.

{"location":"desk",
 "fruits":[],
 "links":[
  {"rel":"self",  "href":"http://bowls/desk"},
  {"rel":"fruits","href":"http://bowls/desk/fruits"}
]}

By reading this I figure out that the bowl on my desk was created, but doesn’t contain any fruits, yet. Also, these “links” seem understandable, while self might point to the bowl resource itself the fruits link probably directs to a collection resource listing all the ingredients in that very bowl.

Looks as if a URL gets a “meaning” by specifying a rel attribute with it.

I infered all that by intuition, as JSON is a pretty simple representation format. And this is the first problem when trying to understand hypermedia. JSON as it doesn’t include any semantics, the links are, well, useless as they’re not understandable to machines. What we need is a hyper-media type. Get it on!

What Is A Media Type, Sir?

A concept called media type gives both syntax and semantics to a document. It is important to understand that a simple media type like JSON doesn’t define anything. It just provides a medium (or format) to encode information.

Why not put it that way: JSON and XML are like primitive communication mechanics. Where XML uses smoke signals for exchanging messages, JSON is human voice. A poor example.

However, listening to my voice doesn’t mean you understand what I’m saying. Reading JSON is like listening to my sounds, but the noize might not make sense to you. Ok?

The media type is like a language. You understanding the media type “english” and me speaking (JSON) in english (media type) makes us happy chatters. And suddenly, a series of sounds turn into “Would you like another beer?”. You understand me since you know the syntax and the semantics of my sounds. That is a media type!

Now That We Understand Hypermedia, What To Do With It?

Instead of using plain, dumb JSON I’d like to introduce a real hypermedia format called HAL which is “specifically for exposing RESTful hypermedia APIs”.

POST http://bowls
Content-type: application/hal+json
------------------------------
{"location": "desk"}

Note that we used the application/hal+json content type desparately hoping the web service understands this media format. Check the response.

{"location":"desk",
 "_embedded":{"fruits":[]},
 "_links":{
  "self":  {"href":"http://bowls/desk"},
  "fruits":{"href":"http://bowls/desk/fruits"}
}}

It obviously does, and now the links are encoded a little bit different, following the HAL standard. While this doesn’t make a real difference for you human being, it changes a lot in machine context. By using this media format, we added semantics: Now, the HAL-aware client knows that links can be found at the _links key, that they’re keyed by rel and so on.

Think about it briefly. Growing up with human voice you understood JSON before. However, now that you learned HAL, you understand all the bits and pieces in the document just by applying the specification rules.

I’m Still Hungry!

Sorry for that detailed discussion about hypermedia types, I’m really getting hungry as well, so let’s add some fruits to the bowl.

POST http://bowls/desk/fruits
Content-type: application/hal+json
------------------------------
{"title": "Apple"}

An apple a day keeps the doctor away. Assuming it is sufficient to post this mini JSON document to the fruits URL I add an apple to my salad. Did that work?

GET http://bowls/desk
Content-type: application/hal+json
------------------------------
{"location":"desk",
 "_embedded":{
  "fruits":[
   {"title":"Apple",
    "colors":[],
    "_links":{"self":{"href":"http://fruits/apple"}}
  }]  
 "_links":{
  "self":  {"href":"http://bowls/desk"},
  "fruits":{"href":"http://bowls/desk/fruits"}}
}

Yeah! I can see an apple inside the _embedded key, which is HAL’s way to nest resources in representations. Also, the apple contains a link again pointing to its resource.

It is needless to note that I could go on like this and POST more fruits to the fruits collection resource in order to enrich my delicious salad.

What Did I Just Do?

This brief example was brief. Nevertheless, it demonstrated the use of hypermedia. Here’s what I did.

  1. First, I POSTed to http://bowls to create a bowl.
  2. The returned document points me to its fruits resource.
  3. To add fruits, I POST to http://bowls/desk/fruits as defined in the representation.
  4. I retrieve the updated bowl by following the self URL of the bowl.

Well, what’s so special about that?

The key is, I didn’t compute any URL except the initial URL in (1.) – this is what we call the single entry point. No knowledge about follow-up URLs was needed to operate my fruit salad API. Everything I need to know is included in the representations.

Actions (aka URLs) that are meaningful in the current application state can be found in the document without any need to build URLs myself. This concept is called HATEOAS – a beautiful name… for a cat.

Thou Shall Not Make Any Fruit Salad Without Hypermedia!

Roy Fielding, the inventor of REST, states that your API is RESTFUL if and only if it is hypermedia-driven! In my words, that’ll mean no URL code should be hard-wired into your REST client – except for the single entry point URL. Any additional resource must be extracted from returned documents. And, hey, this is the very reason why REST is defined as a style for “distributed hypermedia systems”.

How that works with the Roar gem is subject to discussion in my upcoming next post! Stay tuned and enjoy life!

Do you remember when we were writing a reusable sidebar element some time ago? The sidebar used in many controllers was implemented using a cell which encapsulated both assets and code in one place. Those were good times.

When needed, we could render the box with a render_cell call anywhere in our app.

#sidebar
  = render_cell :posts, :recent

Reusability With Engines

Now, imagine this sidebar box was so universally usable that you wanna use it in another project. Code is usually distributed with gems in a Ruby environment – but how does that work with partials, helpers, view code?

We got engines in Rails. We got Cells. We got gems. So let’s pack the cell in an engine gem!

Engines were designed to distribute controllers, views and models between Rails projects. As an example, lots of the authorization gems around use engines for reusable login pages or password reset forms that can be used right in your project. There was no easy way for reusing partials and behaviour, though, unless you’re using cells.

The Cell, Gemified.

In order to ship the sidebar posts box I first need to create a Rails engine.

$ rails plugin new sidebar --mountable

This creates a distributable directory with all the files needed to mount it into a Rails app.

As a second step we need to move the PostsCell into that gem.

$ mv app/cells/posts sidebar/app/cells/

You can now include the sidebar gem in any application using the Gemfile.

gem 'sidebar', :path => 'vendor/plugins/sidebar'

To render your reusable component, just use the render_cell call as you did in the originating application.

Conclusion

Damn, this conclusion came fast, but there is really not more to say. Oh, did I mention that you should update to Cells 3.8.3 for full engines support in Rails 3.0, 3.1 and even 3.2?!

Cells + Engines bring real reusability to Rails. It’s da shit.

It has been a while since I blogged about Roar and it’s representers – beautiful South Africa kept me from doing my homework. Nevertheless, in the meantime, the new roar-rails gem emerged bringing together Rails and Roar in a very easy going way. I’d like to describe how this gem works by implementing a fruit and fruit bowl backend service following the examples from the last posts.

Oh, and before I forget mentioning, the Rails example app is available on github where I will keep adding examples from the Ruby On REST blog series.

Setting It Up…

To make things happen it is necessary adding the roar-rails gem to your Gemfile.

gem 'roar-rails'

As we wanna use Rails’ URL helpers in our representers we have to add one line to the environment.

  config.representer.default_url_options = 
    {:host => "yum.my"}

Rendering Fruits, Done Right.

For simplicity let’s assume our Fruit model has the following underlying, highly complex database scheme.

  create_table "fruits" do |t|
    t.string   "title"
  end

Tough stuff, isn’t it?

Clients might want to retrieve fruit representations, that’s why we start with a functional test for handling GET requests on the FruitsController.

class FruitsControllerTest < ActionController::TestCase
  include Roar::Rails::TestCase
 
  test "GET returns fruit document" do
    get :show, :id => 1, :format => :json
    assert_body "{\"title\":\"Apple\",\"links\":[
      {\"rel\":\"self\",
       \"href\":\"http://yum.my/fruits/Apple\"}]}"
  end

Including the Roar::Rails::TestCase module into the test gives us a couple of new or changed methods. One of those is assert_body and all it does it testing equality of the passed string and the last returned document. This test verifies our REST representations are rendered correctly.

Here’s the handling code in the FruitsController.

class FruitsController < ApplicationController
  include Roar::Rails::ControllerAdditions
  respond_to :json
 
  def show
    fruit = Fruit.find_by_id(params[:id])
    respond_with fruit
  end

This is all very familiar code! But, wait… what happens here behind the scenes? The inclusion of the ControllerAdditions module activates a new responder which will take care of the JSON-rendering that is invoked inside respond_with. So, behind the curtain, the following is executed.

fruit.
  extend(FruitRepresenter).
  to_json

The roar-rails gem infers the representer name used for rendering.

The Fruit Representer

Now, where is that representer? It lives in the app/representers directory and its implementation is quite simple.

module FruitRepresenter
  include Roar::Representer::JSON
 
  property :title
 
  link :self do
    fruit_url(title)
  end
end

All it does is defining the title property and the self link. Please note that we can simply use URL helpers here, making it pretty easy to include hypermedia in our representations.

Amazing! This is all the code needed for rendering fruit documents, including hot hypermedia and handling GET requests. Now, what do we need to consume incoming documents, in, let’s say a POST request?

Eat More Fruits!

To create new fruits in our backend service we’d need to accept POST requests. Test it.

class FruitsControllerTest < ActionController::TestCase
  # ...
 
  test "POST creates fruit" do
    post :create, "{\"title\":\"Orange\"}", 
      :format => :json
 
    assert_body "{\"title\":\"Orange\",\"links\":[
      {\"rel\":\"self\",
      \"href\":\"http://yum.my/fruits/Orange\"}]}"
  end

Again, we use assert_body to assure the resource returns the freshly created representation of the orange. Now, check the post: The second argument is the actual JSON document sent by the client. This is an API change. We no longer pass hashes to the “POST”, but use real documents to test our services.

The consuming controller action is hilariously simple as well.

class FruitsController < ApplicationController
  # ...
  def create
    fruit = Fruit.new.
      extend(FruitRepresenter).
      from_json(request.body.string).
      save
 
    respond_with fruit
  end

It creates a new Fruit instance, mixes in the respective representer, parses the incoming JSON document and updates the fruit’s attributes in the #from_json method and then renders the created model.

In the upcoming version of roar-rails, this code can also be written like:

class FruitsController < ApplicationController
  # ...
  def create
    fruit = consume(Fruit).
      save
 
    respond_with fruit
  end

The consume method provided by roar-rails is still under discussion – feel free to add comments to this post if you have a groundbreaking idea how to simplify the consumption steps!

Fruits On This Planet – Unite!

If that was to easy for you, and I bet it was, why not implement the fruit bowl as well. Consider this model class.

class Bowl < ActiveRecord::Base
  has_and_belongs_to_many :fruits
end

Instead of wasting time with the rendering test and parsing code – which is identical to the fruit code – we jump directly into the parsing test.

class BowlsControllerTest < ActionController::TestCase
  include Roar::Rails::TestCase
 
  test "POST creates bowl with fruits" do
    post :create, 
      "{\"fruits\":[{\"title\":\"Orange\"}]}", 
      :format => :json
 
    bowl = Bowl.find(:last)
    assert_body "{\"fruits\":[
      {\"title\":\"Orange\",\"links\":[
        {\"rel\":\"self\",
        \"href\":\"http://yum.my/fruits/Orange\"}]}],
      \"links\":[
        {\"rel\":\"self\",
        \"href\":\"http://bowls/#{bowl.id}\"}]}"
  end

Sometimes I wish my blog was less narrow.

In the test, an initial bowl document is POSTed to the resource. We expect a fresh bowl representation containing fruits as the response.

Let’s look at the controller action to understand how representers work in a nested setup. Speaking of nesting, here’s the representer responsible for rendering and parsing bowls.

module BowlRepresenter
  include Roar::Representer::JSON
 
  property :location
 
  collection :fruits, 
    :class => Fruit, 
    :extend => FruitRepresenter
 
  link :self do
    bowl_url(id)
  end
end

In addition to the location property the collection defines a nesting fruits. The BowlRepresenter now knows that the collection contains Fruit instances that must be represented with the according FruitRepresenter. We already discussed that in one of the last posts.

Here’s the controller action using that representer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class BowlsController < ApplicationController
  # ...
 
  def create
    bowl = consume(Bowl)
 
    # puts bowl.fruits.inspect
    bowl.fruits = bowl.fruits.collect do |f|  
      Fruit.find_by_title(f.title)
    end
 
    bowl.save
 
    respond_with bowl
  end

I simply assume the consume call already works. Then, what is that loop? Well, when parsing the incoming document, the bowl representer creates a new Fruit instance for every fruit in the collection. If line 7 would be uncommented, it would output the following.

[#<Fruit id: nil, title: "Orange">]

That is, before we reset the collection manually. The representer doesn’t know anything about the database – it just maps a fruit representation in the document to a fresh Fruit instance. This is why there is no id set, yet. We have to do that ourselves (lines 8-10). What might look clumsy to you is simplicity – it’s up to you how to map objects to database records.

Conclusion – For Now?!

Come on, it is easy to use representers in your Rails backends using the roar-rails gem. It helps you rendering documents and makes it quite easy to have object-oriented access to a parsed incoming representation – under Rails-conditions.

And, as always, this is just a start. Open source lives from discussion and criticism, so feel free to use the comments form below. In the next post I’ll discuss writing paginated collections using representers. Have a nice day!

Happy New Year to all my fellow readers! I hope you had a good party!

In this post I wanna clarify why representers in Roar are much more versatile than one might think at first sight.

Model != Resource

I know, Rails teaches us that every resource is a model with exactly one representation. This is wrong. Not only can a resource be just anything, ranging from simple 1-to-1 mappings of database rows to virtual models like a workflow but also can your business models be represented in completely different contexts.

Let’s get back to our fruity example to learn more about this.

orange = Fruit.find_by_title("Orange")
orange.extend(FruitRepresenter).to_json
#=> {"title":"Orange","colors":["orange"]}

In the last discussion we had a Fruit and a Bowl model which were represented in their respective resources. While the fruit just contains some properties the bowl was a composition thereof. This is pretty “rails-conform” (I use this word with a negative undertone) and can simply be abstracted to hundreds of projects where people expose users, blog posts or events in their resources. This is what we call a 1-to-1 mapping of model to resource.

Let’s have some Booze!

We wrote a simple FruitRepresenter for mapping apples, lemons or oranges to documents, and we had the BowlRepresenter to provide documents for fruit collections. That was nice. But you can do more with fruits. Why not open a distillery and make some good booze from pears or grapes?

What that means for our REST API is that we have to represent fruits as ingredients. We also want to document what fruits are contained in a bottle of schnaps.

module IngredientRepresenter
  include Roar::Representer::JSON
 
  property :title
  collection :tastes_like
end

The new IngredientRepresenter looks a bit similar to our FruitRepresenter, however, it represents a fruit in another context.

pear = Fruit.find_by_title("Pear")
pear.extend(IngredientRepresenter).to_json
#=> undefined method `tastes_like'

An exception. While the pear exposes a #title method it does not have a #tastes_like method. Why did I do that? I wanted to emphasize that the representer doesn’t guess anything from the represented object (the pear). It is up to the fruit to provide decent accessors like the #tastes_like reader. No magic or implicit semantics in Roar. And this is a good thing.

Another Context, Another Module.

We could easily push the missing methods into the IngredientRepresenter itself, but we will learn in an upcoming post that it is better to provide additional accessors in a separate module.

module Ingredient
  def tastes_like
    TastesLike.query(title) # returns array.
  end
 
  def tastes_like=(*)
  end
end

In the reader, we query the world-famous TastesLike™ web service. Since we don’t need a writer, the second method ain’t doing nothing.

pear.extend(Ingredient, IngredientRepresenter).to_json
#=> {"title":"Pear","tastes_like":["pear","mango"]}

Cool, this is a fruit represented in a completely different context. What about the parsing, does that work, too?

apple = Fruit.new
apple.extend(Ingredient, IngredientRepresenter)
apple.from_json("{\"title\":\"Apple\",
  \"tastes_like\":[\"Pear\",\"Apple\",\"Mango\"]}")
#=> #<Fruit title="Apple", colors=[]>

Yepp, parsing an ingredient and mapping it to a fruit also works fine.

Fruits in a Bottle.

Let’s see how collections can be represented in different contexts.

module BottleRepresenter
  include Roar::Representer::JSON
 
  collection :fruits, :class => Fruit, 
    :extend => [Ingredient, IngredientRepresenter]
end

The bottle representer knows that it’s composed of Fruit instances. It does use the IngredientRepresenter for parsing and rendering, though. BTW, if you don’t like the long :extend assignment you are free to “hard-include” the modules directly in your models.

Summary

So what we’re doing here is having one model used in two completely different contexts: the conventional “fruit” context and the “ingredient” context. Imagine you’d be doing this with #as_json and different hash-parsing algorithms in your controllers – good luck.

There’s nothing like giving a quick update about Cells on a rainy sunday evening. Almost a year ago we were happy to introduce state-args into Cells. State-args help to prevent saving state in instance variables and instead pass variables from #render_cell as arguments, making your code more explicit.

One big problem was that filters couldn’t take advantage of that feature, thanks to a design flaw in Rails’ callback implementation.

Example?

Consider the following call to render a freaky bassist cell.

render_cell :bassist, :play, "C-sharp", "4/4"

The cell class wants to process the incoming data in a before_filter.

class BassistCell < Cell::Rails
  include Cell::Filters
 
  before_filter :prepare
 
  def prepare(state, tone, timing)
    @before = "In #{tone} and #{timing}"
  end

What now works with the new cells-filters gem is that filters (here, a before filter) can receive the state-args. The implementation is very simple using the hooks gem for easy peasy hooks and callbacks in Ruby.

However, we introduce a dependency to another gem, that’s why cells-filters was released as a separate gem. Go and try it! We might need to add some more behaviour to it, but please don’t ask me to completely bloat it.

You can still use the old-school filters from the Rails Callbacks module but you won’t be able to retrieve state-args. I don’t feel like fixing this in the Rails core itself as the implementation is a bit too complex for me.

Cells Development and a Roadmap.

Dudes, Cells is getting more and more of a standard in Rails development. In the last year, 2011, we had almost 90.000 downloads – this is awesome! Thank you so much.

We have more plans with Cells for 2012, here’s a short summary what we’re planning.

  • Get rid of the Rails dependency at all. We already got Cell::Base to use cells without a controller. Now we want to go one step further and make cells completely decoupled from Rails. Imagine cells (and, numerous “helper” gems like formtastic) being renderable in Sinatra or without a framework at all.
  • Use tilt as an alternative rendering engine. The Rails rendering layer is outdated and should use an abstracting rendering gem like tilt – until we can achieve this in the core, we will provide this in cells. That’ll make huge parts of cells completely independent from Rails.
  • Screencasts! Yeah, I’m working on a screencast series about cells, best practices and interesting solutions users sent in over the recent years.

Beside that, we’re permanently trying to incorporate the cells architecture into the Rails core. Let’s see where this will lead to in Rails 4.0. Happy new year, and… Cheers!

Those of you having asked for mountable cells will be happy with the recent 3.8.0 release! We entirely removed the ActionController dependency. That essentially means you can have cells outside of the standard Rails stack. Cool, heh?

Cells 3.8.0 Released

Two little things in 3.8 changed. Cell::Base and Cell::Rails are now different classes with different semantics. Don’t panic – if you still derive your cells from Cell::Rails and use the #render_cell interface, only, nothing will change for you.

However, we had to tweak the API of some semi-public methods, here’s the new signatures.

Cell::Rails.create_cell_for(name, controller)
Cell::Rails.render_cell_for(name, state, controller, *args)

Well, nothing serious, it’s just the controller sliding to the end. If you use this anywhere, be sure to change it.

What’s new?

What is new is that Cell::Base is now decoupled from the ActionController. There simply is no AC-reference in Base anymore. However, this reference is still managed in Cell::Rails on purpose:

  • Calls to #url_for and friends automatically query the parent controller for host and action name. This makes it easy to embedd cells into a controller view and still having correct links in the cell.
  • Having the AC reference, people can still use request, params and session – if they need it. We strongly discourage accessing HTTP properties from a view component, though.

Let’s see what the new decoupled Base brings us.

Cells on Routes.

Deriving your cell from Base makes it routeable.

class PostsCell < Cell::Base
  def show
    @posts = Post.find(:all)
    render
  end

Routeable? Mountable? Well, let’s look at config/routes.rb to understand this.

match "/posts" => proc { |env|
  content = 
    Cell::Base.render_cell_for(:posts, :show)
  [ 200, {}, [ content ]]
}

How cool is that? You can mount a cell to a route without the ActionController overhead and still use the rendering, the caching and testing you all love from Cells. And, hey, it’s super super fast now.

The lack of the AC dependency makes cells even more versatile.

More on Routing

Since we got rid of the AC instance we have to take care of our URLs ourself. The cell still has access to all the URL helpers. Nevertheless, those helpers usually query the controller for host name portions, etc. That’s actually very simple with cells, too.

class PostsCell < Cell::Base
  def default_url_options
    {:host => "apotomo.de"}
  end

Just override the #default_url_options method as used from AC. This allows using the URL helpers as usual.

PostsCell.new.posts_url
#=> "http://apotomo.de/posts"

Let me know how these changes work for you! I’m eager to see new cases of applications in the next weeks.