Archive for May, 2012

Last week, while developing a feature I had some code like this in a view:

link_to_unless @post.url.blank?, "Link to post", @post.url

Where url is an attribute of type String. As people usually don’t like negative conditionals, we can easily rewrite this code as:

link_to_if @post.url.present?, "Link to post", @post.url

However, we can clean our code a little bit using the #{attribute}? method.

link_to_if @post.url?, "Link to post", @post.url

The #{attribute}? method is a method defined automatically by Active Record. Intuitively, you may think that it is equivalent to !!url and then would evaluate to true when an empty string, but Rails is smart enough to detect that the attribute is a string and returns the equivalent of !url.blank?, as you may see in these lines in Rails source code, which proved itself very useful.

Active Record defines many other attribute methods like that, for example url_changed?. What about you? What is your favorite Rails attribute method?

A BlueVia, Evernote e a Wayra estão organizando um Hackaton para gerar novas idéias e serviços, especialmente àqueles focados em usuários de “feature phones”, para assim aumentar a inclusão digital daqueles que ainda não possuem um smartfone.

As equipes BlueVia e Evernote estarão presentes para ajudar os participantes desta hackathon a conectar suas criações. Evernote, a plataforma global para a memória humana, fornece APIs web e clientes mobile para qualquer um registrar seus pensamentos e BlueVia fornece APIs web simples permitindo aos desenvolvedores rapidamente plugar poderosos serviços de rede mobile como mensagens e cobrança.

Mais importante que ganhar a premiação, os participatens do Hackaton contribuirão para que milhões de pessoas possam acessar a riqueza de informações na Internet que atualmente não conseguem usufruir. Não espere mais, inscreva sua equipe e faça a diferença, além de concorrer aos prêmios de R$6.000,00 e a viagem ao Vale do Silício!

O que: Hackathon BlueVia, Evernote e Wayra
Quando: 26 e 27 de maio
Onde: Wayra Academy São Paulo (região da Berrini)

Inscrições e outras informações em http://blog.bluevia.com/bew-hackathon-2012/?lang=pt-br

Boa sorte! ;)

It is no secret that our team has a great passion for contributing to the open source community and once in a while we receive compliments – it is great to have our work recognized; thank you all for always being supportive. =D

We’d proudly like to announce that, due to their contributions, two specific members of our team were recently awarded by the Ruby on Rails community (by the Rails Core Team, to be more precise).

Without further ado we’d like to congratulate our fellow Carlos Antonio (@cantoniodasilva) and Rafael França (@rafaelfranca) for honorably earning the commit access to the Ruby on Rails repository!

@cantoniodasilva and @rafaelfranca

Guys, congratulations! \o/

We are all very happy for this great achievement. Great work!
From your friends at Plataformatec.

After 4 months of our last major version release, we’re releasing Devise 2.1.0, which includes several bug fixes, some new features and the removal of features deprecated on Devise 2.0. If you’re eager to do the update, please check Devise’s wiki page about Upgrading from 2.0 to 2.1. You can also check the changelog or the commits between 2.0.4 and 2.1.0.

Encrytable is now a gem

As it was only used for old encryption algorithms like sha1 or md5, we have extracted encryptable module to a separated ruby gem. So, if you’re using the encryptable module, you should only require it on your Gemfile and you’re good to go!

Check fields

To allow a developer to cherry-pick which features they want to add to their models, Devise splits its behaviors into modules. One of the consequences of such splitting is that you don’t know if the persistence layer provides all fields required by the behavior. For example, the database authenticatable module requires a encrypted_password field. If the field does not exist, you will end up getting an error during a request. Usually those fields are automatically added to the migration when you call the devise generator, but if you decide to include a module after, you can easily forget to add the new fields.

That said, in order to provide faster feedback, Devise now has a method that checks if a given class is missing any of the required fields and raises an error if so. You can call this method as follow (in case your Devise class is User):

Devise::Models.check_fields!(User)

We’ve implemented this feature in an agnostic way, to not depend on a specific ORM, but only to verify if the instance responds to the required fields. So even if your ORM does everything through method_missing, you should be able to use this method (we’re relying that you also have implemented a working respond_to?, which is strongly recommendeded when using method_missing).

When check_fields! is called, Devise will detect the included modules in the given class and, if there is a missing attribute, it will raise a Devise::Models::MissingAttribute exception with a message telling you all required fields that doesn’t exist. You can easily use that method with your favorite test framework:

Devise::Models.check_fields!(User)

And then you will be able to check if your migrations have added the correct fields to your database.

A message to module maintainers

If you’re a maintainer of a Devise module, you should add a method to each of your modules called self.required_fields(klass) that returns an array of required fields. If the method is absent, you will get a deprecation warning.

UPDATE: Fixed a class name and corrected a grammar error.

Today I want to show you a project I’ve started over a year ago, during Mendicant University core skills course. For those who don’t know, Mendicant University is a group of skilled software developers that offer courses, mentoring, and help out the community, started by Gregory Brown, and that nowadays counts with some other awesome folks as part of the staff. I highly recommend taking a look at and enrolling.

Back to I18n, during Mendicant University we were supposed to create a project in Ruby, not specifically with Rails, and I decided to scratch my own itch by trying to solve a problem we usually have in Brazil: receiving date/time/numeric input from user interface. I know and have already used the delocalized gem, and it works quite nice, but sometimes I felt a bit uncomfortable about how it handled some parts of localization/parsing. This is mainly due to the need to monkey patch both ActiveRecord to handle input, and ActionView to handle output. Besides that, and most important, I had to come up with some project and I thought that’d be a good challenge :D.

The main goal of this project is to provide a proxy object to use with your ORM (currently ActiveRecord only) that will be responsible for localizing and parsing the date/time/numeric attributes when getting or setting their values, respectively. Lets see some quick examples:

# Include the proxy in your model
class Product < ActiveRecord::Base
  include I18n::Alchemy
end
 
# Grab your object from the database
@product   = Product.first
# Instantiate the localized proxy
@localized = @product.localized

Now that we have a localized proxy for the @product object, we can get/set numeric attributes with localized values, such as:

@localized.price = "1.99"
 
@product.price   # => 1.99
@localized.price # => "1.99"
 
I18n.with_locale :pt do
  @localized.price = "1,88"
 
  @product.price   # => 1.88
  @localized.price # => "1,88"
end

And also date/time attributes, for instance:

@localized.released_at = "12/31/2011"
 
@product.released_at   # => Date.new(2011, 12, 31)
@localized.released_at # => "12/31/2011"
 
I18n.with_locale :pt do
  @localized.released_at = "31/12/2011"
 
  @product.released_at   # => Date.new(2011, 12, 31)
  @localized.released_at # => "31/12/2011"
end

I18n Alchemy can also receive a hash of attributes, the same way you use with your models when calling new. That means you can use it like this:

# You could be using params[:product] for instance.
I18n.with_locale :pt do
  @localized = @product.localized(:price => "1,88") 
 
  @product.price   # => 1.88
  @localized.price # => "1,88"
end

The parsing/localization formats are basically the same ones you already use in your Rails application. You can check the basic locale configuration for I18n Alchemy in its README on github.

Wrapping up

I18n Alchemy is a small and new project which solves most of the problems we commonly face when dealing with localization and parsing of date/time/numeric values. It is tested with Rails 3.0, 3.1 and 3.2 and works with all the basic methods, such as attributes=, assign_attributes, update_attributes and nested attributes as well.

It was a really fun time creating it during Mendicant University, and it took a long time until I decided to release it as a gem. There is still a bunch of things to do, but I wanted to ask you to give it a try and let me know about any feedback you have.

As a side note, if you are interested in knowing more about the design decisions that led this project, you may want to take a look at Gregory Brown’s post on Ruby Best Practices, entitled “Issue #23: SOLID Design Principles”, more specifically in the Open/closed principle topic.

I’m releasing the first 0.0.1 version today, and I hope you find it useful. Have any comments? Let us know!