Posts tagged "plugins"

A new I18n gem just got released and it comes with two new backends extensions: Fast and InterpolationCompiler.

First, what is a backend?

I18n.t, I18n.translate, I18n.l and I18n.localize methods are actually just wrappers to I18n.backend, which is actually who does all the heavy lifting. This means that you can change your backend to other stuff, as long as it respects the required API.

By default, I18n comes with the Simple backend, but others are available. For example, I18n has an ActiveRecord, which stores translations in the database. This is useful in cases someone needs to change translations through a web interface. To use it, you just need to do:

  I18n.backend = I18n::Backend::ActiveRecord

There are a couple other backends, like a backend which implements fallbacks, so if something cannot be found in a specified language, like german (:de), it can fallback to english (:en). You can check the whole list, but for this while, we are going to focus on the two new backends extensions.

Fast

Fast, means fast. And oh, boy, this one is fast. This extension flattens translations to speed up the look up. For example, the following hash { :a => { :b => { :c => :foo } } }, gets flattened to { :"a.b.c" => "foo" }, so instead of recursively looking into hashes, it looks just once. The obvious expense is that whenever you are storing translations, you need to flatten the translation hash, and it takes more time than usual.

In order to measure different backend implementations, I pushed some benchmark setup to the I18n repository. The current setup measures the storage time, the time it takes to translate a key (the depth of the key means how many nested hashes it takes), the time to translate a key falling back to the default key and the time translate a key (at depth 5) and interpolate. The results comparing the Simple backend without and with Fast extension are showed below:

Simple vs. Fast

In other words, a simple lookup using the Fast extension is 3 to 4 times faster than the Simple one. Besides, configuring your application to use it is very simple:

  I18n::Backend::Simple.send :include, I18n::Backend::Fast

Nice!

Interpolation compiler

The InterpolationCompiler is a backend extension which extracts all required interpolation keys from a string, leaving just the minimum required to runtime. Imagine the following string: "This is a custom blank message for {{model}}: {{attribute}}". This extension annotates the string so it knows that it needs to interpolate both model and attribute, and points exactly where the interpolation should happen. We can compare the Simple backend without and with the InterpolationCompiler below:

Simple vs. Interpol

The InterpolationCompiler just changes the time taken when we have interpolation keys, without affecting too much the other translations. You can add it to your app as easy as the Fast backend:

  I18n::Backend::Simple.send :include, I18n::Backend::InterpolationCompiler

Run, I18n, run!

But the best is still coming! Fast and InterpolationCompiler can actually be used together, to achieve unseen performance in I18n. The benchmark speaks for itself:

Simple vs. FastInterpol

While we speed up the performance in around four times in simple lookups, Fast and InterpolationCompiler improvements get combined whenever we need to use interpolation, becoming around six times faster!

As said previously, both extensions increase the time taken to store translations as side-effect. Such can be viewed below:

Store

The yaml hash used in for the benchmark, is relatively slow, but it shows how the time taken to store translations grows with such extensions. But remember, you are constantly storing translations only in development (before each request is processed). In production, the translations are stored at startup and that is it.

Using within Rails

You should be able to use such features today in Rails 2.3.5 and it will also be possible in Rails 3. You just need to install the I18n gem and configure it in your environment.

Why care?

All the times shown are in miliseconds. In other words, why care? If you are building a simple application, using just one language, those improvements likely won’t change anything. But in an application which relies on I18n, during a request/response lifecycle, I18n is invoked many times: error messages for models, flash messages, page titles, e-mail subjects, page content, date and time localization, pluralization rules and even in many of ActionView helpers. So in such cases, it’s worth to give such extensions a try.

Running benchmarks on your own

If you want to run benchmarks on your own, it’s quite simple. You just need to do:

git clone git://github.com/svenfuchs/i18n.git
cd i18n
ruby benchmark/run.rb

Credits

The possibility to have backends and such extensions is due to Sven Fuchs, which leads the I18n group quite well.

Many of the backends were added by I18n community, and the Fast and InterpolationCompiler were created by thedarkone.

Guys, I owe you a beer! ;)

Enjoy!

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!

After Devise was released, there were some misunderstandings about Devise roles and how to use it. And the best way to understand it is explaining which problem we wanted to solve when we designing Devise.

In most applications developed at Plataforma, we usually have two actors: one which represents the client who hired us and another which is the end-user, the audience of the developed app.

Before Devise, we used Authlogic or Clearance as authentication solutions. Authlogic does not say anything about controllers, so we usually had two models (Admin and User) and some controllers to handle sign in, password reset and so forth for each model, which required expressive effort to handle and maintain.

On the other hand, we had Clearance. Clearance deals completely with the User model, but we needed to work on the Admin model almost from scratch.

With Devise, we can have a full stack solution for both User and Admin. But that only works if User and Admin does not need to share a lot of responsibilities.

For instance, if you are working on a blogging system with different roles as “editor”, “author” and “contributor”, but they all share a lot of activities in common, as writing a post, handling such roles with Devise can add a great of complexity to your code, mainly because you will need to use Single Table Inheritance (STI) and/or polymorphic relationships very frequently.

To handle such cases, you can use any of the authorization libraries out there for Rails (remember that Devise is mainly an authentication tool).

Scoped authentication

On the same line, there were some requests to provide authentication by username, instead of e-mail, or providing a subdomain as scope for the authentication. You can now do that using Devise 0.5.1 or higher by just setting the authentication keys in your model:

class User < ActiveRecord::Base
 devise :all, :authentication_keys => [ :username, :subdomain ]
end

Now you user needs an username and subdomain to authenticate and their respective value should be sent as parameters when signing in. Such values are converted to conditions when retrieving the user from the database for authentication. For example, the following path with query string:

/users/sign_in?user[username]=josevalim&user[subdomain]=plataformatec

Is converted to the following query with ActiveRecord:

User.first(:conditions => { :username => "josevalim", :subdomain => "plataformatec" })

And only after retrieving the user we check for password validity. However, keep in mind that those conditions are used only when signing in. If an user is already authenticated, it will be retrieved from session, where such conditions are not used. In other words, you still need a filter in your controllers to verify that the user accessing a given subdomain, is really allowed to access that subdomain.

Such configuration should handle most of the cases, but if you still need more customization, you can overwrite three class methods exposed for exactly this purpose: User.authenticate, User.serialize_into_session and User.serialize_from_session.

Enjoy!

UPDATE: This post was an introduction to Devise and a couple of things changed since then. There is a more recent post which describes the same steps as below using generators and, for a more complete and always updated explanation, please check the README.

In Rails Summit Latin America 2009, we showed Devise in a lightning talk and today we are officially releasing it! Before we show you some code, we are going to explain what we want to achieve with Devise, starting with the most used authentication solution nowadays: Clearance and Authlogic.

Clearance

Clearance is a full stack authentication solution, implementing all Model, View and Controller layers using Rails Engines. It deals with account confirmation and password recovery. You just need to plug and play! However, you are required to use the model User and it does not allow you have add and/or customize different roles.

Authlogic

When comes to the Model, Authlogic is definitely the most complete solution out there. It handles several cryptography providers and many other goodies which are completely configurable. However, it’s not a full stack solution (it does not say how users should confirm their account or recover their password) and it has a little bit of controversy since it handles the session in a model. So here is the question, where the session could be handled then?

Here comes Warden!

Warden is a general rack authentication framework, developed by Daniel Neighman, which handles the session in a rack middleware. The main benefit from it is that you can share your authentication strategies with several apps, so if you are using Sinatra, Rails and some others middlewares at the same time, they all rely on the same rules!

Devise: strategies for authentication

After we fell in love with Warden and used it in some projects, we decided to create a full stack solution as Clearance, but flexible as Authlogic, on top of Warden. The solution is Devise, a Rails Engine which handles multiple roles, each one of them with different strategies. Devise currently comes with 5 strategies:

  • Authenticatable: responsible for encrypting password and validating authenticity of a user while signing in;
  • Confirmable: responsible for verifying whether an account is already confirmed to sign in, and to send emails with confirmation instructions;
  • Recoverable: takes care of reseting the user password and send reset instructions;
  • Rememberable: generates and clears a token to remember the user from a saved cookie;
  • Validatable: creates all needed validations for email and password. It’s totally optional, so you’re able to to customize validations by yourself.

The nice thing is: imagine that you are building an app which needs to handle invitations. You just need to create a Invitable strategy on Devise and never implement it again!

Show me the code!

In the README, you will find all the information you need to start using Devise in your projects, so here we are going to cover the main aspects of it. Let’s suppose you are creating an user model, which needs to be authenticated and recover his password. The first step is to create the columns using Devise migration helpers:

create_table :users do |t|
  # creates email, encrypted_password and password_salt
  t.authenticatable
 
  # creates reset_password_token
  t.recoverable
end

Then you need to declare inside your model which strategies you want to use:

class User < ActiveRecord::User
  # Authenticatable is always included
  devise :recoverable, :validatable
end

And create the routes:

ActionController::Routing::Routes.draw do |map|
  # Check for configuration params on README
  map.devise_for :users
end

The route will access your model and create only the routes for the strategies declared. That ensures that your user won’t access the confirmations controller inside Devise. Devise also adds a couple of helpers and filters to be used inside your controllers:

  # Inside your protected controller
  before_filter :authenticate_user!
 
  # Inside your controllers and views
  user_signed_in?
  current_user
  user_session

user_session is a hash scoped only to the user. So if you have two roles, they will have different session hashes and their data won’t conflict! This awesome feature come straights from Warden!

Devise also has I18n support and since it’s an engine, you can customize your views just by placing a copy of it in your application. A small application build as example is also available on Github!

What’s more to come?

We are planning to add several other strategies to Devise, including brute force protection, session timeouts and also other features, as generators. You can spy our TODO list whenever you want.

Our many thanks to

Carlos Antônio which worked on Devise and made it ready for prime time! Jonas Nicklas, which introduced us to Warden and Daniel Neighman for building and maintaining it!

We also want to thank Thoughtbot guys, which wrote several decisions and tips they took while developing Clearance which helped us while building Devise.

Finally, thanks to Fábio Akita for giving us the chance to release it at Rails Summit and Gregg Pollack for releasing Devise on Ruby 5!

First, what is Inherited Resources?

Inherited Resources is a gem/plugin that allows you to speed up development by making your controllers inherit all restful actions so you just have to focus on what is important. A Rails scaffold controller which responds to html, xml and json is as simple as:

1
2
3
class ProjectsController < InheritedResources::Base
  respond_to :html, :xml, :json
end

However all actions are still customizable! For example, you can change the behavior of the create action on success just doing:

1
2
3
4
5
6
7
8
9
class ProjectsController < InheritedResouces::Base
  respond_to :html, :xml, :json
 
  def create
    create! do |success, failure|
      success.html { redirect_to edit_project_url(@project) }
    end
  end
end

It also supports I18n (all flash messages are set with I18n), belongs to association (like a task belongs to project), nested belongs to (task belongs to project which belongs to company), polymorphic belongs to (comments belong to task or file or message) and optional belongs to (the same as previously, but you can request the resource with or without parents).

As you noticed, besides simplifying your controllers, InheritedResouces makes easy to reproduce your models behavior and relationship in controllers. And right now, it’s also scopes and responder fluent!

has_scope: named_scope twin brother

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
class ProjectsController < InheritedResources::Base
  has_scope :featured, :boolean => true
  has_scope :by_methodology
  has_scope :limit, :default => 10, :only => :index
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

Yay!

Responder

A couple weeks ago, we wrote about ActionController::Responder. But you don’t have to wait Rails 3 to be released to play with it, you can start now by using Inherited Resources.

Quick redirect

After using Inherited Resouces, I realized that most of the times I overwrite a create, update or destroy actions is to change the redirect destination. In our ProjectsController above, if we want to redirect to the edit page after create, we would have to do:

1
2
3
4
5
6
7
8
9
class ProjectsController < InheritedResouces::Base
  respond_to :html, :xml, :json
 
  def create
    create! do |success, failure|
      success.html { redirect_to edit_project_url(@project) }
    end
  end
end

It wouldn’t be cool if it have a shortcut? Now it has:

1
2
3
4
5
6
7
class ProjectsController < InheritedResouces::Base
  respond_to :html, :xml, :json
 
  def create
    create! { edit_project_url(@project) }
  end
end

That simple, just give the url as a proc and since the proc does not expect any parameters, it assumes that you want to overwrite the redirect url.

Finally some DSL?

Last weeks, there was a discussion on Boston.rb group about different resource controllers gems. Reading some of the feedback there, I’ve decided to stab a DSL to Inherited Resources. It will mainly remove the duplication when you have to give a block, the previous example above could be written as:

1
2
3
4
5
6
7
class ProjectsController < InheritedResouces::Base
  respond_to :html, :xml, :json
 
  create! do |success, failure|
    success.html { redirect_to edit_project_url(@project) }
  end
end

Or even in the compact form:

1
2
3
4
class ProjectsController < InheritedResouces::Base
  respond_to :html, :xml, :json
  create! { redirect_to edit_project_url(@project) }
end

Those changes were not applied yet, it depends mainly on you. If you like or not, let us know in the comments!