We cannot express how excited we are with such great news. In our last blog post we were celebrating Rafael’s achievement and just a few months later we are celebrating again. Years ago, having three Plataformatec teammates as Rails Core members would be something we’d only dream of, but in 2012 it became reality. I must say that it didn’t happen by chance, not at all.
Carlos has always been an outstanding software developer and a great teammate. He is someone we all deeply trust to solve hard problems and deliver mission critical projects. We’ve always watched Carlos working really hard and we must say that he deserved every bit of such achievement. You can check out his contributions into many other open source projects at http://github.com/carlosantoniodasilva
Kudos to our friend @cantoniodasilva!!!
Last May we happily announced that Rafael França and Carlos Antonio earned commit access to the Ruby on Rails repository – it was a great accomplishment that deserved its own blog post. Today, we have some great news and we want to share with our readers. Just a few days ago, our team mate Rafael França (@rafaelfranca) received an invitation to join the Rails Core Team. And, of course, he accepted!
Rafael contributed to different features coming up in the next Rails 4 release and worked extensively with other Rails contributors to smash bugs and provide many improvements to the framework. I am personally happy to have a friend joining me in the Rails Core Team.
Furthermore, Rafael França’s contributions go beyond Rails. Lately he has also contributed to many other open source projects, like Mongoid, Janky and Dalli besides Plataformatec’s own projects like Devise, Simple Form and Elixir.
From all your friends at Plataformatec.
It is common for web applications to interface with external services. When testing, since depending on an external service is very fragile, we end up mocking the interaction with such services. However, once in a while, it is still a good idea to check if the contract between your application and the service is still valid.
For example, this week we had to interact with a SOAP service, let’s call it
KittenInfo (why would someone provide kitten information via a SOAP service is beyond the scope of this blog post). We only need to contact one end-point of the
KittenInfo and it is called
get_details, which receives a kitten identifier and returns kitten information:
Since this API is simple, it is very easy to mock the client whenever it is required by our application. On the other hand, we still need to verify that the integration between
KittenInfo SOAP service and our application works correctly, so we write some tests for it:
describe KittenInfo::Client do it "retrieves kitten details" do client = KittenInfo::Client.new details = client.get_details("gorbypuff") details[:owner].should == "tenderlove" end end
However, since this is actually contacting the SOAP Service, it may make your test suite more fragile and slower, even more in this case, in which the SOAP Service responses take as long as kitten’s staring contests.
One possible solution to this problem is to make use of filter tags to exclude the SOAP integration tests from running, except when explicitly desired. We could do this by simply setting:
describe KittenInfo::Client, external: true do # ... end
Then, in your
spec_helper.rb, just set:
RSpec.configure do |config| config.filter_run_excluding external: true end
Now, running your specs will by default skip all groups that have
:external set to
true. Whenever you tweak the client, or in your builds, you can run those specific tests with:
$ rspec --tag external
$ rspec --tag ~js.
What about you? What is your favorite RSpec trick?
A couple weeks ago, Aaron Patterson (aka @tenderlove) wrote about getting rid of
config.threadsafe! on Rails 4. When discussing multi-process and multi-threaded servers in production, one important aspect of the discussion that came up in the blog post was code loading.
This blog post is about which code loading strategies exist in a Rails application, how they affect multi-process and multi-threaded servers, and how to build libraries that will behave well in both environments.
The most common form of loading code in Ruby is via requires.
Some libraries work great by simply using requires, but as they grow, some of them tend to rely on autoload techniques to avoid loading all up-front.
autoload is particularly important on Rails applications because it helps boot time to stay low in development and test environments, since we will load modules as we need them.
One of the strategies used by Rails and libraries is Ruby autoload:
module Foo autoload :Bar, "path/to/bar" end
Now, the first time
Foo::Bar is accessed, it will be automatically loaded. The issue with this approach is that it is not thread-safe, except for latest JRuby versions (since 1.7) and Ruby master (2.0).
This means that eager loading these modules on boot (i.e. loading it all up-front) is essential for multi-threaded production servers, otherwise it could lead to scenarios where your application tries to access a module that does not exist yet when it just booted.
In multi-process servers, we may or may not want to eager load them. For instance, if your web server uses fork to handle each request (like Unicorn, Passenger), loading them up-front will become more important as we move towards Ruby 2.0 which will provide copy-on-write semantics. In such cases, if we load
Foo::Bar on boot, we will have one copy of
Foo::Bar shared between all processes otherwise each process will end up loading its own copy of
Foo::Bar possibly leading to higher memory usage.
The downside of eager loading is that we may eventually load code that your application never uses, increasing memory usage. This not a problem if your server uses fork or threads, it is exactly what we want (share and load the most we can), but in case you server doesn’t (for example, Thin) nothing bad is going to happen.
Another strategy used to load code is the one provided by
ActiveSupport::Dependencies. In this mode, you don’t need to specify which module to load and its file, but instead Rails tracks a series of directories and tries to load missing constants based on it.
For instance, when you first access the constant
User, Rails tries to find it in many directories, including
app/models in your application. If a
user.rb exists in it, it is loaded.
This approach is not thread safe, so regardless of using Ruby master or JRuby for a threaded server, it needs to be eager loaded. For multi-process servers, the trade-offs are the same as in the previous section.
So, eager loading
In other words, if you are using Unicorn, Puma, Passenger or any JRuby server, you probably want to eager load. Geez, so it basically means that most of us probably do want to eager load.
Although Rails has been taking care of eager loading its frameworks (defined using Ruby autoload) and its application and engines (defined using Rails autoload), the Rails ecosystem has not taken care of eager loading its libraries. This blame is shared with Rails, which could have provided better mechanisms to do so.
In order to better understand the problem, let’s take a template engine like HAML as an example. If the template engine uses Ruby autoload and it is not eager loaded, one of these things will happen:
On multi-threaded servers, it won’t be thread-safe depending on the Ruby version, leading to crashes on the first requests;
On multi-process servers with fork, HAML will have to be loaded on every request, unnecessarily taking response time and memory on each process instance;
On multi-process servers without fork, it will be loaded when its needed the first time, without extra-hassle;
To avoid problems with 1) and 2), Rails 4 will provide tools and mechanisms to make it easier for libraries to eager load code.
First, Rails 4 will ship with a
config.eager_load option. Today, eager loading an application is coupled with the
config.cache_classes configuration. This means that every time we cache classes, we eager load the app. This is not necessarily the best configuration. For example, in the test environment, an application could benefit by lazily loading the application when running a single test file.
Second, Rails will include a
config.eager_load_namespaces option to allow libraries to register namespaces that Rails should eager load. For instance, for Rails 4, Simple Form will probably execute:
config.eager_load_namespaces << SimpleForm
Rails will invoke
eager_load! on all objects in the
config.eager_load_namespaces list whenever
config.eager_load is set to true. For Simple Form, eager loading will load inputs, form builder and others on boot, instead of loading when they are first used in production.
The idea of registering namespaces (and not blocks) is that a user should be able to remove a namespace from the list if it is causing problems or if they don’t really need to eager load it.
Rails engines and applications will be automatically added to
config.eager_load_namespaces. This is because engines and applications rely on the Rails autoload for everything inside the
app directory, which is not thread-safe and should always run on production.
As an extra, Rails will also provide a convenience module called
ActiveSupport::Autoload to make it easier to define which modules are auto and eager loaded. We’ll see how to use it next.
In order to make your libraries eager load ready, here is an easy recipe:
1) Don’t worry about
app. Everything in
app is automatically taken care by Rails applications and engines since they are always added to
2) If you only use
lib, you are good to go! This is the recommended for Rails applications and small libraries. However, if your library is considerably big, you may want to use Ruby autoload (next step) to avoid loading your library up-front on boot (which affects rake tasks, development, etc).
3) If you are using autoload in
lib, you need to eager load your code. In order to do that, you can use
ActiveSupport::Autoload to annotate which modules to eager load. For example, here is the
SimpleForm module before being eager load ready:
module SimpleForm autoload :Components, 'simple_form/components' autoload :ErrorNotification, 'simple_form/error_notification' autoload :FormBuilder, 'simple_form/form_builder' autoload :Helpers, 'simple_form/helpers' autoload :I18nCache, 'simple_form/i18n_cache' autoload :Inputs, 'simple_form/inputs' autoload :MapType, 'simple_form/map_type' autoload :Wrappers, 'simple_form/wrappers' end
And now eager load ready:
module SimpleForm extend ActiveSupport::Autoload # Helpers are modules that are included on inputs. # Usually we don't need to worry about eager loading # modules because we will usually eager load a class # that uses the module. autoload :Helpers # Wrappers are loaded on boot, it is part of Simple Form # configuration API, so no need to worry about them. autoload :Wrappers # We need to eager load these otherwise they will # be rendered the first time just when a form is # first rendered. eager_autoload do # Notice ActiveSupport::Autoload allows us to skip # the file name as it guesses it from the module. autoload :Components autoload :ErrorNotification autoload :FormBuilder autoload :I18nCache autoload :Inputs autoload :MapType end # ActiveSupport::Autoload automatically defines # an eager_load! method. In this case, we are # extending the method to also eager load the # inputs and components inside Simple Form. def self.eager_load! super SimpleForm::Inputs.eager_load! SimpleForm::Components.eager_load! end end
The comments above explain part of the decision process taken in choosing if a module should be eager loaded or not. To be clear, the question you should be asking is: “if I don’t eager load this module, when will it be autoloaded”? If the answer is: “during a request”, you have to eager load it.
This is the reason we don’t need to eager load something like
ActionController::Base. Because Rails already eager loads your models, controllers, etc and if you are actually using Action Controller, you will have a controller inheriting from
ActionController::Base which then forces it to be loaded on boot.
Similar reasoning applies to most of Active Model modules. There is no need to eager load
ActiveModel::Validations because if an application is using it, it will load a framework or a model that actually requires it on boot. You will find that this reasoning will probably apply to most modules in your library.
After defining your eager loads, all you need to do is to define a Railtie and include your eager load namespace in it:
module SimpleForm class Railtie < Rails::Railtie config.eager_load_namespaces << SimpleForm end end
Although Ruby is moving to a direction where autoload is threadsafe, which makes eager load not a requirement, improvements to the language, garbage collectors and web-servers make eager load a “nice to have” feature.
Today, it is very likely that you want to eager load the majority of your code when deploying applications to production. Although Rails has always been eager load friendly, the majority of the tools in the ecosystem are not. Rails 4 will change this panorama by not only giving flexible configuration options to app developers but also convenient abstraction for library developers.
The general recommendation is to use
require to load code inside the
lib directory if the project is small. Engines and applications do not need to worry about the
app directory, since it is automatically taken care by Rails.
The more complex libraries probably already use autoload in the
lib directory to avoid loading unnecessary amount of code in development. In such cases they need to provide custom
eager_load! instructions for productions environment, which can be done with the help of the recipe above and Rails modules.
This blog post ended up too long but the subject is important and should be considered with care by the authors who maintain the most used libraries out there. Cheers to them!
Besides the big and shiny features that Rails 4 holds, there’s a lot of small improvements on several other sections of the Rails framework – helpers, core extensions, app configurations and more – that might not even hit the Changelogs but will somehow make our lifes easier in the future. One of these hidden gems that I’ve found recently is an improvement on the
content_for helper to flush and replace previous chunks of HTML with new ones.
content_for that we are used to
content_for method is an old friend of every Rails developer, and it’s a pretty simple and flexible helper. You can store a chunk of HTML from a String or a block, and grab it somewhere else in your views or
yield it directly into your templates. It’s a pretty handy trick to move data from your views into your layouts, like page titles, custom meta tags or specific
script tags that your page needs to include.
# On your 'application.html.erb' layout, inside the '<head>' tag. <%= yield :metatags %> # Then, into a specific view <% content_for :metatags do %> <meta property="og:image" content="http://example.com/image.jpg" /> <% end %>
Multiple calls of the
content_for helper using the same identifier will concatenate them and output them together when you read it back on your views, as:
<% content_for :example, "This will be rendered" %> <% content_for :example do %> <h1>This will be rendered too!</h1> <% end %>
On some scenarios this behavior might not be desired, and with Rails 4 you can flush out the stored pieces of an identifier and replace it instead of adding more content to it: using the
flush: true option. The first implementation used an extra
true argument, but we changed to use a Hash instead, so the
flush key can express better the behavior we’re expecting.
<% content_for :example, "This will be rendered" %> <% content_for :example, flush: true do %> <h1>But this will override everything on the ':example' block.</h1> <% end %>
The gallery situation
I’ve stumbled upon this on a recent project, where we had a somewhat classic scenario: a partial named
_gallery, responsible for rendering the piece of HTML to display a gallery of images that also supplies a
content_for block with a
script tag to include the required libraries to put the gallery to work.
It works like a charm. But with an updated requirement we had the case where multiple galleries could be present on the same page, rendering the
_gallery partial several times. The required HTML would be present, but the
gallery.js script would be included multiple times into the rendered page. Instead of working this out using instance variables to check that the partial was rendered at least once, we could let Rails do all the hard work for us, using the
flush option when including the
Back to the present: Rails 3.2
Well, while this seems to be a perfect solution to my problem, this feature isn’t available on Rails 3.2 or on the
3-2-stable branch – it’s only available on the
master branch that will be released with Rails 4. But, backporting this feature into a 3.x application is pretty simple, using a helper of your own.
def single_content_for(name, content = nil, &block) @view_flow.set(name, ActiveSupport::SafeBuffer.new) content_for(name, content, &block) end
After some source diving into the ActionPack source code we’re done – it just needs to replace any present content with a brand new
SafeBuffer instance before storing the piece of HTML.
What do you think about this little addition to Rails 4? Can you think of a similar problem that could be solved with this instead of a custom hack?
I’d like to start with a question: Have you ever seen code like this?
class User < ActiveRecord::Base end User.new.tap do |user| user.name = "John Doe" user.username = "john.doe" user.password = "john123" end
I have. But what few developers know is that many methods in Active Record already accept a block, so you don’t need to invoke
tap in the first place. And that’s all because Active Record loves blocks! Let’s go through some examples.
Using blocks with Active Record
When creating an Active Record object, either by using
create!, you can give a block straight to the method call instead of relying on
User.new do |user| user.name = "John Doe" user.username = "john.doe" user.password = "john123" end User.create do |user| user.name = "John Doe" user.username = "john.doe" user.password = "john123" end
And you can mix and match with hash initialization:
User.new(name: "John Doe") do |user| user.username = "john.doe" user.password = "john123" end
All these methods, when receiving a block,
yield the current object to the block so that you can do whatever you want with it. It’s basically the same effect as using
tap. And it all happens after the attributes hash have been assigned and other internal Active Record code has been run during the object initialization, except by the
That’s neat. That means we can stop using
tap in a few places now. But wait, there’s more.
Active Record associations also love blocks
We talked about using blocks when building an Active Record object using
create, but associations like
has_many also work with that, when calling
create on them:
class User < ActiveRecord::Base has_many :posts end class Post < ActiveRecord::Base belongs_to :user end # has_many user = User.first user.posts.build do |post| post.title = "Active Record <3 Blocks" post.body = "I can give tap a break! <3 <3 <3" end # belongs_to post = Post.first post.build_user do |user| user.name = "John Doe <3 blocks" user.username = "john.doe" user.password = "john123" end
That’s even better. That means we can stop using
tap in a few more places.
Wrapping up: Active Record <3 blocks
It is possible to avoid extra work, sometimes simple stuff such as using
tap with methods like
create, other times more complicated ones, by getting to know what the framework can give us for free.
There are other places inside Active Record that accept blocks, for instance
first_or_initialize and friends will execute the given block when the record is not found, to initialize the new one.
In short, next time you need a block when creating records using Active Record, take a minute to see if you can avoid using
tap by using an already existing feature. Remember: Active Record <3 blocks. And don’t do that with blocks only, the main idea here is that you can learn more about the framework, and let it do more work for you.
How about you, do you have any small trick in Ruby or Rails that makes your work easier? Take a minute to share it with others in the comments.