Posts tagged "rails"

The Carnival is over in Brazil but we are still partying at Plataformatec by bringing you a complete new release of SimpleForm. This time is not a small bump though, it’s a shiny new version: SimpleForm 2.0, that comes with a bunch of new features and customizations, a new wrapper API to create custom input stacks and a great integration with Twitter Bootstrap.

Wrappers API

The new wrappers API is here in place of the old components option (besides some other *_tag and *_class configs), to add more flexibility to the way you build SimpleForm inputs. Here is an example of the default wrapper config that ships with SimpleForm when you run its install generator:

config.wrappers :default, :class => :input,
  :hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
  ## Extensions enabled by default
  # Any of these extensions can be disabled for a
  # given input by passing: `f.input EXTENSION_NAME => false`.
  # You can make any of these extensions optional by
  # renaming `b.use` to `b.optional`.
 
  # Determines whether to use HTML5 (:email, :url, ...)
  # and required attributes
  b.use :html5
 
  # Calculates placeholders automatically from I18n
  # You can also pass a string as f.input :placeholder => "Placeholder"
  b.use :placeholder
 
  ## Optional extensions
  # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup`
  # to the input. If so, they will retrieve the values from the model
  # if any exists. If you want to enable the lookup for any of those
  # extensions by default, you can change `b.optional` to `b.use`.
 
  # Calculates maxlength from length validations for string inputs
  b.optional :maxlength
 
  # Calculates pattern from format validations for string inputs
  b.optional :pattern
 
  # Calculates min and max from length validations for numeric inputs
  b.optional :min_max
 
  # Calculates readonly automatically from readonly attributes
  b.optional :readonly
 
  ## Inputs
  b.use :label_input
  b.use :hint,  :wrap_with => { :tag => :span, :class => :hint }
  b.use :error, :wrap_with => { :tag => :span, :class => :error }
end

Wrappers are used by the form builder to generate a complete input. You can remove any component from the wrapper, change the order or even add your own to the stack.

The :default wrapper is going to be used in all forms by default. You can also select which wrapper to use per form, by naming them:

# Given you added this wrapper in your SimpleForm initializer:
config.wrappers :small do |b|
  b.use :placeholder
  b.use :label_input
end
 
# Uses the :small wrapper for all inputs in this form.
simple_form_for @user, :wrapper => :small do |f|
  f.input :name
end

Or you can just pick a different wrapper in a specific input if you want:

# Uses the default wrapper for other inputs, and :small for :name.
simple_form_for @user do |f|
  f.input :name, :wrapper => :small
end

You can see a more detailed description of the new wrappers API in the documentation.

Twitter Bootstrap

The second big change in SimpleForm 2.0 is out of the box Bootstrap integration. SimpleForm now ships with a generator option to initialize your application with a set of specific wrappers customized for Bootstrap. To get them, just run in your terminal, inside a Rails application (with SimpleForm already installed):

rails generate simple_form:install --bootstrap

This gives you the default SimpleForm initializer in config/initializers/simple_form.rb with some extra integration code added for Bootstrap. For example, here is the default wrapper:

config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', 
  :error_class => 'error' do |b|
  b.use :placeholder
  b.use :label
  b.wrapper :tag => 'div', :class => 'controls' do |ba|
    ba.use :input
    ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
    ba.use :hint,  :wrap_with => { :tag => 'p', :class => 'help-block' }
  end
end

This wrapper is setup with the same structure that Bootstrap expects and is set to be the default wrapper in your application. This is the killer feature in SimpleForm 2.0: the Bootstrap integration is not inside SimpleForm but all in your application. This means that, if you want to move away or customize Bootstrap in the future, you don’t need to monkey patch SimpleForm, everything is in your app!

We’ve set up a live example application showing most of the SimpleForm inputs integrated with Twitter Bootstrap, make sure you check it out! The application code is on github.

Keep reading this blog post to find out the other changes and deprecations that gave SimpleForm all this extra flexibility, allowing it to be easily integrated with Twitter Bootstrap 2.0.

New configs

SimpleForm 2.0 comes with some new configs to ease its integration with Bootstrap and to make your daily work even more flexible:

  • default_wrapper: defines the default wrapper to be used when no one is given.
  • button_class: defines a class to add for all buttons.
  • boolean_style: change the way booleans (mainly check boxes and radio buttons) are shown: :inline (the default) uses the same structure as before, checkbox + label; :nested (generated for new apps) puts the checkbox inside the label, as label > checkbox.
  • collection_wrapper_class: class to add in all collections (check boxes / radio buttons), given collection_wrapper_tag is set.
  • item_wrapper_class: class to add to all items in a collection.
  • generate_additional_classes_for: allows you to specify whether to generate the extra css classes for inputs, labels and wrappers. By default SimpleForm always generate all classes, such as input type and required info, to all of them. You can be more selective and tell SimpleForm to just add such classes to the input or wrapper, by changing this config.

Deprecations

In order to create the new wrappers API, we had to deprecate some configs and change some helpers, so here is a basic summary of what is being deprecated:

Configs

  • translate: By making placeholder and hint optional options in the wrappers API, you can already disable the automatic translation attempt that happens for these components. labels, on the other hand, are always used in forms, so we added a special config for them: translate_labels.
  • html5: this config is now part of the wrappers API, with b.use :html5, so the config option has been deprecated.
  • error_notification_id: in favor of using error_notification_class only.
  • wrapper_tag=, wrapper_class=, wrapper_error_class=, error_tag=, error_class=, hint_tag=, hint_class=, components=: all these were moved to the wrappers API structure, and are not required anymore.

Helpers

  • :radio input type: In order to integrate with Bootstrap, we had to get rid of the :as => :radio and use :as => :radio_buttons instead. The former still works, but will give you a bunch of deprecation warnings. CSS class names changed accordingly as well
  • collection_radio: has changed to collection_radio_buttons to follow the :as => :radio_buttons change. Its label class has changed as well based on the helper name.

Wrapping up

SimpleForm 2.0 comes with a lot of new features, in special the new wrappers API, to make it flexible enough to allow you to customize inputs as much as possible in an easier way, and to bring you the integrated Bootstrap structure.

Make sure you check out the new SimpleForm README and also the CHANGELOG for a full list of changes. We’ve also created an special wiki page to help you Upgrading to SimpleForm 2.0.

If you find any trouble while migrating to 2.0, or any issue with Bootstrap integration, or any other issue, please let us know in the issues tracker. And if you have any questions, make sure to send them to the mailing list, there are a lot of people there to help you.

All our development team and an amazing number of contributors put a lot of effort into this new release and we hope you will enjoy it. SimpleForm 2.0 + Bootstrap: from us, for you, with love.

Thoughts about SimpleForm 2.0? Please let us know in the comments.

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?

A while ago we were working on an application that had an entire version specially created for mobiles, such as the iPhone. This specific application was entirely tested with Capybara, Steak and Selenium Webdriver. Although the test suite wasn’t the fastest one in the world, the web application was very well tested, and to guarantee that we would also be testing the mobile version, we would have to simulate an iPhone user agent accessing the application.

But wait, you might be thinking that we are not able to change browser headers while dealing with Selenium. Capybara has a nice API to define new drivers and Selenium allows us to define different profiles with custom configurations for each driver. Lets see how we can put all this together to handle that:

Capybara.register_driver :iphone do |app|
  require 'selenium/webdriver'
  profile = Selenium::WebDriver::Firefox::Profile.new
  profile['general.useragent.override'] = "iPhone"
 
  Capybara::Driver::Selenium.new(app, :profile => profile)
end

Yup, it’s that simple =). We are creating a new driver for Capybara called :iphone, that will use Selenium with Firefox, but with a different profile, overriding the user agent string. This way you can pretend to your application that you are accessing through a “real” iPhone, by giving the “iPhone” string as user agent. You could also configure an :android driver, for instance, by simply changing the user agent string.

So now, how do we make use of that new driver in our specs? Here comes a simple example:

scenario 'access phone information using a modal box', :driver => :iphone do
  visit root_path
 
  page.should have_no_css "#fancybox-wrap"
  page.should have_no_content "0800 123456"
 
  within("header") { click_link "Telefones úteis" }
 
  within("#fancybox-wrap") do
    page.should have_content "0800 123456"
  end
end

We are just passing the :driver => :iphone option to our scenario. Remember that the latest Capybara versions use RSpec metadata options and will apply the :driver option automatically, changing the current driver to our registered :iphone in this case. For more info please refer to Capybara’s README.

You are now able to configure different user agents based on your application requirements, and test it in a full stack way. How about you, do you have any quick hint on how to test different user agents using another driver? Let us know in the comments :)

Erik DeBill has put two interesting benchmarks on his blog. The first one compares the performance of different Ruby implementations in Rails development mode while the second compares their performance in Rails boot time. If you haven’t read them yet, please do it now.

Benchmarking code is an important practice, but it can be misleading if you fail to understand the root causes that lead to the different results.

Performance in development mode

In the first blog post, it is guessed that the root case for having slow requests in development is because Rails eager loads all models and controllers for each request:

Now, what I’d really like is a way to avoid recompiling everything every time. If I could have Rails recompile just the model or controller I’m working on and skip all the others, that’d be grand. I’ve taken a couple stabs at it, but I haven’t succeeded yet.

This is wrong! Rails, in development, only loads the model and the controller you are using in that specific request. This is very easy to verify if you create a new application, scaffold two resources and add a puts self.name in their class definition. If you access one controller, it will only load the model explicitly referenced in that controller. Even the model associations try to be lazy in that aspect, always loading the minimum it can.

So you may ask, why Rails is getting so slow after adding more scaffolds?

It happens because Rails 3.0 includes all helpers by default in your ApplicationController. So at the beginning of each request, Rails needs to load all helpers. Loading a helper in development mode is slow because ActiveSupport::Dependencies needs to track which dependencies were added when a file is loaded. This tracking basically happens by checking which constants were added invoking Object.constants before and after the file was loaded. Tracking these constants take more than 50% of the time in the request, mainly because invoking Object.constants is slow.

In other words, the main reason for an implementation to perform better in the benchmarks showed in the blog post is if it can calculate Object.constants faster. Those results do not mean at all that an implementation is more suitable than other for Rails development. In order to have real results, we would need a real application that is not made of 1000 scaffold (or, in this case, 1000 helpers).

In any case, if the root cause is in loading all helpers, how can we make it better? There are a few things:

1) Obviously, the problem can be fixed by having less helper files. Since Rails scaffold automatically generates helper files, it is common that applications have a bunch of empty helpers. Get rid of them. If you prefer you can even turn off the automatic generation of helpers in scaffold by adding the following to your application configuration:

config.generators.helper = false

2) If you simply don’t want to include all helpers, there is a method called clear_helpers that you could invoke in your ApplicationController. This method won’t fix the problem because it is invoked too late, after all the helpers were already loaded. So you get the feature, but not the performance improvement.

3) Rails master (upcoming Rails 3.1) has a configuration option that allows you to effectively turn these helpers off getting both the feature and the performance improvement:

config.action_controller.include_all_helpers = false

Boot performance

The second blog post shows how Rails boot time performs in different implementations. Since it was not made explicit in which environment those benchmarks were executed, I will assume it happened on development.

At the end of the second blog post, it tries to associate the performance of booting Rails in development with the amount of code inside the app. However, when you boot an application in development, no model, controller or helper is loaded at all unless you explicitly access them in an initializer or in your routes file. Once again, you can check that by adding some puts to your classes.

So, you may ask one more time, what makes booting up so slow?

Rails 3 has a new router that can match paths very fast, but in order to do so, it needs to compile each route into a regular expression and that takes some time (although it could probably be made faster). And it is exactly the routes compilation that is slow on boot time. We can easily reproduce it by adding the following to our router:

Foo::Application.routes.draw do
  1000.times do |index|
    resources :"posts#{index}"
  end
end

This took 55 seconds on my machine using REE which is quite close to the value that he showed on his benchmark.

Again, benchmarking code is important, but more important is to correctly interpret the results. In his example, it is likely that most of Rails booting time is spent on compiling the routes and the benchmark just shows how good different Ruby implementations are in handling all these regular expressions.

Wrapping up

Much more interesting benchmarks for Rails boot time would actually be performed in production environment, which actually has to load all the code inside the app folder and compile the routes file. Regardless, developers starting new applications should always be skeptical about choosing a Ruby implementation based on other application’s benchmarks.

When starting out a new application, any Ruby implementation should suit you just fine unless you have a stronger constraint (like Java integration). Once your application starts to grow and you want to evaluate how well it performs in different implementations, you should do your own benchmarks and see how it goes. In any case, don’t jump into conclusions. If you need to investigate deeper, each implementation has its own sets of benchmarking and profiling tools that may help you really understand what is actually slow and how to improve it.

I also want to thank ruby-prof authors and maintainers, for such an amazing tool, and Yehuda Katz, who helped me profile a demo Rails application in order to write this detailed response.

And you? Have you done benchmarks in your applications and found any interesting data you would like to share?

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!