Edge Rails: Bug no submit_tag corrigido

20 de outubro de 2008  |  Rails 2.2  |  Nenhum comentário  | 

Quando usávamos o método submit_tag com a opção :disable_with ligada, ele suprimia o parâmetro :commit quando o formulário era enviado para o servidor. Isto acontecia porque após submeter o formulário, o javascript do evento onclick primeiro desabilita o botão e só depois envia o formulário ao servidor, e como sabemos campos desabilitados não são enviados no submit.

Isto representava um problema para os casos onde o formulário possuía mais de um submit_tag e a sua lógica de atualização/criação dependia do valor do parâmetro :commit para fazer alguma coisa.

Este problema foi corrigido incluindo um código no inicio do javascript que copia o valor deste parâmetro para um campo hidden no formulário e o envia para o servidor mesmo com o botão desabilitado.


Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Mais um finder dinâmico

7 de outubro de 2008  |  Rails 2.2  |  2 Comentários  | 

Aumentando o número de finders dinâmicos do ActiveRecord, agora temos o find_last_by. Já tinhamos os famosos find_by e o find_all_by.

Além de simplificar, ficou muito mais elegante recuperar o último comentário feito por um usuário, por exemplo. Veja:

Comment.find_last_by_author("Carlos Brando")

Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Benchmarking reports em milisegundos

6 de outubro de 2008  |  Rails 2.2  |  Nenhum comentário  | 

Todas as mensagens de log que continham uma indicação do tempo que determinado processo levou para ser executado, foram alteradas para exibir o tempo em milisegundos.

Por exemplo, a mensagem:

Completed in 0.10000 (4 reqs/sec) | Rendering: 0.04000 (40%) | DB: 0.00400 (4%) | 200 OK [http://example.com]

Agora será exibida da seguinte forma:

Completed in 100ms (View: 40, DB: 4) | 200 OK [http://example.com]

Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Novo método each_with_object

3 de outubro de 2008  |  Rails 2.2  |  4 Comentários  | 

O método each_with_object do Ruby 1.9 foi adicionado ao Rails, caso você ainda não esteja usando a nova versão do Ruby. Este método é bem interessante, pois ele funciona como o conhecido método each, com um pequeno diferencial. Cada iteração além de receber um elemento da coleção, recebe também um objeto que chamamos de memo.

Por exemplo, vamos dizer que eu pretenda preencher um hash com valores de uma coleção:

%w(first second third).each_with_object({}) do |str, hash|
  hash[str.to_sym] = str
end
# => {:second=>"second", :first=>"first", :third=>"third"}

Note que no exemplo acima o memo é um hash vazio ({}). Dentro do bloco eu preencho este hash com os itens da minha coleção.

Apenas um alerta: Não podemos usar objetos imutáveis como memo, tais como números, true e false. No exemplo abaixo o retorno sempre será 1, já que o número um não pode ser alterado:

(1..5).each_with_object(1) { |value, memo| memo *= value } # => 1

Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Melhorando a performance nos métodos association_ids

2 de outubro de 2008  |  Rails 2.2  |  Nenhum comentário  | 

Se você tiver dois modelos: Post e Comment. Onde Post tem muitos (has_many) comentários. Se você executar:

Post.first.comment_ids

O Rails usará a seguinte query para recuperar os ids:

SELECT * FROM `comments` WHERE (`comments`.post_id = 1)

Mas neste caso, não precisamos dos objetos inteiros. A seguinte query seria mais do que suficiente para o funcionamento deste método, além de possuir uma performance melhor:

SELECT `comments`.id FROM `comments` WHERE (`comments`.post_id = 1)

Tanto para associações has_many, como para associações has_many :through o código foi alterado para incluir esta melhora de performance a partir do Rails 2.2.


Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Partials não vão mais definir as variáveis locais implicitamente

29 de setembro de 2008  |  Rails 2.2  |  2 Comentários  | 

No exemplo abaixo estou renderizando uma partial, e não estou informando qual variável ela deve usar para preencher o conteúdo. Hoje o Rails encara que como tenho uma variável de instância com o mesmo nome, implicitamente é esta que deve ser usada.

@customer = Customer.new("Carlos Brando")
render :partial => "customer"

Isto funciona mas é um pouco arriscado. A partir do Rails 2.2, esta funcionalidade continua funcionando mas sempre emitindo uma aviso de que será por pouco tempo:

@customer will no longer be implicitly assigned to customer

Sim, este recurso será removido do Rails no futuro.


Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Correção de bug no método count do ActiveRecord

28 de setembro de 2008  |  Rails 2.2  |  2 Comentários  | 

Existe um bug no método count do ActiveRecord quando usamos uma associação has_many em conjunto com a opção :limit ou :offset. Vejamos um exemplo:

class Post < ActiveRecord::Base
  has_many :comments, :limit=> 2
end

No código acima quando tentarmos recuperar os comentários de um post, apenas 2 comentários devem ser retornados.

post.comments.length # => 2

# Veja o SQL usado:
# SELECT * FROM "comments" WHERE
# ("comments".post_id = 1) LIMIT 2

Mas, ao usarmos o método count:

post.comments.count # => 3

# Veja o SQL usado:
# SELECT count(*) AS count_all FROM "comments" WHERE
# ("comments".post_id = 1)

Como você pode ver o erro ocorre porque a clausula LIMIT 2 não foi incluída na query do SQL.

Obviamente isto já foi corrigido no Edge Rails e já estará funcionando no Rails 2.2.


Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Método count do ActiveRecord não inclui um alias para associações

27 de setembro de 2008  |  Rails 2.2  |  Nenhum comentário  | 

Digamos que temos a seguinte associação has_many :through:

class Author < ActiveRecord::Base
  has_many :authorships
  has_many :books, :through => :authorships
end

Ao procurar por um livro você pode incluir a autoria em sua busca:

author.books.find(:all, :include => :authorships,
                  :conditions => ["authorships.primary = ?", true])

Isto funciona muito bem, sem erros. Mas tente fazer o mesmo com o método count:

author.books.count(:include => :authorships,
                   :conditions => ["authorships.primary = ?", true])

Temos um erro. Isto acontece porque a tabela authorships foi incluída duas vezes na mesma query.

O método find é mais esperto, porque ele cria um apelido para a tabela, coisa que o método count não faz. Eu sei que o exemplo dado não é muito bom, mas é apenas para tentar mostrar o problema com o método count.

Esta falha foi corrigida. Agora o método count se comporta exatamente como o método find em relação ao :include.


Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Troca de biblioteca geradora de chaves secretas

26 de setembro de 2008  |  Rails 2.2  |  Nenhum comentário  | 

A classe Rails::SecretKeyGenerator, usada para gerar chaves secretas aleatórias como as usadas para armazenar a sessão do usuário em cookies, está sendo marcada para ser removida do Rails (Deprecate).

Em seu lugar o Rails passará a usar a classe ActiveSupport::SecureRandom que foi feita para o Ruby 1.9. A biblioteca SecureRandom faz a mesma coisa que a anterior, mas um pouco melhor.

Esta nova biblioteca suporta os seguintes geradores de números aleatórios:

  • openssl
  • /dev/urandom
  • Win32

Vejamos alguns exemplos de chaves geradas com esta nova biblioteca:

# random hexadecimal string.
ActiveSupport::SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
ActiveSupport::SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
ActiveSupport::SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8"
ActiveSupport::SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306"
ActiveSupport::SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"

# random base64 string.
ActiveSupport::SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
ActiveSupport::SecureRandom.base64(10) #=> "9b0nsevdwNuM/w=="
ActiveSupport::SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
ActiveSupport::SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY="
ActiveSupport::SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
ActiveSupport::SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg=="

# random binary string.
ActiveSupport::SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
ActiveSupport::SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"

Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.

Edge Rails: Nova versão destrutiva dos métodos de pesquisa do ActiveRecord

25 de setembro de 2008  |  Rails 2.2  |  2 Comentários  | 

Os métodos dinâmicos de pesquisa do ActiveRecord receberam uma versão destrutiva, que dispara um erro do tipo RecordNotFound caso nenhum registro seja encontrado, ao invés de apenas retornar nil como acontece com a versão original.

Para usar esta versão destrutiva, basta adicionar o sinal de exclamação no final do método. Veja um exemplo:

Topic.find_by_title!("The First Topic!")
# => ActiveRecord::RecordNotFound

Esta alteração é muito bem vinda.


Este artigo pertence a série “Edge Rails”. Todos os exemplos dados aqui funcionarão somente no Ruby on Rails 2.2 ou superior. A intenção desta série é preparar antecipadamente os programadores para as próximas versões do framework.