Uncategorized

Ruby On REST 2: Representers and the DCI Pattern

Friday, December 16th, 2011

We talked about Representers earlier last week. Today, I wanna describe DCI and how it fits perfectly together with representers in Roar.

What is DCI?

For years we’ve been taught that “Fat Models, Skinny Controllers” is the way to organize code. Push all your domain code into your ActiveRecord classes. Many people, including me, agree that this is bullshit. This leads to bloated classes, usually combined with one or two object instances taking care of an entire workflow (aka request).

DCI is an architectural pattern that makes the model “fat-on-demand”: Data objects are enhanced with roles at runtime, but only when needed.

The DCI pattern consists of three concepts.

  1. Data objects are supposed to contain application data. Nothing else. This would be your ActiveRecord row instance, but without any predefined behaviour. Just data.
  2. Context objects define what is done in the current workflow. In Rails, a controller running an action could be a context object.
  3. Roles are behaviour for data objects in a particular context. In Ruby, a Rails controller could mixin a module (a “role”) into an empty model row and thus let it process something.

Hooray for DCI – But Why?

Now the thing is, I absolutely hate to hype something (except stuff I did, of course). However, DCI makes code better maintainable, easier to follow and way easier to test. Period.

BTW, did you already check out my new Roar gem? It’s hip!

Think of a classical model found in many Rails applications with maybe one hundred methods. Or fifty. Fifty methods to interfere with each other. In a DCI setup, an object has a limited behaviour scope. The limited knowledge makes it easier to debug and predictable.

One Model, Multiple Faces

Since representers are modules they fit perfectly into the DCI approach, making them roles. Let’s consider the fruit representer from last week, again.

require 'roar/representer/json'
 
module FruitRepresenter
  include Roar::Representer::JSON
 
  property :title
  collection :colors
end

You still can include this representer into its “host” class directly.

class Fruit
  include Roar::Representer
  include FruitRepresenter
end

The problem now is that the Fruit class is limited to one representation, only. Forever and a day you may only render one particular representation. The key about representations, however, is that one model may be represented by multiple, yeah, representations.

Now, back to the start, let’s assume the Fruit class is some empty ActiveRecord class without any prior knowledge of representations at all.

class Fruit < ActiveRecord::Base
end
 
lemon = Fruit.from_json("{\"title\":\"Lemon\"}")
#=> undefined method `from_json' for Fruit:Class

Yeah, there is no #from_json class method.

Representers On DCI

In order to use the DCI approach, we first need an instance. Here’s how the lemon instance, and only this instance, can be extended with the fruit representer.

lemon = Fruit.new.extend(FruitRepresenter)
lemon.from_json("{\"title\":\"Lemon\"}")
lemon.title #=> "Lemon"

Awesome! The built-in Ruby #extend method makes the lemon instance aware of its representation and mixes in #from_json and friends.

Naturally, this works in both ways.

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

The mixed-in representer also lets us render the JSON document.

Gimme Complexity!

On a flat level with single objects, this works out-of-the-box with recent Roar/representable versions. Problems arise when we have nested setups.

module BowlRepresenter
  include Roar::Representer::JSON
  include Roar::Representer::Feature::Hypermedia
 
  property :location
  collection :items, :as => Fruit,
    :extend => FruitRepresenter
 
  link :self do
    "http://bowl/#{location}"
  end
end

Using the :extend option we can give representable a hint about the representer to use when rendering/parsing contained objects.

And, hey, this works.

empty_bowl = Bowl.new
empty_bowl.extend(BowlRepresenter)
emtpy_bowl.from_json("{\"location\":\"kitchen\", \
  \"items\":[{\"title\":\"Lemon\",\"colors\":[]}]}")
 
puts empty_bowl.items.first.title #=> "Lemon"

Discussion Needed!

Having representers on an object level makes the whole thing really clean and versatile. You can test document rendering and parsing without polluting classes. And you can have a FruitRepresenter, a RottenVegetableRepresenter and what else you like for your orange instance. BTW, oranges ain’t no vegetables.

We still discuss about the API and need your opinion. Right now, we got this

collection :items, :as => Fruit,
    :extend => FruitRepresenter

Here, :as describes the class that encapsulates the contained data. The :extend option helps representable to find the correct module for the nested item. Now, what about this?

collection :items, :class => Fruit,
    :module => FruitRepresenter

Does that make sense? These options really just describe what’s on the right side of the hash rocket. Thanks to Scott for discussion here. Now, tell us your story!

Ruby On REST: Introducing the Representer Pattern

Wednesday, December 7th, 2011

This post introduces the new Roar gem, a framework-agnostic REST framework for Ruby that puts focus on object-oriented REST documents.

More object-orientation?

The calls for more object-orientation in Ruby frameworks are growing ever louder. Most web frameworks, like Rails, come with a nice database abstraction, a Rack-like HTTP endpoint, routing, and a template engine. It’s the lack of additional abstraction layers that make many programmers ask for “more OOP”.

Already yawning? Yeah, I wrote about that earlier this year. Let’s talk about working solutions now. Let’s talk about REST.

REST is about Documents!

REST is not only about pretty URLs. The problem ain’t URLs at all. Most frameworks have a decent routing layer to connect resource logic (aka controllers) to URLs. However, the key of REST is pushing documents between clients and servers, so why don’t we finally focus on documents?

It’s the document parsing, processing and rendering that makes our heads spinning.

Note: I here use the terms representation and document interchangable just because I can!

Parsing and Processing

Both clients and services have to parse incoming documents. Consider this JSON document.

{"title":  "Lemon",
 "colors": ["green"]}

This could be sent to a resource to create a new fruit, or be retrieved by some client which issued a GET request.

In Rails, and many HTTP gems, this is automatically parsed using a JSON gem.

params = JSON['{"title":  "Lemon",
                "colors": ["green"]}']
 
params["title"] #=> "Lemon"
params["colors"][0] #=> "green"

We’re using a hash access to read properties from that document. This is handy! Now, assume the sender forgot to include the colors.

params = JSON['{"title":  "Lemon"}']
 
params["colors"][0]
#=>NoMethodError: undefined method `[]' for nil:NilClass

An exception, shit! While processing the parsed document (aka hash), we have to take care of missing keys, wrong types etc. We as the consumer have to know about all the pitfalls with this particular document.

Rendering

Now that our parsing and processing code is finished, how do we render outgoing representations? We could use #to_json.

@lemon.to_json(:only => [:title, :colors])

Being a quick solution for rendering small models this approach hits the wall when we have nested models but still want a plain JSON representation, or when we want to embed hypermedia. Also, we put “REST” logic into our database layer. It’s up to you to judge.

What about template languages? Let’s try jbuilder for JSON rendering.

Jbuilder.encode do |json|
  json.title  @lemon.title
  json.colors @lemon.colors
end

Nice! But, wait. How do I test this? Can I test this separately? What if I want different representations for the same model? Do I need different templates? And… is it cool to have format knowledge both in our parsing layer and in our rendering layer? I mean, both need to know about the title property and the colors array.

Representers: OOP to our Documents!

I won’t further discuss the shown concepts here. Let me just criticize that they are not object-oriented and encourage the distribution of document internals about the entire framework.

Here’s how representers can handle all that and make you a happy man at the same time!.

require 'roar/representer/json'
 
module FruitRepresenter
  include Roar::Representer::Base
 
  property :title
  collection :colors
end

This is all we need to declare the basic syntax of the fruit document. Note that it resides in a module which can be used anywhere in your app.

Rendering a Lemon

Now let’s say our database layer provides us a class Fruit with ActiveRecord-like behaviour.

lemon = Fruit.new(:title => "Lemon")
puts lemon.title #=> "Lemon"

Since the representer knows everything about the document format it can be used for rendering JSON. We just have to include the FruitRepresenter module into the class and new methods will be available.

Fruit.class_eval do # DB layer.
  include Roar::Representer::JSON
  include FruitRepresenter
end
 
lemon.to_json
#=> "{\"title\":\"Lemon\",\"colors\":[]}"

Awesome, the FruitRepresenter module gives us a #to_json method. Internally, this method compiles the JSON document by asking the represented object (aka lemon) for its properties and values. Remember, the representer knows about those properties, since we declared them. It does not know anything about ActiveRecord and the like.

Now, what about parsing?

Parsing a Lemon

The great thing about representers is: they work bidirectional. That alone is one of the main advantages to many other gems out there. Bidirectional? Let’s just see what that is.

orange = Fruit.from_json("{\"title\":\"Orange\"}")
puts orange.inspect
#=> #<Fruit:0x9df73a8 @title="Orange", @colors=[]>

We can parse representations and create objects from it! That’s bidirectional: rendering and parsing is combined in one representer.

Again, the representer does not know anything about the underlying database – it just creates an object it was mixed into, reads from the document and assigns properties using polite setters. Nothing more, bro.

Don’t like the class method? If you already have an instance, you can use #from_json on the instance.

orange.from_json("{\"title\":\"Yummy Orange\"}")
orange.title #=> "Yummy Orange"

Nesting Representers

Now that we have fruits, lets put ‘em in a bowl. A fruit bowl contains a list of fruits.

bowl = Bowl.new
bowl.items << lemon
bowl.items << orange

In order to bind the fruit bowl to a REST resource we write another representer module.

module BowlRepresenter
  include Roar::Representer::Base
 
  property :location
  collection :items, :as => Fruit
end
 
Bowl.class_eval do # DB layer.
  include Roar::Representer::JSON
  include BowlRepresenter
end

Properties can be typed using the :as option. The target class must be a representer, too. That’s the only requirement.

bowl.to_json
#=> {"items":[
  {"title":"Lemon","colors":[]},
  {"title":"Orange","colors":[]}
]}

Typed properties allow us to build more complex representations without breaking with OOP. The collection assignment makes building lists as easy as possible. And if you still need to tweak things, there are some helpful configuration options around – more on that in one of the next posts.

Representers love HATEOAS

HATEOAS? Check out this talk I gave if you want to learn about Hypermedia and HATEOAS.

Hypermedia helps clients to operate the API without having to compute URLs. We want hypermedia in our documents.

module BowlRepresenter
  include Roar::Representer::Feature::Hypermedia
 
  link :self do
    "http://bowls/#{location}"
  end
end

Including the Hypermedia feature dynamically adds a new method #link to our representer module. What does it do?

bowl.location = :desk
bowl.to_json
#=> {
"items":[
  {"title":"Lemon","colors":[]},
  {"title":"Orange","colors":[]}],
"links":[{"rel":"self","href":"http://bowls/desk"}]
}

Seems like an easy way to embed links in our documents. In roar-rails the Rails URL helpers work like a charm within the link blocks – making it super simple to provide hypermedia to consumers and still being railsy.

Representers on the Client Side

Ok, representers basically are plain modules. Why not use ‘em on the client side as well? The client doesn’t have access to the model layer – if it does, something’s wrong! However, it’s absolutely ok to share the representer modules.

class Bowl
  include Roar::Representer::JSON
  include Roar::Representer::Feature::HttpVerbs
  include BowlRepresenter # from a gem.
end

See how we simply use an empty class with the mixed-in representer on the client side? Remember, we don’t want to have access to the database here.

The next step is creating a new fruit bowl.

bowl = Bowl.new
bowl.location = "kitchen"
bowl.post!("http://bowls")

This code is enough to send a POST request to the specified URL. The bowl instance will serialize a JSON document, send it to the URL using the HttpVerbs feature, receive the new bowl, deserialize it and update its properties accordingly. You may know this behaviour from REST client gems like ActiveResource – here, with less code and manageable complexity.

Consume Hypermedia, it’s gooood.

The representer also makes it easy to extract hypermedia links from documents.

bowl.links[:self]
#=> "http://bowls/kitchen"

No parsing needed, the representer knows where to find your hypermedia. How cool is that?

XML is not a Crime!

Roar comes with both JSON and XML representers.

module BowlRepresenter
  include Roar::Representer::XML
end
 
bowl.to_xml
#=> '<bowl>
#  <link rel="self" href="http://bowl/kitchen"/>
#</bowl>'

Now choose if you want JSON or XML – it’s up to you! I still don’t understand the XML hating – did I miss something or is it just “too java”?

Roar – and more?

The Roar project is still evolving. However, the current API is almost stable. New features, new concepts, testing helpers, etc will be added over time just like in every framework. Roar is framework-agnostic and can be used anywhere, as long as it’s Ruby.

Its modulare feature architecture makes it easy to extend your documents. Currently, we have some exciting on-going brainstorming and hacking on features like client-side caching in the representer instance, generic error handling, validations, DSLs, … We need you to try it out, complain, propose, help, and spread the word. Thank you for reading until here, you rock!

What was a Classic Tester Became a Mockist…

Saturday, November 26th, 2011

Today I had an interesting experience which I’d like to share with my friends. No, I didn’t discover my dark side, I knew that before. What I found out is that mocking as a test method comes in handy once you get it.

Why Don’t You Use RSpec?

I’ve never been an RSpec fan. Not that I don’t like the BDD-approach, which I do appreciate, I was always scared about its internal complexity. I happened to stay with MiniTest, and this has nothing – and i mean nothing – to do with the opinion of Mr. Rails.

Now, I don’t say that RSpec sucks and is too complex. This would be bullshit and I might even soon switch to using this powerful framework (just to make my friend Justin happy) but right now, this test framework still is too powerful for me.

1
2
3
4
5
6
7
8
9
10
class StringTest < MiniTest::Spec
  describe "String" do
    before do
      @string = "Be nice."
    end
 
    describe "#to_xml" do
      it "returns a string" do
        assert_kind_of String, @string.to_xml
      end

That’s pure MiniTest code, included in Ruby 1.9 and working out-of-the-box.

Testing with Assertions Is Not A Crime!

What MiniTest::Spec gives me is basically a BDD interace for classical testers. I say classic as I learned that testers not using expectations are called classic. Old school. Yo.

I can use the keyword methods describe and it to phrase my requirements to the object (line 2 and 8). Before and after hooks provide convenient setup and teardown blocks (line 3).

However, I still use assertions rather than matchers as found in RSpec. I could use matchers, though. MiniTest provides these.

  it "returns a string" do
    @string.to_xml.must_be_kind_of String
  end

Wow, this is “better readable” in many people’s opinion. I still prefer assertions. But that’s not the point of this essay. What I was going to talk about is mocking. Right, mocking.

Who needs Mocking?

Now let’s say my #to_xml method accepts an additional parameter to configure the behaviour. We’d have to test that, too.

  it "accepts the uppercase option" do
    assert_equal @string.to_xml(uppercase: true),
      "<STRING>BE NICE.<STRING>"
  end

This could go on forever, and we test all the features that the method provides in numerous test cases – or its – uppercase, lowercase, reverse, whatever.

Until now, I’ve been testing only using state verification. I run the method and test the state of my string instance afterwards using assertions. This is called state verification.

Purposeless, I now decide that my app needs another method. Here’s the implementation.

class String
  def to_exemel(options={})
    log "stupid phonetic alias called"
    to_xml(options)
  end

I told you, it doesn’t make any sense. What I want to point out is, the method #to_exemel delegates its arguments to the #to_xml method, which we already tested thoroughly.

Expect the Unexpected!

Testing the logging makes sense, I already use mocking here, as I mock the #log method. More on that in a minute.

1
2
3
4
5
6
describe "#to_exemel" do
  it "delegates to #to_xml" do
    String.any_instance.expects(:log)
 
    @string.to_exemel
  end

However, testing all the behaviour of #to_xml again doesn’t. Here, I found out that mocking is cool, too.

1
2
3
4
5
6
7
8
describe "#to_exemel" do
  it "delegates to #to_xml" do
    @string.
      expects(:to_xml).
      with(:uppercase => false)
 
    @string.to_exemel(:uppercase => false)
  end

First, we define expectations: In the ongoing test case, the #to_xml method must be called on the @string instance along with the specified options hash (line 3-5).

I then call the actual method which is subject of our test. The method will be run – and the mocking framework internally checks, if the #to_xml method is really invoked the way we want it (line 7). If it doesn’t, the test will fail!

I Never Knew It’s Called Behaviour Verification!

What we do here is behaviour verification – we no longer have an assertion checking the final string state (we could do that additionally) but set up an expectation, which changes the workflow of our test slightly.

  • I saved a lot of lines of test code since I do not assert all of #to_xml’s features in the #to_exemel method, again. This is cool.
  • Nevertheless, after mocking my test case includes a lot of knowledge about internal implementation. The test now’s aware that #to_exemel forwards to #to_xml. Changing this implementation detail within the class will break the expectation tests, although the second method might still work from the public perspective.

It seems to be a matter of careful choice when to use mocking, and when not. I for myself still lack the experience to make smart assumptions here. However, I can call now myself a Mocker according to Martin Fowler’s great post, which you should definitely read if you haven’t, yet!

Mocking frameworks?

I found mocha to be a very simple to use mocking framework integrating seamless into MiniTest. Never peeked at the source, though. RSpec comes with a powerful mocking functionality as well, which most people might know, use and appreciate.

Outsights?

The example was stupid, I hope I still could point out the difference between status verification and behaviour verification in this short post. Let me know what you think about it. Good nite, and Mock’n‘Roll!

Apotomo – Screencasts Of Glory – Episode 4

Saturday, October 15th, 2011

The 4th episode discusses partial updates of widgets.

  • Using the event instance to transport payload data between widgets.
  • Updating the page by sending back arbitrary JavaScript and markup from trigger states.
  • Extracting partials to separate widget views.
  • Using #render in both views and states for DRY code.

BTW, please feel free to send me feedback or requests for future episodes – I appreciate!

Cells 3.7 released, taataa.

Thursday, October 13th, 2011

Is it a good sign when a minor release doesn’t yield any stunning new features? When there’s nothing breathtaking to talk about? I guess with Cells it is – the gem finally seems to get into what it should have been 6 years ago: a mature view components framework for Rails.

The 3.7 release, again, lost code – it’s goal was getting rid of the #options hang-over which succeeded. No more state in your cell, except if you choose to do so.

Here’s what changed.

Rails 3.x

Well, needless to say that 3.7 still runs with Rails 3.0 and 3.1. We were able to incorporate a couple of changes into Rails 3.1 to make Cells’ life even easier. Thanks, José for being such a patient maintainer and happy birthday to you ;-)

Caching Inheritance and Conditionals

Arthur Gunn brought us the :if option for caching. So, if you ever needed conditional caching in your cell, here it is.

class CommentsCell < Cell::Base
  cache :show, 
    :if => proc { |cell, opts| opts[:enable_cache] }

To pass in the required options, I’d use #render_cell.

render_cell(:comments, :show, :enable_cache => false)

See how easy it is to bypass (or enable) caching using :if? Also, don’t forget that the second block parameter is the options passed to #render_cell, which brings us to the next core change.

BTW, as a nice extension and in good OOP manners cpb made the cache configurations inheritable. A cell derived from CommentsCell will automatically inherit the cache setting for #show – no need for redundancy.

No more Options!

Luckily, we were able to remove the #options behaviour from Cells – it added unnecessary state, and we try to avoid internal state wherever possible (unlike the Rails core). Where you used to access the magic options hash in a state method you now use explicit state-args.

class CommentsCell < Cell::Base
  def show(user, comments)
    @user, @comments = user, comments
    render
  end

Since the method expects arguments (“state-args”), here’s how you’d pass them into.

render_cell(:comments, :show, user, @comments)

Any additional argument after the state name (2nd argument) is passed to the state. The rest is up to you.

If you want the old behaviour with the options hash that was “simply there”, just include the Deprecations module.

class CommentsCell < Cell::Base
  include Deprecations
 
  def show
    @user = options.first

Test your View Assigns

Another small addition is the #view_assigns method in Cell::TestCase. This works just like in conventional controller test (both Test::Unit and RSpec).

it "should assign correct values" do
  render_cell(:comments, :show)
  assert_equal @user_1, view_assigns[:user]

The view_assigns hash captures all instance variables that were assigned in the rendering cycle. Some people may like that – I don’t. However, here it is.

Have fun with Cells! ;-)

Released Apotomo 1.2

Wednesday, October 12th, 2011

I just released Apotomo 1.2 today. Yeah. People screaming, clapping, hooting, going nuts, I can hear it. Ok, this release is nothing special, but it fixes a severe bug. No, it wasn’t just a bug, it was more, it was a design flaw!

What’s new?

Nothing. I already said that. However, in the last release we added some option that allowed the following.

  responds_to_event :click, :passing => :root

The :passing option makes it easier to attach event handlers to other widgets, for instance, :root. This worked fine on a 2-level setup, but having deeper widget trees, this failed silently.

The problem – in short – was that the parent widget sometimes wasn’t available yet when the child set up its event handlers. The fix: The constructor Widget.new now requires the parent widget as the first argument. Makes things way simpler and explicit.

What can I do with that?

Well, you now can safely use the :passing option anywhere. You can also use root and parent in your has_widgets blocks now. They will be what you expect.

class CommentsWidget < Apotomo::Widget
  has_widgets do |me|
    me.root # => returns the real root
    me.parent # => well, yeah...

All in all, the new constructor makes the Apotomo core a lot cleaner and more understandable.

What changed?

Be warned that widget doesn’t return a real widget instance anymore (line 3). Don’t be worried, you have plenty of ways do to what you want.

1
2
3
4
5
6
7
8
has_widgets do |root|
  root << widget(:comments) # This still works.
  widget(:comments).markup! # This doesn't.
 
  root[:comments].markup! # This works, of course.
 
  comments = CommentsWidget(root, :comments) # works.
  comments.markup! # yepp, works.

Remember, you’re free to use the real constructor in a has_widgets block (line 7) if you need to grab the created instance for whatever reason. You could also use the block for that.

  has_widgets do |root|
    root << widget(:comments) do |comments|
      comments.markup!
    end

In short, the << widget(..) syntax now is a DSL construction, what happens internally is a call to the actual constructor. Easy.

The second big change is that we got rid of the after_add hook. Since widgets receive their parent explicitely in the constructor, there’s no need for a hook after adding a widget. Use the after_initialize hook for that.

Check the CHANGELOG for further notes and let me know if the changes work for you.

Kevin- thanks for donating ;-) LOVE to Austin!

Rails Misapprehensions: Helpers are shit.

Wednesday, October 5th, 2011

When I started using Rails years ago I found helpers extremely cool. I could call a method in a view and it would help me by doing something. The method was simply there, no need to worry about its source and how to access it, just call it.

I got older, wiser, and more opinionated. I still like the concept of helpers – of methods. However, the way helpers are implemented in Rails sucks. Also, having object-disoriented functions in your view brings us back to the years where OOP still had to be invented.

In this post I’d like to discuss why I dislike Rails helpers and how to get out of that misery.

What’s a helper?

In Rails, a helper is a function.

<h2>
  Hello, <%= capitalize @user.name %>
</h2>

Here, the #capitalize method helps me capitalizing the username, which is freaking awesome. As this is pretty simple behaviour, let’s call helpers like this utility methods. They modify the input parameter, compute something or escape strings. Pretty straight-forward.

As a second example, I’d like to show a more complex helper.

<div id="sidebar">
  <%= render_news_for @user %>
</div>

This helper will iterate through news items for a particular user and render markup, maybe using several partials. Since it actively renders templates, let’s call this a view component.

Why are helpers shit?

At first sight, using helpers rocks. Capitalizing a string works like a charm – I simply call a function and it happens.

However, looking at the first helper I can identify several drawbacks.

module StringHelper
  def capitalize(string)
    string.capitalize
  end
  • Helpers in Rails are modules, which do not allow inheritance. If I’d need a foreign method I’d have to include another module into the helper module. Not a big deal.
  • Using the #capitalize methods happens without a receiver. The method is globally available in the view since Rails somehow mixes the helper into the view. So, what happens if I have two #capitalize methods in two different helpers mixed in the same view? I don’t have a clue. Do you?

Before getting to solutions, let me discuss another issue with helpers: Another real problem is the implementation in Rails – how these functions are made available to the view.

Helpers in Rails

Again, I’m not talking about how #form_for or #url_for are written internally, I’m talking about how these methods get into the view.

In Rails 3, all helpers are mixed into the view automatically, you still can insert additional modules using the controller’s helper facilities.

class HomeController < ApplicationController
  helper StringHelper

It’s not that the implementation as-it is bad code or something, it is the idea of magically mixing methods into the view instance to make them globally available. This adds complexity to the Rails core, namely around 280 LOCs. Just to mix some methods into the view.

Helpers are shit.

I desperately tried to demonstrate the major disadvantages of helpers in Rails. To summarize.

  1. I like utility methods. There is nothing wrong with having those little “helpers” in your view. What I don’t like is that they are called without an obvious receiver – they look and feel like functions. This is wrong.
  2. The way Rails mixes helpers into the view is error-prone and sucks. Following a slightly different approach there’s no need for all that complexity.
  3. Complex helpers suck. I do believe in view components and the need for those but they shouldn’t be rendering helper methods.

Moaning is fine, but let’s see how things could be changed.

Solution 1: Push Utility Methods into Decorators.

Luckily, a bunch of people feel uncomfy about the current helper architecture. My friend Steve Klabnik wrote a nice article about Jeff Casimir’s draper gem which introduces the Decorator pattern into Rails’ view layer.

Basically, the draper gem wraps existing model instances and provides utility (“helper”) methods on the decorated instance. Here’s an example.

class ArticleDecorator < ApplicationDecorator
  decorates :article
 
  def published_at
    model.published_at.strftime("%A, %B %e")
  end

Now that we defined the Decorator we can use it to wrap the actual model.

@article = ArticleDecorator.decorate(Article.find(1))

The wrapped model can then be used in the view.

<li>
  <%= @article.published_at %>
</li>

The interesting point is that we call the utility helper on the wrapped model which clearly states a receiver. No need for a homeless, global helper function. This way, we can have cleanly separated, domain-focused helpers for models. Decorators also allow inheritance and all other OOP features, since they are just objects.

Decorators are a solid technique when it comes to – well – decorating models. What can we do if there’s no matching model, for instance, when we need to call #url_for?

Solution 2: Use the Controller Instance as View Context

To learn more about that we should peek at the rendering cycle in Rails. What happens when a controller renders a template?

  1. An ActionView instance is created (this will be the “context”).
  2. The controller manages a magical module that contains all helper methods. This module is now mixed into the ActionView instance to make helpers available. I already discussed the need for hundreds of lines of code in order to achieve this “knowledge transfer” from the controller to the view.
  3. Next, instance variables from the controller are copied to the view instance as well.

These are 3 completely useless steps. Completely. Every template engine, whether it be Rails’ internal or tilt requires a so called view context whenever a template is rendered. Both instance variables and methods (that is, helper calls) used within the template are looked up on this view context instance.

Now, there is absolutely no reason for having a separate ActionView instance as view context! We can simply use the controller instance as context object and everything would work. No need to copy over variables, no need to transfer “helpers” to the view instance.

“Helpers” would be modules mixed into the controller – and that’s it.

class HomeController < ApplicationController
  include UrlMethods
 
  def show
    @link = link_to(home_url)

Notice how we can use the mixed-in “helper” methods in the controller instance – we simply included them.

<a href="<%= home_path %>">

The cool thing is we can also use the utility methods in the view which will be invoked on the controller instance, again. No magic copying, just modules.

The Cells project currently is experimenting with this approach and things work out fine. Will blog.

I can hear people now moan about too many mixed-in methods in their ActionController – and they are right! Again, this is due to Rails’ monolithic view/controller design. If one single controller is responsible for rendering an entire web page, then this controller has a lot of responsibilities – too many. That’s why we should use Cells to split up the view into components, which is discussed next.

Solution 3: Use View Components instead of Complex Helpers.

Helpers that compute data and render partials are scary. Often, there is too much concerns in the little helper.

def render_news_for(user)
  items = user.find_news
  render "shared/news", :items => items
end

Let’s assume the _news partial should be reusable throughout your application, needs some special helper function #sanitize and does caching.

<% cache do
  <%- for item in items %>
    <%= sanitize item.text %>
  <% end %>
<% end %>

Several problems here.

  • Every controller has to take care of requiring the special SanitizerHelper for the partial.
  • Caching happens by using helpers, again, which is no good .

Moving the partial and its behaviour into a cell would cleanly separate concerns. The cell could be used as view context and thus provide utility methods itself.

class NewsCell < Cell::Base
  cache :show
 
  def show(items)
    @items = items
    render
  end
 
  def sanitize(string)
    # ...
  end

This creates a reusable view component with a defined scope. Intentionally, I keep the cells discussion briefly as this would break the mold.

Combining Decorators and Cells

Using draper’s decorators within cells is what I figure a fantastic option. Where the decorator cleanly wraps the model object and provides utility methods for tweaking model data the cell separates the concern into a reusable view component, provides a limited scope and generic helper methods (like #url_for), and even caching!

I really don’t care whether draper, cells, or whatever replaces helpers – all I want is less magic code, more object-orientation and rock-solid software. This was a long post – gimme some feedback in the comments section or tweet me

Spec Your Widgets with rspec-apotomo!

Tuesday, September 27th, 2011

Open source is a great thing. I love the fact that you can simply ignore feature requests by users and anybody will give you a hard time about it – hey, it’s just open source. Even better, people will start implementing things on their own if you make them wait long enough.

This is what happened with Christian Höltje and Jake Goulding who initiated a first version of rspec-apotomo. Thank you, guys!

It’s now possible to test your Apotomo widgets in isolation using RSpec. Yay! Let’s see how that works.

Using the Gem

Bundler is your friend, just add this one-liner to your Gemfile.

group :test do
  gem 'rspec-apotomo'
end

Whoops, this wasn’t a one-liner.

I’m your Generator!

To create a sample spec, just run the generator shipped with the gem.

$ rails g rspec:widget comments
  create  spec/widgets/comments_widget_spec.rb

Spec it!

Even the spec is pretty self-explanatory.

describe CommentsWidget do
  has_widgets do |root|
    root << widget(:comments)
  end
 
  it "should render :display" do
    render_widget(:comments).should == "No Comments!"
  end
end

All we have to do is setting up a widget tree with #has_widgets, just as know from controllers. The #render_widget method does exactly the same as in your application views – it renders and returns the markup. Easy.

Testing Events

Now, Apotomo would be boring without its interactivity.

describe CommentsWidget do
  # ..
  it "should respond to :post events" do
    trigger(:post, :comments).should == ["Thanks!"]
  end
end

#trigger first fires the event (first argument) from the source (second argument). It then returns an array of all return values from widgets responding to that event.

We’re now waiting for proposals how to simplify testing multiple responses – maybe some comfy matcher? I’m excited.

Let us know what you think of this new gem.

BTW- Cells and Apotomo is a lot of work, if you like my gems consider donating.

Folks, here is the Cells Cheatsheet 1.0!

Thursday, September 15th, 2011

Why didn’t I do this earlier? Here’s the official Cells cheatsheet with all the information you need at hand when writing sweet view components in Rails.

It discusses the following topics.

  • Generator
  • Options processing
  • Rendering
  • Control Flow & Initialization
  • View Inheritance & Builders
  • Caching
  • Configuration
  • Test::Unit

There’s still some work to do and if something is missing feel free to fork and commit!

Enjoy your day!

Private Methods: To Test or Not To Test?

Wednesday, September 7th, 2011

Recently I sat in a job interview, we were TDDing a data structure. That was fun, but it turned out that one big minus for me was that I insisted on testing a private method.

I still believe that when writing a class that’s reused in multiple places (maybe as a gem) you have to test both the public and the internal API.

Here’s a very abstract example to discuss.

Example: A Helper.

Let’s say we were writing a helper method to join two strings and format them appropriately. I know, the example is more than stupid.

1
2
3
4
5
6
7
8
9
10
11
class Hello
  def welcome(name)
    name = sanitize(name)
 
    "Hey, #{name}!"
  end
 
private
  def sanitize(string)
    # do whatever you want
  end

The welcomeing process involves tWO steps. First, it removes unwanted chars from the name string using a private method (line 3). Then, the greeting is joined and returned (line 5).

To render the string, you’d do something like

Hello.new.welcome("<b>Ryan</b>")
  #=> "Hey, Ryan!"

Testing the public API

Now, since we ship this really useful helper in its own gem we have to test the public API thoroughly.

it "does not sanitize good names" do
  welcome("Ryan").should == "Hey, Ryan!"
end

Naturally, we’d also test edge cases to see if the complex internal logic works. For example, what if the name contains unsolicited markup?

it "removes HTML" do
  welcome("<b>Ryan").should == "Hey, Ryan!"
end

And so further and so on. Testing the public API with edge cases usually is a good thing. In my gems, I have so called API tests” which test the public interface, only.

Testing in Public – Guilty as Charged!

Testing your public API, only, brings certain benefits

  1. It’s less work as you’re testing less methods, resulting in fewer test cases.
  2. You don’t have redundancies in your tests. All egde cases are asserted on the public API, only, and you don’t do that on your private methods, again.
  1. Your test are more stable since they don’t have to change after an internal refactoring. Given the case you’d rename #sanitize you don’t have to touch your test as you did not test the #sanitize method at all.

Apparently, I can see those advantages and this is where I agree with my interview mate. However, what if a private method yields a certain level of complexity? What if my #sanitize method goes crazy, removes HTML, swipes out SQL injections and donates to Greenpeace at once, all-in-one?

I don’t want to run all those tests through the public API – and there is absolutely no point against testing a private method.

Let’s Go Private!

Testing private methods often makes sense, and I push those tests into so called “Unit Tests”. This might be a different context, scenario, or test file, depending on the test framework I chose.

it "removes HTML" do
  sanitize("<b>Ryan").should == "Ryan"
end
 
it "removes SQL" do
  sanitize("\DESTROY *\Ryan").should == "Ryan"
end

This approach creates redundancy. Some of the cases may have also been covered in the public test, yet. There’s a thin line between redundancy and better-maintainable code.

Anyway, when testing a private method we get benefits as well.

  1. Bugs can be spotted much faster when writing a provoking test against the concerned private method. As I know the bug is somewhere in #sanitize, why should I run through the entire public method stack?
  2. Tests are less complex and thus easier. Testing #welcome, only, obfuscates my output and my test. If I want to test if the sanitizer works, I don’t want to be greeted with an annoying “Hey!” in every test case.
  1. Private tests are focused on the problem the separated methods solves and don’t involve outer methods, which might introduce bugs as well.

Test Privates – Or Not?

When I started with “API” and “Unit” tests I created tons of redundancy. As I kept refactoring lots of tests would break resulting in a bit of work. So reducing private tests seemed to make my tests more stable towards refactoring.

However, if there is a private method that makes me feel nervous due to its complexity (I’m talking about 5 lines of code, not 45), I tend to write “Unit” tests against it.

What are your experiences? Are there any rules-of-thumbs, pros or cons I forgot? Let us know and feel free to comment!