Posts by José Valim

We have just released Devise 2.0. This version is not a big refactoring, nor contains stellar features, it is simply another step towards a very mature authentication library.

Over the years, we have learned from our own experience and from your feedback, how to better use Devise. We’ve made changes to improve security and also to make the library more flexible. All those changes were backwards compatible, forcing us to maintain different branches of logic in the same source code to accomodate those different scenarios. Devise 2.0 simply deprecates those old scenarios so we can clean up the code.

When you migrate to 2.0, you should get some warnings. The amount of warnings will depend on when you started using Devise. For recent applications, it should take 2 minutes to update (basically fixing up migrations and the locale file), older applications should be up to speed in 15-30 minutes. We have created a page with instructions to upgrade, be sure to read it for a smoother experience.

Finally, Devise 2.0 also includes:

  • Support to the reconfirmable feature. When on, if the user changes his e-mail, he needs to confirm the new e-mail address before the e-mail is finally updated;
  • We got rid of t.database_authenticatable and friends in migrations in favor of explicit code;
  • Better support to engines. For example, we now support config.parent_controller which you can set to something different from ApplicationController. There is a good sample engine here;
  • Rails 3.2 support. The previous Devise version (v1.5) runs fine but with a few deprecation warnings, v2.0 gets rid of them;

The CHANGELOG is available here.

Thanks everyone that contributed to this awesome release and, if you have any issues, please let us know in the issues tracker. Here to a better future!

Rails 3.2 is out with great features on spotlight: faster development reloading, faster router and explain queries. However, every Rails release ships with minor features that do not get that much attention but still would be a great fit to your application. This blog post is about my five favorites “hidden” features of Rails 3.2.

1) Smarter content_tag_for

This feature written by Prem Sichanugrist provides a very simple but welcome clean up to your views. Both content_tag_for and div_for now accepts an array of records and automatically loop over each record. Therefore, instead of writing this:

  @posts.each do |post|
    content_tag_for(:li, post) do
      ...
    end
  end

You can simply write:

  content_tag_for(:li, @posts) do |post|
    ...
  end

2) Smarter migration generators

It is funny how some parts of Rails as old as the migration generators continue receiving improvements day after day. Rails 3.1 already added a feature that automatically generate indexes for associations, by simply invoking:

rails g scaffold Comment post:references title:string body:text

With the above, Rails will detect that post is a reference and it will automatically 1) add a post_id integer column, 2) add an association to your model and 3) add an index to that column.

Right after 3.1 came out, I have pushed another small feature to the migration generator that simply makes the type attribute default to string. Therefore, you no longer need to write:

rails g scaffold Person name:string email:string

You could simply write:

rails g scaffold Person name email

Oddly enough, the idea for this feature came when I was preparing a presentation and the scaffold command could not fit in a slide (the so-called Presentation Driven Development). Anyhow, this small addition would not be enough to make to the best five “hidden” features of Rails 3.2. That’s when Dmitrii Samoilov comes in.

Dmitrii sent a pull request that allows you to specify which columns should have an (unique) index. So one could write:

rails g scaffold Person name:index email:uniq

And the generator will automatically generate an index for name and an unique index for e-mail. There are other features there as well, so don’t forget to checkout the CHANGELOG.

3) Flexible exception handling

When Rails 3.0 came out, one of the features that people suddenly missed was the ability to better handle exceptions. The issue was: since Rails 3 became a lot more Rack “fluent”, we had to move some features to the middleware stack and this forced us to move the whole exceptions handling as well. Rails 3.2 attempts to bring some customization back to the game by allowing you to set your own exceptions rack application that is invoked when a failure happens. For instance, you could set the exceptions application to your own router in your config/application.rb:

config.exceptions_app = self.routes

Now, every time there is an exception, your router is going to be invoked. Therefore, to render custom 404 pages, you could simply add to your router:

match "/404", :to => "errors#not_found"

And implement the logic in the controller as you wish! However, there are a few things to keep in mind if you go down this road:

  1. You need to use match in your routes and not get/post/put/delete because such exceptions can happen in any HTTP request;
  2. You won’t be able to see your custom exceptions in development unless you set config.consider_all_requests_local to false in your config/environments/development.rb. The reason is, if the request is considered local, Rails will always favor to show the debug exceptions page;
  3. You can always access the original exception in the controller at env["action_dispatch.exception"];
  4. It is not possible to set cookies, the session nor the flash after an exception happens. They all were already serialized back to the client;
  5. Finally, the default exceptions application used by Rails that simply renders a page in public/STATUS.html is available here: action_dispatch/middleware/public_exceptions.rb

Remember that whatever you do in the errors controller, it should not be anything “fancy”. Keep it simple because something already went wrong with your application!

4) Custom partial paths

In order to render a partial for a given model, Rails 3.0 retrieved the partial name by calling: model.class.model_name.partial_path. Grant Hutchins & Peter Jaros noticed that this was not very flexible because the class was responsible to define the partial path and therefore they decided to move this responsibility to the instance. In order to better understand how you can use this feature, let’s consider the following practical example.

Imagine your application have an activity feed and each activity in the feed has a certain type. Usually, each type is rendered differently. For example, if you consider a to-do-list application, activities could be both “marking a list as favorite” or “marking a task as done”. Usually, applications solve this by looping for each item and rendering its respective partial, something like this:

@activities.each do |activity|
  render :partial => "activities/#{activity.kind}",
    :locals => { :activity =>  activity }
end

Now, you can solve this problem by defining to_partial_path in the model (the method to_partial_path is part of the ActiveModel API and can be implemented in any object. The example above implements it in the model for convenience, but it could be a presenter, another ORM, etc):

class Activity < ActiveRecord::Base
  def to_partial_path() "activities/#{kind}" end
end

And then invoking:

render :partial => @activities, :as => :activity

This will now work on Rails 3.2 because even though all activities are of the same class, each instance is actually responsible for telling Rails which partial should be rendered.

The difference here is not only in brevity, but also in performance. Although the first snippet works fine, it is slow. In the scenario where only one kind of activity happened, the first snippet will go through the render stack 30 times and lookup the same template in your filesystem 30 times. If you read Crafting Rails Applications you know that this lookup is cached, but even though it would certainly be faster if we didn’t have to do this 30 times, but once.

That’s where render :collection or render :partial with an array comes in. In such cases Rails will retrieve all templates up front skipping duplicates, and this new feature allows us to take advantage of it even if the partial lookup is dynamic. So, in the scenario where all the activities are of the same kind, the template lookup will happen just once and no longer 30 times. In other words, best case scenario becomes O(1), worst case scenario is still O(n).

5) Filtered chain logging is back

Another very small change that will make development more pleasant is that Rails will now log “Filter chain halted as CALLBACK_NAME rendered or redirected” every time a before/around/after filter in your controller halts the request. This was the case in Rails 2.3 but somehow got lost when Rails 3 came out. It is one of those small things you don’t know how much you missed until you see it again!

And what is your favorite Rails 3.2 “hidden” feature? Don’t forget to take a good look at the CHANGELOGs and check out many others improvements!

We, Rails developers, have always worried about improving the performance of our test suites. Today I would like to share three quick tips we employ in our projects that can drastically speed up your test suite.

1. Reduce Devise.stretches

Add the following to your spec/test helper:

Devise.stretches = 1

Explanation: Devise uses bcrypt-ruby by default to encrypt your password. Bcrypt is one of the best choices for such job because, different from other hash libraries like MD5, SHA1, SHA2, it was designed to be slow. So if someone steals your database it will take a long time for them to crack each password in it.

That said, it is expected that Devise will also be slow during tests as many tests are generating and comparing passwords. For this reason, a very easy way to improve your test suite performance is to reduce the value in Devise.stretches, which represents the cost taken while generating a password with bcrypt. This will make your passwords less secure, but that is ok as long as it applies only to the test environment.

Latest Devise versions already set stretches to one on test environments in your initializer, but if you have an older application, this will yield a nice improvement!

2. Increase your log level

Add the following to your spec/test helper:

Rails.logger.level = 4

Explanation: Rails by default logs everything that is happening in your test environment to “log/test.log”. By increasing the logger level, you will be able to reduce the IO during your tests. The only downside of this approach is that, if a test is failing, you won’t have anything logged. In such cases, just comment the configuration option above and run your tests again.

3. Use shared connection with transactional fixtures

If you are using Capybara for javascript tests and Active Record, add the lines below to your spec/test helper and be sure you are running with transactional fixtures equals to true:

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil
 
  def self.connection
    @@shared_connection || retrieve_connection
  end
end
 
# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

Explanation: A long time ago, when Rails was still in 1.x branch, a new configuration option called use_transactional_fixtures was added to Rails. This feature is very simple: before each test Active Record will issue a begin transaction statement and issue a rollback after the test is executed. This is awesome because Active Record will ensure that no data will be left in our database by simply using transactions, which is really, really fast.

However, this approach may not work in all cases. Active Record connection pool works by creating a new connection to the database for each thread. And, by default, database connections do not share transactions state. This means that, if you create data inside a transaction in a thread (which has its own database connection), another thread cannot see the data created at all! This is usually not an issue, unless if you are using Capybara with Javascript tests.

When using Capybara with javascript tests, Capybara starts your Rails application inside a thread so the underlying browser (Selenium, Webkit, Celerity, etc) can access it. Since the test suite and the server are running in different threads, if our test suite is running inside a transaction, all the data created inside the test suite will no longer be available in the server. Alternatively, since the server is outside the transaction, data created by the server won’t be cleaned up. For this reason, many people turn off use_transactional_fixtures and use Database Cleaner to clean up their database after each test. However, this affects your test suite performance badly.

The patch above, however, provides a very simple solution to both problems. It forces Active Record to share the same connection between all threads. This is not a problem in your test suite because when the test thread is running, there is no request in the server thread. When the server thread is running, the test thread is waiting for a response from the server. So it is unlikely that both will use the connection at the same time. Therefore, with the patch above, you no longer need to use Database Cleaner (unless you are using another database like Mongo) and, more importantly, you must turn use_transactional_fixtures back to true, which will create a transaction wrapping both your test and server data, providing a great boost in your test suite performance.

Finally, if any part of your code is using threads to access the database and you need to test it, you can just set ActiveRecord::Base.shared_connection = nil during that specific test and everything should work great!

Conclusion

That’s it! I hope you have enjoyed those tips and, if they helped you boost your test suite performance, please let us know in the comments the time your test suite took to run before and after those changes! Also, please share any tips you may have as well!

Last week I spoke at Silicon Valley Ruby Group about PlataformaTec’s open source tools, mainly Devise, Simple Form and Responders.

When talking about Devise, I’ve mentioned that, before creating Devise, we were alternating between using Authlogic or Clearance in our projects. However, we soon realized that we needed a solution that was as customizable as Authlogic (allowing us to choose behaviors and several configuration options) and as complete as Clearance (whole MVC stack). It is fun to remember this happened more than 2 years ago.

After the presentation, someone came to talk to me about Sorcery and said it would be nice if Devise provided the same kind of tooling, allowing someone to build their own controllers and views around Devise instead of using Devise built-in controllers and views. His proposal surprised me, because this approach is totally possible with Devise and it was one of our design goals since day one.

That said, we realized that we were probably not “advertising” the bare-bone, stripped-down aspect of Devise well enough. That’s why I am writing this blog post. Devise already makes it easy for you to customize your own views, using the generator rails g devise:views which copies the views to your application. But what if you want to roll out your own views AND controllers?

To show you how we can achieve that, let’s write some code! The first step is to create a Rails application:

rails new devise-only-model

Next, we will add Devise to the Gemfile:

gem "devise", "~> 1.4.6"

And run the installation generator:

bundle install && rails g devise:install

The installation generator is going to give you some extra instructions, so don’t forget to do that as well. Next, let’s generate our basic User model, but we will pass an extra parameter called --skip-routes:

rails g devise User --skip-routes

By passing this extra parameter, Devise is going to generate everything as usual, with a small difference on config/routes.rb:

devise_for :users, :skip => :all

This parameter tells Devise to not generate any route at all. You can check that by executing bundle exec rake routes. However, you may be wondering: why can’t we simply remove the devise_for call? If we remove the route, Devise wouldn’t actually know that you have added Devise configuration to the User model, as all models are lazy loaded. So we need the route to tell Devise it needs to setup the appropriate helpers for the user, like authenticate_user!.

With Devise configured, we are ready to create the controllers and views on our own. In this blog post, we are going to create the SessionsController as an example allowing us to sign in and sign out. First, let’s add our routes:

root :to => "sessions#new"
post "/users/sign_in"    => "sessions#create"
delete "/users/sign_out" => "sessions#destroy"

Our SessionsController at app/controllers/sessions_controller looks like:

class SessionsController < ApplicationController
  # For security purposes, Devise just authenticates an user
  # from the params hash if we explicitly allow it to. That's
  # why we need to call the before filter below.
  before_filter :allow_params_authentication!, :only => :create
 
  def new
    @user = User.new(params[:user])
  end
 
  def create
    # Since the authentication happens in the rack layer,
    # we need to tell Devise to call the action "sessions#new"
    # in case something goes bad. Feel free to change it.
    user = authenticate_user!(:recall => "sessions#new")
    flash[:notice] = "You are now signed in!"
    sign_in user
    redirect_to root_path
  end
 
  def destroy
    sign_out
    flash[:notice] = "You are now signed out!"
    redirect_to root_path
  end
end

The controller implementation is quite straightforward. With the controller in hands, we just need to generate the view for the new action at app/views/sessions/new.html.erb:

<% if user_signed_in? %>
  You are signed in as <%= current_user.email %>. <%= link_to "Sign out", users_sign_out_path, :method => :delete %>.
<% else %>
  <%= form_for @user, :url => users_sign_in_path do |f| %>
  <div><%= f.label :email %><br />
  <%= f.email_field :email %></div>
  <div><%= f.label :password %><br />
  <%= f.password_field :password %></div>
  <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
  <div><%= f.submit "Sign in" %></div>
  <% end %>
<% end %>

The view shows a message if the user is signed in, otherwise it shows a sign in form. Now we are almost ready to check if it works. First, we need to run the migrations:

bundle exec rake db:migrate

Remove the index page:

rm public/index.html

And create a user in the database so we can sign in. We can do that in rails console:

User.create!(:email => "jose@example.com", :password => "123456")

Now, start the server and you are ready to sign in and sign out. You can also block user access in any controller by calling authenticate_user! in a before filter. Just remember that, if you add the filter to your application controller, remember to skip the filter on the sessions controller, otherwise you won’t be able to sign in in the first place.

You can now freely proceed to implement the other controllers and views in your application. Keep in mind that if you have devise :recoverable in your model, all the related methods like User.send_reset_password_instructions will already be available in your model, so you can use them straight away to implement your own reset password feature. Since Devise use all those methods internally, if you have any questions about implementing your own reset password feature, you can always take a look at Devise own controllers for some help.

I hope this post can help you to roll out your own controllers if this is the kind of feature you expect from Devise. Also, if you are worried about the overhead of using Devise even if you are not using its controllers, there is no need to worry at all. Devise does the smart thing and only loads the controllers you are actually using. Also, it lazily loads all behaviors, so if you are not using recoverable, no code related to recoverable will be loaded at all.

It is important to keep in mind that Devise was built by us to be flexible and capable of handling different requirements from different clients, so it is PlataformaTec’s priority to have it as flexible as possible! So, what would you like to see in “bare-bone, stripped-down Devise” in order to better use it in your applications?

When writing Crafting Rails Applications, I knew exactly which parts from Rails I wanted to talk about. However, I didn’t want the book to simply describe how everything works, I actually wanted everyone to build something useful from each part of Rails.

One of the hardest areas to come up with an useful tool as example was the template handlers. Template handlers are responsible for template compilation and the canonical examples are: ERb and Haml. Obviously, creating something like ERb or Haml from scratch would require a lot of code beyond the Rails integration so it wasn’t an option. On the other hand, tools that simply render rdoc or markdown templates would be too simple and there are already plenty of gems doing the same out there.

So I started playing with some options. The first one was something like Why’s Markaby but that would still require a good amount of code (albeit much less than ERb). Next, I have played with something called YERb (YAML + ERb) which was an interesting hack but too slow to be of any use. I was almost planning to remove the chapter about template handlers when it finally came to me the idea of markerb: markdown + erb (in the book, we did a wordplay and called merb). While the idea was simple and easy to implement, it had a great use case: multipart templates.

With Markerb, you can create one template for ActionMailer and it will be delivered both as text and HTML. So there is no need to maintain two templates. You write it in markdown, which is delivered as text, but also rendered to be delivered as HTML. Recently, I have crafted Markerb in its own gem so everyone can use it.

How to use?

The usage is quite simple. Assuming you have a notifier as below:

class Notifier < ActionMailer::Base
  def contact(recipient)
    @recipient = recipient
    mail(:to => @recipient, :from => "john.doe@example.com") do |format|
      format.text
      format.html
    end
  end
end

If you create a template at app/views/notifier/contact.markerb:

Multipart templates **rock**, right <%= @recipient %>?!

It will generate two parts, one in text and another in HTML when delivered. And that is it! Before we finish, here are a few things you might need to know:

  • The “contact.markerb” template should not have a format in its name. Adding a format would make it unavailable to be rendered in different formats;
  • The order of the parts matter. It is important for e-mail clients that you call format.text before you call format.html;
  • Notice you can normally use ERb inside the template.

If you are interested in how Markerb, template handlers and other part of Rails work, check out Crafting Rails Applications. We also hope to add a generator to Devise that will optionally copy all views as Markerb templates to your application.

And you? Do you have any use cases for Markerb? Do you have any other interesting template handlers you would like to share?

It is common in Rails 3.0 applications that you want to provide default views for a group of controllers. Let’s say you have a bunch of controllers inside the Admin namespace and you would like each action to fallback to a default template. So if you are rendering the index action for Admin::PostsController and “app/views/admin/posts/index.html.*” is not available, it should then render “app/views/admin/defaults/index.html”.

There are several ways to implement this feature at the controller level. It mainly relies on trying to render the original template and then rescue ActionView::MissingTemplate. If this error is rescued, you then render the default one. However, there is a considerable performance overhead in this approach as it needs to pass through the rendering and template lookup stack twice.

Luckily, since Rails 3.0, we have a new abstraction called resolvers that holds the logic to find a template. I explain comprehensively how resolvers work and their API in my book Crafting Rails Applications. So here I would just show the basics to get this functionality working.
First, we need to define a DefaultResolver, it could be done inside the lib directory:

class MyResolver < ::ActionView::FileSystemResolver
  def initialize
    super("app/views")
  end
 
  def find_templates(name, prefix, partial, details)
    super(name, "admin/defaults", partial, details)
  end
end

Our new resolver simply inherits from ActionView::FileSystemResolver and does two changes: Overrides the initialize method so the view path defaults to “app/views” inside our application and overrides find_templates. The find_templates method receives the template name, a prefix (i.e. the controller path), a boolean marking if the template is a partial or not and a hash of details. In the example above, we simply ignore the prefix given and hardcode it to “admin/defaults”.

Now, assuming that all controllers inside the Admin namespace inherit from an Admin::ApplicationController, we can add default views to all of them by adding the following line:

class Admin::ApplicationController < ActionController::Base
  append_view_path MyResolver.new
end

And we are done! The view_paths holds a list of paths and/or resolvers that the controller will look for templates until one is found. If none is found, an ActionView::MissingTemplate is raised. Since we used append_view_paths, our resolver was added after the “app/views” path, used by default in all controllers.

As you may have guessed, resolvers are a powerful abstraction that allows you to retrieve templates from anywhere, including the database, which is the example given in Crafting Rails Applications.

Finally, template inheritance was a feature recently added to Rails master (upcoming Rails 3.1), so you won’t need to create your custom resolver as above. There is a good wrap up about this feature in Rails Edge.