Posts tagged "responders"

This week we released the first release candidate version of Devise that is fully compatible with Rails 4, and we’re bumping its version to 3.0. This version completely drops support for Rails 3.1 and Ruby 1.8.7, only keeping compatibility with both Rails 3.2 and Rails 4, running with Ruby 1.9.3 and 2.0.

This rc version took some time to get ready, we’ve been running a rails4 branch for some time already and one of the reasons was because of the changes required to make it compatible with the new strong parameters API from Rails 4. We are aware that some people have been using this branch since Rails 4.0 beta1 with success, and we’re now inviting you to try 3.0 rc with the recent release of Rails 4.0 rc1.

Devise stable

Together with the 3.0 beta version, we’ve released Devise 2.2.4 with a few enhancements and bug fixes, make sure to check the changelog to see the new goodies. All changes are also included in the rc version.

Simple Form

Simple Form has been running a 3.0 rc version for a couple months already, fully compatible with Rails 4 as well, and today we are releasing its release candidate version. In Simple Form master we just dropped support to the 3.x Rails series, focusing our work on Rails 4 compatibility from now on, due to a series of improvements in Rails 4 regarding form helpers – but don’t worry, we will be keeping a v2.1 branch with Rails 3.2 compatibility for a while.

We have some cool plans to improve the wrappers API even further, but that’s subject for another blog post :).

Responders

Responders has been around for quite some time already and we use it in most of our projects, so today we’re celebrating its 1.0 release candidate version, specially to support Rails 4.

Show For

Show For just got a new stable release, v0.2.6, with all the enhancements and bug fixes that were in master, plus a v0.3.0 rc version that adds Rails 4 support.

Mail Form

Mail Form also got a new 1.5 rc release with Rails 4.0 compatibility. Nothing else has changed from the current 1.4 version.

Has Scope

Has Scope is getting a new 0.6 rc version with Rails 4.0 compatibility, including a couple of fixes that were already present in master.

Compatibility

All these new releases are officially dropping support to Rails 3.0 and 3.1, and Ruby 1.8.7. We’ll keep compatibility with Rails 3.2 and 4.0 from now on, all of them on the same branches except for Simple Form which has different branches for each Rails version.

Wrapping up

We’ve got new hot releases for you to try out with Rails 4, please give them a try and let us know if you find any issue or have any feedback.

We’d also like to specially thank everyone involved in helping us getting these projects up and running in Rails 4, without you folks that’d have never been possible.

Enjoy <3

This year is coming to an end and it was amazing for us at Plataforma Tecnologia. We are proud to share with you, faithful reader, our accomplishments in 2010, which weren’t few.

Open Source

The year has begun on fire. In February, José Valim made his way into the Rails Core team and has been doing a great work since then, including many contributions to the Rails 3 release.

We are also really proud with Devise. It got very mature, achieving the 1.0 version this February. Since then, Devise is becoming one of the best solutions for authentication in Rails and also one of the most watched repositories on GitHub.

In August, Devise 1.1 was released with Rails 3 support and a bunch of cool features. Recently, a lot of work is being done towards the 1.2 version, which includes full support to the awesome OmniAuth gem.

We also released SimpleForm this year. SimpleForm is our take on building forms in a simplified way lead by Carlos Antônio who recently did a great work on HTML 5 support.

Other gems were released, such as ShowFor, which is a DSL to simplify how you show your objects in views and also Responders, a collection of Rails 3 responders.

Book

Eariler this month, José Valim’s book entitled Crafting Rails Applications has been released by the highly acclaimed publisher Pragmatic Bookstore! The book covers internal aspects of Rails 3 and how you can bend it to your will. The reviews and buzz has been great so far, even though still in beta. Grab your copy now!

Events

This year was also very productive in terms of events. We’ve been to a lot of events, heck, George was even able to go to RailsConf, in Baltimore! Also, José Valim has spoken in various events, including Euruko 2010 (includes video), RubyConf Brazil 2010 (talk in portuguese) and OxenteRails 2010.

Carlos, Hugo and George did their share as well, speaking at various events, from smaller and user-group events to bigger ones such as OxenteRails, RS on Rails and QCon SP.

Company

The company itself is getting more mature and increasing. At January 2010, PlataformaTec was composed of 6 people, and up until December 2010, 5 other people joined the company (including myself)! We also have started playing with iOS development, something we believe to have a great future, expect future blog posts on the subject.

Great 2011!

Have a great New Year! We wish you all the best for year to come. We have high expectations for 2011, so stay tuned!

Inherited Resources always had a hate/love history with Rails Edge. Just after DHH posted about respond_with, it was already there in Inherited Resources. This initial implementation provided a nice test suite and several use cases for a improved Rails’ implementation, based in Responders, which encapsulates all the behavior in one class, and can be added, modified or updated.

After that, Inherited Resources was outdated and envy. It needed to be updated and it was: responders has been available in Inherited Resources for more than four months, and consequently in Rails 2.3.

Everything looked great until we started to develop a fresh Rails 3 application. The main purpose of this fresh application is to be a sample of Rails 3 features, including generators and responders. Based on that, it doesn’t make sense to use a tool like Inherited Resources, since it would abstract almost all controllers away and the application would no longer fit as an example.

So we were there, building an application based on scaffold, and as we saw duplicated code we started to realize Inherited Resources contains a lot of tools that could be used outside its context. And this is what is happening right now, two new gems are being launched: Responders and HasScope.

Responders

Responders is a repository of Rails 3 responders, mainly based on this post on Ruby on Rails weblog. And as a proof of concept, we wrote two Responders: FlashResponder and HttpCacheResponder.

FlashResponder uses I18n to automatically look up flash messages for you, even allowing you to set generic messages. In other words, your old create action:

1
2
3
4
5
  def create
    @post = Post.new(params[:post])
    flash[:notice] = "Post was successfully created" if @post.save
    respond_with(@post)
  end

Can now be written as:

1
2
3
4
5
  def create
    @post = Post.new(params[:post])
    @post.save
    respond_with(@post)
  end

Your locale just needs to have the following configuration:

  flash:
    actions:
      create:
        notice: "{resource_name} was successfully created"
      update:
        notice: "{resource_name} was successfully updated"
      destroy:
        notice: "{resource_name} was successfully destroyed"
        alert: "{resource_name} could not be destroyed"

If you want to change a message, let’s say, the success message when creating a post, there are several ways to achieve that. You can give :notice to respond_with or even update your I18n under the key: “flash.posts.create.notice”.

For us it came as a nice tool to provide I18n by default in our controllers and decouple messages from code.

The HttpCacheResponder automatically adds a Last-Modified header to API requests without any extra configuration. This allows clients to easily query the server if a resource changed and also replies with 304 (Not Modified) status.

As usual, the code for both implementations came from Inherited Resources. And since it contains a Rails 3.0 Responders shim, those responders can already be used in Inherited Resources and they are!

In other words, Inherited Resources code got simplified and such features can now be used by any Rails 3 application without a need to load all Inherited Resources stack. Besides, as more Responders appears, they can be added to Responders repository and be used in Inherited Resources easily.

HasScope

The other tool extracted from Inherited Resources is HasScope.

Let’s suppose that we have a ProjectsController and at some point you want to add some filters on the index action like showing just featured projects, selecting projects by methodology or even let the user choose how many projects he can see per page. The first thing to do? Add named scopes to your model:

1
2
3
4
5
class Project < ActiveRecord::Base
  named_scope :featured, :conditions => { :featured => true }
  named_scope :by_methodology, proc {|methodology| { :conditions => { :methodology => methodology } } }
  named_scope :limit, proc{|limit| :limit => limit.to_i }
end

The next step would be to add a lot of code in your controllers that check which named scopes you should call, based on the parameters sent right? Well, not anymore. Your controller can be as simple as:

1
2
3
4
5
6
7
8
9
class ProjectsController < ApplicationController
  has_scope :featured, :type => :boolean
  has_scope :by_methodology
  has_scope :limit, :default => 10, :only => :index
 
  def index
    @projects = apply_scopes(Project).all
  end
end

Then for each request:

/projects
#=> acts like a normal request, but returning only 10 projects

/projects?featured=true
#=> calls the featured named scope and bring 10 featured projects

/projects?featured=true&by_methodology=agile&limit=20
#=> brings 20 featured projects with methodology agile

If you configure your routes, you could even have pretty urls with it:

/projects/agile/featured
#=> brings 10 featured projects with methodology agile

All in all, you can now call has_scope in any controller and in case you are using it inside an Inherited Resources controller, everything gets handled automatically, so enjoy!

So Inherited Resources finally reaches 1.0

After this refactoring and a complete clean up of Inherited Resources issues, it finally reaches 1.0! When you install it, responders and has_scope gems should be installed as well. Responders is always loaded, since it’s a dependency, but if you want to use has_scope you will need to add it to your environment as well.

After you install the gem, the upgrade process in any application can be handled in three steps:

1) Add config.gem “has_scope” to your “config/environment.rb”.

2) Configure which flash keys are used by your application. At first, Inherited Resources used :notice and :error. Then we changed to :success and :failure, but just after this DHH established :notice and :alert as Rails default.

From 1.0 on, Inherited Resources will be using :notice and :alert, but it allows you to change it:

  InheritedResources.flash_keys = [ :success, :failure ]

3) Finally, you may need to do a final change in your application due to how responders work. The default way a resource tells a responder if it was created/updated/destroyed with success or not, is through errors. If the errors are empty, it assumes it succeeded, otherwise it failed.

This will be true in all create/update scenarios, but not in destroy. In other words, if you have a code with similar structure in your model (please don’t!):

  def before_destroy
    if some_condition_is_not_valid?
      false
    else
      true
    end
  end

It won’t work anymore. You need to add an error to your model to really invalidate it:

  def before_destroy
    if some_condition_is_not_valid?
      errors.add(fault_attribute, :invalid)
      false
    else
      true
    end
  end

Now you should be ready to go. Enjoy!

UPDATE: ActionController::Renderer was renamed to ActionController::Responder, so this post was changed to properly reflect such changes.

About two and a half years ago, resources started to be a first class citizen in Rails when version 1.2 was released and it was all about RESTful admiration and HTTP Lovefest. Since then we’ve added map.resources to our routes, started to use different formats in respond_to and really learned how to love all HTTP verbs.

Your application entry point (the router) has become completely RESTful, but it still haven’t reached ActionPack core. Today we are bringing the missing ingredient: make your controllers more resource aware.

The first step: respond_with(@resource)

About one week ago the first step was given. We brought Merb’s provide/display into Rails, just as DHH proposed: you can define supported formats at the class level and tell in the instance the resource to be represented by those formats. Let’s see some code:

  class UsersController &lt; ApplicationController
    respond_to :html, :xml, :json
 
    def index
      @users = User.all
      respond_with(@users)
    end
  end

It works like this: when a request comes, for example with format xml, it will first search for a template at users/index.xml. If the template is not available, it tries to render the resource given (in this case, @users) by calling :to_xml on it. Before Rails 3.0, the equivalent to the index action above would be:

  class UsersController &lt; ApplicationController
    def index
      @users = User.all
      respond_to do |format|
        format.html
        format.xml { render :xml =&gt; @users }
        format.json { render :json =&gt; @users }
      end
    end
  end

The gain with respond_with introduction is more obvious if you compare index, new and show actions:

  class UsersController &lt; ApplicationController
    respond_to :html, :xml, :json
 
    def index
      @users = User.all
      respond_with(@users)
    end
 
    def new
      @user = User.new
      respond_with(@user)
    end
 
    def show
      @user = User.find(params[:id])
      respond_with(@user)
    end
  end

With older version:

  class UsersController &lt; ApplicationController
    def index
      @users = User.all
      respond_to do |format|
        format.html
        format.xml { render :xml =&gt; @users }
        format.json { render :json =&gt; @users }
      end
    end
 
    def new
      @user = User.new
      respond_to do |format|
        format.html
        format.xml { render :xml =&gt; @user }
        format.json { render :json =&gt; @user }
      end
    end
 
    def show
      @user = User.find(params[:id])
      respond_to do |format|
        format.html
        format.xml { render :xml =&gt; @user }
        format.json { render :json =&gt; @user }
      end
    end
  end

However, even if respond_with is full featured (Ryan Daigle has done an excellent job covering all respond_with features), it started to show some flaws on create, update and destroy actions. A default create action could be written with respond_with as:

  def create
    @user = User.new(params[:user])
    if @user.save
      flash[:notice] = "User was created successfully."
      respond_with(@user, :status =&gt; :created, :location =&gt; @user) do |format|
        format.html { redirect_to @user }
      end
    else
      respond_with(@user.errors, :status =&gt; :unprocessable_entity) do |format|
        format.html { render :action =&gt; :new }
      end
    end
  end

You can notice that:

  1. You have to call respond_with twice;
  2. On the first respond_with, you have to give the location twice. One as a hash and other as parameter to redirect_to;
  3. And by giving a block to respond_with, you focus more on the exception than on the default behavior.

Suddenly we realized that respond_with is useful just for GET requests. There was no HTTP Lovefest, it was more like HTTP monotheism.

2. Second step: Love all

At this point, we started to ask ourselves: why can’t respond_with include HTTP verb semantics? Isn’t that what RESTful is all about?

After this commit, we brought all HTTP verbs to respond_with, but only for resourceful formats like xml and json (ie. formats that don’t need to render a template). Then our create action with POST request could be rewritten as:

  def create
    @user = User.new(params[:user])
    respond_with(@user) do |format|
      if @user.save
        flash[:notice] = "User was created successfully."
        format.html { redirect_to @user }
      else
        format.html { render :action =&gt; :new }
      end
    end
  end

Internally, when a xml request happened, respond_with would check the current request method (in this case, POST) and whether the resource has errors or not. Depending on these values, it will render the resource or the resource errors, setting accordingly the status and location headers. Now we just have to worry with non-RESTful requests, like html, mobile and iphone… (which we call navigational formats).

Personally, I was quite happy with the results at this iteration, since it solves two of the three problems exposed previously. However, Jeremy Kemper and Yehuda Katz wanted more. And they were right, yeah!

3. Third step: Responder

In step 2, we were able to abstract POST, PUT and DELETE requests for formats like xml and json, but we still would have to repeat html behavior through all controllers, even if almost all of them behave similarly.

So what we want is a simple way to tell the controller how to render our resources depending on the format AND HTTP verb. In this commit, we’ve added ActionController::Responder.

By default, ActionController::Responder holds all formats behavior in a method called to_format. It’s similar to this:

  def to_format
    return render unless resource.respond_to?(:"to_#{format}")
 
    if get?
      render format =&gt; resource
    elsif has_errors?
      render format =&gt; resource.errors, :status =&gt; :unprocessable_entity
    elsif post?
      render format =&gt; resource, :status =&gt; :created, :location =&gt; resource
    else
      head :ok
    end
  end

As you can see, it renders the resource based on the HTTP verb and whether it has errors or not. If some format, like :html, does not fall into the to_format behavior, we just need to define a to_html in ActionController::Responder, which by default is:

  def to_html
    if get?
      render
    elsif has_errors?
      render :action =&gt; (post? ? :new : :edit)
    else
      redirect_to resource
    end
  end

As result, you have your resources representation encapsulated in one place. Your controller code just have to send the resource using respond_with(@resource) and respond_with will call ActionController::Responder which will know what to do. Our create action (POST request) can then be written as:

  def create
    @user = User.new(params[:user])
    flash[:notice] = "User was created successfully." if @user.save
    respond_with(@user)
  end

If you need to change the redirect URL, you can overwrite just the html behavior:

  def create
    @user = User.new(params[:user])
    flash[:notice] = "User was created successfully." if @user.save
    respond_with(@user) do |format|
      format.html { redirect_to user_confirmation_url }
    end
  end

On the other hand, if you want to change the redirect url and the Location header for XML and JSON, you can simply give :location as option:

  def create
    @user = User.new(params[:user])
    flash[:notice] = "User was created successfully." if @user.save
    respond_with(@user, :location =&gt; user_confirmation_url)
  end

The best of all is that the responder implementation is quite simple and straight-forward, but still powerful. We haven’t enforced any restriction in the API. Anything that responds to :call can be a responder, so you can create your custom classes or even give procs, fibers and so on.

Embrace REST in your design and enjoy a consistent behavior through all your controllers. Spread the word!