Posts by Carlos Antônio

When we start programming with Ruby, one of the first niceties we learn about are the Ruby blocks. In the beginning it’s easy to get tricked by the two existing forms of blocks and when to use each:

%w(a b c).each { |char| puts char }
%w(a b c).each do |char| puts char end

The Ruby Community has sort of created a “guideline” for when to use one versus another: for short or inline blocks, use curly brackets {..}, for longer or multiline blocks, use the do..end format. But did you know there is actually a slight difference between them? So sit tight, we’ll cover it now.

Operators Precedence

Languages contain operators, and these operators must obey a precedence rule so that the interpreter knows the order of execution, which means one operator will be executed first if it has higher precedence than others in a piece of code. Consider the following example:

a || b && c

What operation gets executed first, a || b, or b && c? This is where operator precedence takes action. In this case, the code is the same as this:

a || (b && c)

Which means && has higher precedence than || in Ruby. However, if you want the condition a || b to be evaluated first, you can enforce it with the use of ():

(a || b) && c

This way you are explicitly telling the interpreter that the condition inside the () should be executed first.

What about blocks?

It turns out blocks have precedence too! Lets see an example that mimics the Rails router with the redirect method:

def get(path, options = {}, &block)
  puts "get received block? #{block_given?}"
end
 
def redirect(&block)
  puts "redirect received block? #{block_given?}"
end
 
puts '=> brackets { }'
get 'eggs', to: redirect { 'eggs and bacon' }
 
puts
 
puts '=> do..end'
get 'eggs', to: redirect do 'eggs and bacon' end

This example shows a rather common code in Rails apps: a get route that redirects to some other route in the app (some arguments from the real redirect block were omitted for clarity). And all these methods do is outputting whether they received a block or not.

At a glance these two calls to get + redirect could be considered exact the same, however they behave differently because of the blocks precedence. Can you guess what’s the output? Take a look:

=> brackets {..}
redirect received block? true
get received block? false
 
=> do..end
redirect received block? false
get received block? true

The curly brackets have higher precedence than the do..end, which means the block with {..} will attach to the inner method, in this example redirect, whereas the do..end will attach to the outer method, get.

Wrapping up

This blog post originated from a real Rails issue, where you can read a little bit more about the subject and see that even Rails got it wrong in its documentation (which is now fixed). The precedence is a subtle but important difference between {..} and do..end blocks, so be careful not to be caught off guard by it.

Do you know any other interesting fact about Ruby blocks that people may not be aware of? Or maybe you learned something tricky about Ruby recently? Please share it on the comments section, we would love to hear.


This year’s RailsConf was held in Chicago, from April 22 to 25, and Plataformatec was there, as in previous years, and this time it was represented by George Guimarães, Lucas Mazza, Rafael França, and myself included. Even though I’ve attended the last 5 RubyConf / Rails Summit here in Brazil, this was my first time at RailsConf in the US, and I have only one word to TL;DR it: awesome.

Chicago is a welcoming city, there are lots of nice tourist attractions to visit, and the conference was a great opportunity to meet new people, share ideas, collaborate, and learn new things from the well selected list of talks. But all of this is quite hard to explain in words, so I’ll go with the a picture is worth a thousand words motto and show you a series of pictures, hopefully they will show you better what I mean.

The conference

The highlight of the first day was DHH’s keynote about clarity, patterns and TDD, which sparked many conversations/discussions during the day. Farrah Bostic also gave a nice keynote at the end of the day, entitled What Happens to Everyone, When Everyone Learns to Code, which added even more to the topic DHH had covered.

RailsConf 2014 - DHH's keynote - TDD

RailsConf 2014 - Plataformatec

In the second day I was a bit nervous, since I was going to give my very first talk in English, Tricks that Rails didn’t tell you about. I received awesome feedback from a lot of people after the talk and in the following days of the event, thank you everyone for that <3. You can check the embedded slides at the end of this post.

RailsConf 2014 - Tricks that Rails didn't tell you about

By afternoon we participated in the Community Office Hours sponsored by Heroku, where we gathered a lot of Rails Contributors to answer questions and help the community with any Rails issue they could be having. It was an opportunity to talk to different people and understand how they use the framework and the real problems they have, but it was not a very busy time for everyone, so some contributors had time to sit together and hack some stuff. What came out of that is a script to label stale issues on the Rails repository, marking them to be closed later in case no feedback is given in a timely fashion. Great stuff.

RailsConf 2014 - Community Office Hours - Rails Contributors

On Wednesday night we went to the Basecamp Open House event, and we took the opportunity to take a picture of most of the Rails Contributors present at RailsConf.

RailsConf 2014 - Rails Contributors

But we missed some folks on this picture, so we decided to take another. However, DHH was not present anymore, thankfully we had someone skilled enough to draw his double:

RailsConf 2014 - Rails Contributors and DHH double

The third day was very important for us, but specially for my friend and coworker Rafael França: he got a Ruby Hero award <3 <3 <3.

RailsConf 2014 - Ruby Hero Award - Rafael França

As most of you probably know, Rafael has been doing an amazing work with Rails and all the surrounding environment, working on all fronts, solving issues, releasing gems, and being super present on discussions everywhere you can think of. Besides that, he dedicates some time to maintain our Open Source projects, for example lately he did some work to add Bootstrap 3 support to Simple Form (check the latest 3.1.0.rc1 version :D).

RailsConf 2014 - Ruby Hero Award - Rafael França

You deserve it, congratulations!

On Thursday afternoon we had the second turn of the Community Office Hours, this time it was busier and we were able to help many developers having issues. I hope we can do something like that during the next RubyConf Brazil. At night we went to Code Climate’s after party and had some beers. Rafael returned to Brazil on this day, heading to Recife for the Abril Pro Ruby conference where he was speaking (expect another blog post on this soon).

On the last day the closing keynote was a super awesome talk by @tenderlove, where he showed us that there’s a real need for science on our work, and then he merged AdequateRecord to Rails master while on stage! Well, not really on stage, but it’s merged :D. We also handed on our last Devise, Simple Form, Elixir, and Hacking Beautiful Code stickers. If you got one, please tweet a picture to @plataformatec, we’ll appreciate that.

Devise, Simple Form, Elixir, Hacking Beautiful Code stickers

Devise, Simple Form, Elixir, Hacking Beautiful Code stickers

Finally, on Friday night we met with our friend David Chelimsky for a night of conversation and brazilian music on a place called Revolver. It was the perfect night to close the conference.

RailsConf 2014 - David Chelimsky

The tourism

We arrived a couple of days before the event, and left the Sunday after, so we had some free time to visit Chicago and enjoy some tourist stuff.

We started by visiting the Skydeck on Saturday night. It was a breathtaking view, I had never seen anything like that before, it’s super worth the visit.

RailsConf 2014 - Skydeck

On Sunday we went to the Navy Pier, and did the architectural tour. We spent almost 1h30 hour learning about Chicago, its architecture, the great fire, batman, transformers, and much more, definitely recommended.

RailsConf 2014 - Navy Pier

After the Pier we decided to go to the Shedd Aquarium. Most of us had never been to an aquarium before, and it was such a great experience. You never know what you can find under the water, right?

RailsConf 2014 - Shedd Aquarium - Octopus

RailsConf 2014 - Shedd Aquarium - Penguins

We were very tired at this point but wanted more, so we went to the Adler Planetarium, which was unfortunately about to close – it was around 5PM. So we took a picture that could be easily transformed into a music album cover, and headed to a nice coffee place near the Millenium Park.

RailsConf 2014 - Plataformatec Music Album Cover

We couldn’t go back to the hotel without taking the famous picture on “The Bean” steel sculpture in the Millenium Park, so here it is:

RailsConf 2014 - Millenium Park - The Bean

Monday, the day before the conference, was marked by the visit to the Adler Planetarium (we made it!), which is a cool place to go if you enjoy such things as we do.

RailsConf 2014 - Adler Planetarium

We also went to the Field Museum, which is another must place to go, where you can easily get lost in all those sections, it seems like a big maze, but it’s very enjoyable to walk through and learn more about all kinds of history. And we closed the day having dinner with some Rails Contributors and Basecamp folks.

RailsConf 2014 - Field Museum - T-Rex

Finally, on the Saturday after the conference we did some Shopping, and during the afternoon George and Lucas went to a Comic Conference that was happening in Chicago.

Besides that, I couldn’t end this post without commenting about the great breakfasts we had, I think I can say with certainty that we all particularly enjoyed these two places: Eggsperience Pancakes & Cafe and Meli Cafe. Definitely recommended.

RailsConf 2014 - Breakfast

There’s nothing like eggs & bacon to start your day :).

Wrapping up

I hope I could show you at least a little bit how RailsConf was awesome for us. Conferences are always great to do networking, and RailsConf in particular allowed us to share and collaborate a lot with other people from the community. I like to think this is the main point of events like that, it’s where most of the good things come from, sharing and discussing ideas.

And Chicago is really a great city for tourism, there are lots of nice places to go, hopefully I will be able to go back there someday, visit some of these again and some other places, plus visiting some of the folks we met from Chicago would be cool too.

Here are the slides of my talk, Tricks that Rails didn’t tell you about:

I’ll update this post with the video as soon as it is online. In addition to that, we’ll be preparing another blog post with some of the talks we enjoyed the most after the videos are available, so we can link everything properly.

I want to thank again everyone that came to talk to me or tweeted about about my talk, I really appreciate every single feedback I’ve received. And also thanks to everyone who came to say thanks for our Open Source projects, we appreciate it a lot, it keeps us motivated to work more and more on these projects so that everyone can benefit from them.

How about you? Did you go to RailsConf? Did you enjoy it? Or are you planning to go next year? Remember, it’ll be in Atlanta, hopefully we’ll see you there.

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

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

Devise stable

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

Simple Form

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

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

Responders

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

Show For

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

Mail Form

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

Has Scope

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

Compatibility

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

Wrapping up

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

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

Enjoy <3

Here at Plataformatec we use Github Pull Requests a lot for code review and this usually yields tons of constructive comments and excellent discussions from time to time. One of the recent topics was about whether we should use scopes or class methods throughout the project to be consistent. It’s also not hard to find discussions about it all over the internet. The classic comment usually boils down to “there is no difference between them” or “it is a matter of taste”. I tend to agree with both sentences, but I’d like to show some slight differences that exist between both.

Defining a scope

First of all, lets get a better understanding about how scopes are used. In Rails 3 you can define a scope in two ways:

class Post < ActiveRecord::Base
  scope :published, where(status: 'published')
  scope :draft, -> { where(status: 'draft') } 
end

The main difference between both usages is that the :published condition is evaluated when the class is first loaded, whereas the :draft one is lazy evaluated when it is called. Because of that, in Rails 4 the first way is going to be deprecated which means you will always need to declare scopes with a callable object as argument. This is to avoid issues when trying to declare a scope with some sort of Time argument:

class Post < ActiveRecord::Base
  scope :published_last_week, where('published_at >= ?', 1.week.ago)
end

Because this won’t work as expected: 1.week.ago will be evaluated when the class is loaded, not every time the scope is called.

Scopes are just class methods

Internally Active Record converts a scope into a class method. Conceptually, its simplified implementation in Rails master looks something like this:

def self.scope(name, body)
  singleton_class.send(:define_method, name, &body)
end

Which ends up as a class method with the given name and body, like this:

def self.published
  where(status: 'published')
end

And I think that’s why most people think: “Why should I use a scope if it is just syntax sugar for a class method?”. So here are some interesting examples for you to think about.

Scopes are always chainable

Lets use the following scenario: users will be able to filter posts by statuses, ordering by most recent updated ones. Simple enough, lets write scopes for that:

class Post < ActiveRecord::Base
  scope :by_status, -> status { where(status: status) }
  scope :recent, -> { order("posts.updated_at DESC") }
end

And we can call them freely like this:

Post.by_status('published').recent
# SELECT "posts".* FROM "posts" WHERE "posts"."status" = 'published' 
#   ORDER BY posts.updated_at DESC

Or with a user provided param:

Post.by_status(params[:status]).recent
# SELECT "posts".* FROM "posts" WHERE "posts"."status" = 'published' 
#   ORDER BY posts.updated_at DESC

So far, so good. Now lets move them to class methods, just for the sake of comparing:

class Post < ActiveRecord::Base
  def self.by_status(status)
    where(status: status)
  end
 
  def self.recent
    order("posts.updated_at DESC")
  end
end

Besides using a few extra lines, no big improvements. But now what happens if the :status parameter is nil or blank?

Post.by_status(nil).recent
# SELECT "posts".* FROM "posts" WHERE "posts"."status" IS NULL 
#   ORDER BY posts.updated_at DESC
 
Post.by_status('').recent
# SELECT "posts".* FROM "posts" WHERE "posts"."status" = '' 
#   ORDER BY posts.updated_at DESC

Oooops, I don’t think we wanted to allow these queries, did we? With scopes, we can easily fix that by adding a presence condition to our scope:

scope :by_status, -> status { where(status: status) if status.present? }

There we go:

Post.by_status(nil).recent
# SELECT "posts".* FROM "posts" ORDER BY posts.updated_at DESC
 
Post.by_status('').recent
# SELECT "posts".* FROM "posts" ORDER BY posts.updated_at DESC

Awesome. Now lets try to do the same with our beloved class method:

class Post < ActiveRecord::Base
  def self.by_status(status)
    where(status: status) if status.present?
  end
end

Running this:

Post.by_status('').recent
NoMethodError: undefined method `recent' for nil:NilClass

And :bomb:. The difference is that a scope will always return a relation, whereas our simple class method implementation will not. The class method should look like this instead:

def self.by_status(status)
  if status.present?
    where(status: status)
  else
    all
  end
end

Notice that I’m returning all for the nil/blank case, which in Rails 4 returns a relation (it previously returned the Array of items from the database). In Rails 3.2.x, you should use scoped there instead. And there we go:

Post.by_status('').recent
# SELECT "posts".* FROM "posts" ORDER BY posts.updated_at DESC

So the advice here is: never return nil from a class method that should work like a scope, otherwise you’re breaking the chainability condition implied by scopes, that always return a relation.

Scopes are extensible

Lets get pagination as our next example and I’m going to use the kaminari gem as basis. The most important thing you need to do when paginating a collection is to tell which page you want to fetch:

Post.page(2)

After doing that you might want to say how many records per page you want:

Post.page(2).per(15)

And you may to know the total number of pages, or whether you are in the first or last page:

posts = Post.page(2)
posts.total_pages # => 2
posts.first_page? # => false
posts.last_page?  # => true

This all makes sense when we call things in this order, but it doesn’t make any sense to call these methods in a collection that is not paginated, does it? When you write scopes, you can add specific extensions that will only be available in your object if that scope is called. In case of kaminari, it only adds the page scope to your Active Record models, and relies on the scope extensions feature to add all other functionality when page is called. Conceptually, the code would look like this:

scope :page, -> num { # some limit + offset logic here for pagination } do
  def per(num)
    # more logic here
  end
 
  def total_pages
    # some more here
  end
 
  def first_page?
    # and a bit more
  end
 
  def last_page?
    # and so on
  end
end

Scope extensions is a powerful and flexible technique to have in our toolchain. But of course, we can always go wild and get all that with class methods too:

def self.page(num)
  scope = # some limit + offset logic here for pagination
  scope.extend PaginationExtensions
  scope
end
 
module PaginationExtensions
  def per(num)
    # more logic here
  end
 
  def total_pages
    # some more here
  end
 
  def first_page?
    # and a bit more
  end
 
  def last_page?
    # and so on
  end
end

It is a bit more verbose than using a scope, but it yields the same results. And the advice here is: pick what works better for you but make sure you know what the framework provides before reinventing the wheel.

Wrapping up

I personally tend to use scopes when the logic is very small, for simple where/order clauses, and class methods when it involves a bit more complexity, but whether it receives an argument or not doesn’t really matter much to me. I also tend to rely more on scopes when doing extensions like showed here, since it’s a feature that Active Record already gives us for free.

I think it’s important to clarify the main differences between scopes and class methods, so that you can pick the right tool for the job™, or the tool that makes you more comfortable. Whether you use one or another, I don’t think it really matters, as long as you write them clear and consistently throughout your application.

Do you have any thought about using scopes vs class methods? Make sure to leave a comment below telling us what you think, we’d love to hear.

Nos dias 30 e 31 de Agosto de 2012, aconteceu o maior evento de Ruby da América Latina: a RubyConf Brasil, e a Plataformatec marcou presença com palestras e lightning talks. O evento foi um sucesso, com mais de 750 participantes durante a conferência, e mais de 500 pessoas assistindo o evento online através do site da Eventials.

Plataformatec Team

Abaixo você pode ver os temas, com links para os slides e vídeos:

Palestras

Vamos falar sobre Concorrência

Por José Valim. Confira o vídeo.

Escrevendo Aplicações Melhores com Active Model

Por Carlos Antonio. Confira o vídeo.

Conhecendo as Entranhas do Rails

Por Rafael França. Confira o vídeo.

Lightning Talks

Contribuindo para o Rails

Por Carlos Galdino.

I18nAlchemy

Por Lucas Mazza.

Copyright, Licenças Open Source e você!

Por George Guimarães.

Confira o vídeo das Lightning Talks.

Sinta-se à vontade para ver e rever os slides e vídeos das palestras, e nos passar seu feedback através dos comentários. Não deixe também de conferir as outras palestras disponíveis, e se você escreveu um post sobre o evento em seu blog, adoraríamos ver um comentário com um link compartilhando seu post.

Gostaríamos também de agradecer e parabenizar o Fábio Akita e a Locaweb pela ótima organização e alta qualidade do evento, tudo funcionou perfeitamente para que todos pudessem aproveitar ao máximo a conferência.

E nos vemos na RubyConf Brasil 2013!

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 new or create/create!, you can give a block straight to the method call instead of relying on tap:

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 after_initialize callbacks.

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 new or create, but associations like belongs_to or has_many also work with that, when calling build or 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 new and 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. :)