Após algum tempo trabalhando na tradução do Rails 2.3 Release Notes para o projeto de tradução dos Rails Guides, finalmente temos uma versão 100% (faltando alguma revisão, mas vamos lá).

Peço a todos que lerem as notas de lançamento, se encontrarem alguma sentença mal formada, erro de português ou mesmo erro na tradução, por favor postem um comentário informando o problema que terei prazer em analisar e corrigir o que for necessário tanto aqui no post quanto na tradução oficial.

Espero que esta tradução ajude a esclarecer as novidades que o Rails 2.3 está trazendo.

Boa leitura.

Notas de Lançamento do Ruby on Rails 2.3

O Rails 2.3 traz uma variedade de funcionalidades novas e melhoradas, incluindo integração pervasiva com Rack, atualização do suporte aos Rails Engines, transações aninhadas para o Active Record, escopos dinâmicos e padrões, roteamento mais eficiente, templates de aplicação, e backtraces silenciosos. Esta lista abrange as maiores atualizações, mas não inclui cada pequena correção de bug e alteração. Se você quiser visualizar tudo, verifique a lista de commits no repositório principal do Rails no GitHub ou revise os arquivos CHANGELOG para os componentes individuais do Rails.

Arquitetura da Aplicação

Existem duas grandes mudanças na arquitetura das aplicações Rails: integração completa da interface modular para servidores web Rack, e suporte renovado para os Rails Engines.

Integração com o Rack

O Rails agora separou-se do seu passado com CGI, e utiliza o Rack em toda parte. Isto exigiu e resultou em um tremendo número de modificações internas (mas se você usa CGI, não se preocupe; o Rails agora suporta CGI através de uma interface proxy). Ainda assim, esta é uma mudança importante para o Rails internamente. Após atualizar para o 2.3, você deve testar em seu ambiente local e em seu ambiente de produção. Algumas coisas para testar:

  • Sessões
  • Cookies
  • Upload de arquivos
  • APIs JSON/XML

Segue um resumo das mudanças relacionadas ao rack:

  • script/server foi mudado para usar Rack, o que significa que suporta qualquer servidor compatível com Rack. script/server também irá carregar um arquivo de configuração rackup se existir. Por padrão, ele irá procurar um arquivo config.ru, mas você pode sobrescrever isto com o modificador -c.
  • O gerenciador FCGI passa pelo Rack.
  • ActionController::Dispatcher mantém sua própria pilha de middleware padrão. Middlewares podem ser injetados, reordenados, e removidos. A pilha é compilada dentro da cadeia no boot. Você pode configurar a pilha de middleware no environment.rb.
  • A tarefa rake middleware foi adicionada para inspecionar a pilha de middleware. Isto é útil para depurar a ordem da pilha de middleware.
  • O executador de testes de integração foi modificado para executar as pilhas de middleware e da aplicação inteiras. Isto faz os testes de integração perfeitos para testar o middleware Rack.
  • ActionController::CGIHandler é um wrapper para compatibilidade CGI em torno do Rack. O CGIHandler destina-se a pegar um antigo objeto CGI e converter sua informação de ambiente em um formato compatível com Rack.
  • CgiRequest e CgiResponse foram removidos.
  • Sessões agora são carregadas sob demanda (lazy-load). Se você nunca acessar o objeto da sessão durante uma requisição, ele nunca tentará carregar os dados da sessão (analisar cookies, carregar os dados do memcache, ou buscar um objeto Active Record).
  • Você não precisa mais usar CGI::Cookie.new no seus testes para definir um valor para um cookie. Agora associar um valor String para request.cookies[“foo”] seta o cookie como esperado.
  • CGI::Session::CookieStore foi substituído pelo ActionController::Session::CookieStore.
  • CGI::Session::MemCacheStore foi substituído pelo ActionController::Session::MemCacheStore.
  • CGI::Session::ActiveRecordStore foi substituído pelo ActiveRecord::SessionStore.
  • Você ainda pode mudar seu método de armazenamento de sessão com ActionController::Base.session_store = :active_record_store.
  • As opções padrão das sessões ainda são definidas com ActionController::Base.session = { :key => "…" }.
  • O mutex que normalmente envolve toda a requisição foi movido para um middleware, ActionController::Lock.
  • ActionController::AbstractRequest e ActionController::Request foram unificados. O novo ActionController::Request herda de Rack::Request. Isto afeta o acesso ao response.headers['type'] nas requisições de teste. Use no lugar response.content_type.
  • O middleware ActiveRecord::QueryCache é automaticamente inserido dentro da pilha de middleware se o ActiveRecord foi carregado. Este middleware monta e limpa a cache de consultas do Active Record a cada requisição.
  • As classes router e controller do Rails seguem a especificação do Rack. Você pode chamar um controller diretamente com SomeController.call(env). O router armazena os parâmetros de roteamento em rack.routing_args.
  • ActionController::Request herda de Rack::Request.
  • Ao invés de config.action_controller.session = { :session_key => 'foo', … utilize config.action_controller.session = { :key => 'foo', ….
  • Usando o middleware ParamsParser quaisquer requisições XML, JSON, ou YAML são pré-processadas, podendo então ser normalmente lidas com qualquer objeto Rack::Request após isto.
Suporte renovado para Rails Engines

Após algumas versões sem atualização, o Rails 2.3 traz algumas novas funcionalidades para Rails Engines (aplicações Rails que podem ser embutidas dentro de outras aplicações). Primeiro, arquivos de roteamento nos engines são automaticamente carregados e recarregados agora, assim como seu arquivo routes.rb (isto também se aplica a arquivos de roteamento em outros plugins). Segundo, se seu plugin possui um diretório app, então app/[models|controllers|helpers] serão automaticamente adicionados ao load path do Rails. Engines também suportam agora a adição de caminhos para views, e o Action Mailer assim como o Action View usará views dos engines e outros plugins.

Documentação

O projeto Ruby on Rails guides tem publicado vários guias adicionais para o Rails 2.3. Além disso, um site separado mantém cópias atualizadas dos Guias para o Rails Edge. Outros esforços de documentação incluem o relançamento do wiki Rails e o planejamento inicial para um livro de Rails.

Suporte para o Ruby 1.9.1

O Rails 2.3 deve passar por todos os seus próprios testes se você está rodando o Ruby 1.8 ou o recentemente liberado Ruby 1.9.1. No entanto, você deve estar ciente que mudar para o 1.9.1 acarreta checar todos os adaptadores de dados, plugins, e outros códigos que você depende para compatibilidade com o Ruby 1.9.1, assim como o core do Rails.

Active Record

O Active Record recebe um número considerável de novas funcionalidades e correções de bug no Rails 2.3. Os destaques incluem atributos aninhados (nested attributes), transações aninhadas (nested transactions), escopos dinâmicos (dynamic scopes) e padrões (default scopes), e processamento em lote (batch processing).

Atributos Aninhados

O Active Record pode agora atualizar os atributos em modelos aninhados diretamente, desde que você o diga para fazê-lo:

class Book < ActiveRecord::Base
  has_one :author
  has_many :pages

  accepts_nested_attributes_for :author, :pages
end
&#91;/sourcecode&#93;

Ligar os atributos aninhados ativa uma séria de coisas: salvamento automático (e atômico) de um registro juntamente com seus filhos associados, conhecimento das validações nos filhos, e suporte para formulários aninhados (discutidos mais tarde).

Você também pode especificar requerimentos para qualquer novo registro que for adicionado através de atributos aninhados usando a opção <code>:reject_if</code>


accepts_nested_attributes_for :author,
  :reject_if => proc { |attributes| attributes['name'].blank? }
Transações Aninhadas

O Active Record suporta agora transações aninhadas, uma funcionalidade muito requisitada. Agora você pode escrever código como este:

User.transaction do
    User.create(:username => 'Admin')
    User.transaction(:requires_new => true) do
      User.create(:username => 'Regular')
      raise ActiveRecord::Rollback
    end
  end

  User.find(:all)  # => Retorna somente Admin

Transações aninhadas permitem que você cancele uma transação interna sem afetar o estado da transação externa. Se você deseja que uma transação seja aninhada, precisa adicionar explicitamente a opção :requires_new; caso contrário, a transação aninhada simplesmente será parte da transação pai (assim como é atualmente no Rails 2.2). Por baixo dos panos, transações aninhadas estão usando savepoints, portanto elas são suportadas mesmo em bancos de dados que não possuem transações aninhadas reais. Existe também um pouco de mágica acontecendo para fazer com que estas transações funcionem bem com fixtures transacionais durantes os testes.

Escopos Dinâmicos

Você conhece sobre os finders dinâmicos no Rails (que permitem que você concatene métodos como find_by_color_and_flavor dinamicamente). Bem, agora você pode ter métodos de escopo dinâmicos. A idéia é unir sintaxes que permitam filtragem dinâmica e encadeamento de métodos. Por exemplo:

Order.scoped_by_customer_id(12)
Order.scoped_by_customer_id(12).find(:all,
  :conditions => "status = 'open'")
Order.scoped_by_customer_id(12).scoped_by_status("open")

Não há nada para definir o uso de escopos dinâmicos: eles apenas funcionam.

Escopos Padrão

O Rails 2.3 introduzirá a noção de escopos padrão similares aos escopos nomeados (named scopes), mas aplicados a todos os escopos nomeados ou métodos find dentro do modelo. Por exemplo, você pode escrever default_scope :order => 'name ASC' e a qualquer hora que você recuperar registros desse modelo eles retornarão ordenados pelo nome (a menos que você sobrescreva a opção, é claro).

Processamento em Lote

Agora você pode processar um grande número de registros de um model ActiveRecord com menos pressão sobre a memória usando find_in_batches:

Customer.find_in_batches(:conditions => {:active => true}) do |customer_group|
  customer_group.each { |customer| customer.update_account_balance! }
end

Você pode passar a maioria das opções do find para o find_in_batches. Entretanto, você não pode especificar uma ordem para os registros serem retornados (eles sempre retornarão em ordem crescente pela chave primária, que precisa ser um inteiro), ou usar a opção :limit. Ao invés, utilize a opção :batch_size, que tem o padrão de 1000, para definir o número de registros que serão retornados em cada lote.

O novo método find_each proporciona um wrapper em torno do find_in_batches que retorna registros individuais, com o próprio find sendo executado em lotes (de 1000 por padrão):

Customer.find_each do |customer|
  customer.update_account_balance!
end

Note que você só deve utilizar este método para processamento em lote: para números de registros pequenos (menores que 1000), você deve usar só os métodos find regulares com seu próprio loop.

Condições Múltiplas para Callbacks

Quando se usa os callbacks do Active Record, você pode agora combinar opções :if e :unless no mesmo callback, e fornecer condições múltiplas como um array:

before_save :update_credit_rating, :if => :active,
  :unless => [:admin, :cash_only]
  • Contribuidor Líder: L. Caviola
Find com Having

O Rails agora tem uma opção :having no find (assim como nas associações has_many e has_and_belongs_to_many) para filtragem de registros em finds agrupados. Tal como aqueles com backgrounds SQL pesados sabem, isto permite filtros com base em resultados agrupados:

developers =  Developer.find(:all, :group => "salary",
  :having => "sum(salary) >  10000", :select => "salary")
Reconectando Conexões MySQL

O MySQL suporta a flag de reconectar em suas conexões – se definida como verdadeiro, então o cliente tentará reconectar ao servidor antes de desistir no caso de uma conexão perdida. Você pode agora setar reconnect = true para suas conexões MySQL no database.yml para obter este comportamento em uma aplicação Rails. O padrão é false, assim o comportamento das aplicações existentes não muda.

Outras Mundaças no Active Record
  • Um AS extra foi removido do SQL gerado pelo carregamento do has_and_belongs_to_many, melhorando o funcionamento para alguns bancos de dados.
  • ActiveRecord::Base#new_record? agora retorna false ao contrário de nil quando confrontado com um registro existente.
  • Um bug com o nome de tabelas com aspas em algumas associações has_many :through foi corrigido.
  • Você pode agora especificar um timestamp particular para o updated_at: cust = Customer.create(:name => "ABC Industries", :updated_at => 1.day.ago).
  • Melhores mensagens de erro em falhas nos métodos find_by_attribute!.
  • O suporte ao to_xml do Active Record fica um pouco mais flexível com a adição da opção :camelize.
  • Um bug no cancelamento de callbacks a partir do before_update ou before_create foi corrigido.
  • Tarefas rake para bases de teste via JDBC fora adicionadas.
  • validates_length_of usará a mensagem de erro customizada com a opção :in ou :within (se for fornecida).
  • Counts em selects com escopos (scoped selects) agora funcionam corretamente, assim você pode fazer coisas como Account.scoped(:select => "DISTINCT credit_limit").count.
  • ActiveRecord::Base#invalid? agora funciona como o oposto de ActiveRecord::Base#valid?.

Action Controller

O Action Controller lança algumas mudanças significantes à renderização, bem como melhoramentos no roteamento e em outras áreas, nesta versão.

Renderização Unificada

ActionController::Base#render está muito mais esperto na hora de decidir o que renderizar. Agora você pode apenas dizer para ele o que renderizar e esperar obter os resultados corretos. Em versões antigas do Rails, muitas vezes você precisava fornecer a informação a ser renderizada explicitamente:

render :file => '/tmp/random_file.erb'
render :template => 'other_controller/action'
render :action => 'show'

Agora no Rails 2.3, você pode apenas fornecer o que quer renderizar:

render '/tmp/random_file.erb'
render 'other_controller/action'
render 'show'
render :show

O Rails escolhe entre arquivo, template, e ação dependendo se há uma barra no início, uma barra no meio, ou nenhuma barra em todo o conteúdo que é para ser renderizado. Note que você também pode utilizar um símbolo em vez de uma string quando renderizar uma ação. Outros estilos de renderização (:inline, :text, :update, :nothing, :json, :xml, :js) ainda requerem uma opção explícita.

Application Controller Renomeado

Se você é uma das pessoas que sempre se aborreceu pelo caso especial de nomenclatura do application.rb, alegre-se! Ele foi reformulado para application_controller.rb no Rails 2.3. Além disso, há uma nova tarefa rake, rake rails:update:application_controller para fazer isto automaticamente para você – e ela rodará como parte do processo normal do rake rails:update.

Suporte a Autenticação HTTP Digest

O Rails agora possui suporte embutido a autenticação HTTP digest. Para usá-la, você chama authenticate_or_request_with_http_digest com um bloco que retorne a senha do usuário (a qual é então transformada em hash e comparada contra as credenciais transmitidas):

class PostsController < ApplicationController
  Users = {"dhh" => "secret"}
  before_filter :authenticate

  def secret
    render :text => "Password Required!"
  end

  private
  def authenticate
    realm = "Application"
    authenticate_or_request_with_http_digest(realm) do |name|
      Users[name]
    end
  end
end
Roteamento Mais Eficiente

Existe um par de mundaças significativas no roteamento do Rails 2.3. Os helpers para rotas formatted_ sumiram, em favor de passar apenas :format como uma opção. Isto reduz o processo de geração de rotas em 50% para qualquer recurso – e pode salvar uma quantia substancial de memória (até 100MB em grandes aplicações). Se o seu código utiliza os helpers formatted_, ele ainda funcionará atualmente – mas este comportamento está deprecado depreciado e sua aplicação será mais eficiente se você reescrever estas rotas usando o novo padrão. Outra granda mudança é que o Rails agora suporta vários arquivos de roteamento, não só o routes.rb. Você pode utilizar RouteSet#add_configuration_file para importar mais rotas a qualquer momento – sem limpar as rotas carregadas atualmente. Embora esta mudança é mais útil para os Engines, você pode utilizá-la em qualquer aplicação que precise carregar rotas em lote.

Sessões com Lazy-load Baseadas no Rack

Uma grande mudança empurrou as camadas baixas de armazenamento de sessão do Action Controller para o nível do Rack. Isto envolveu uma grande quantidade de trabalho no código, apesar de que deve ser completamente transparente para suas aplicações Rails (como um bônus, alguns patches desagradáveis em torno do antigo gerenciador de sessão CGI foram removidos). Isto ainda é significativo, entretanto, por uma simples razão: aplicações Rails não baseadas no Rack têm acesso aos mesmos gerenciadores de armazenamento de sessão (e por conseqüência a mesma sessão) assim como sua aplicação Rails. Além disso, as sessões agora são carregadas sob demanda (lazy load) (em conjunto com os melhoramentos de carga do resto do framework). Isto significa que você não precisa mais desabilitar as sessões explicitamente se você não as quer; somente não se refira a elas e elas não serão carregadas.

Mundanças no Tratamento de Tipos MIME

Há um par de mudanças no código para tratamento de tipos MIME no Rails. Primeiro, agora o MIME::Type implementa o operador =~, tornando as coisas muito mais limpas quando você precisa checar pela presença de um tipo que possui sinônimos:

if content_type && Mime::JS =~ content_type
  # faça algo legal
end

Mime::JS =~ "text/javascript"        => true
Mime::JS =~ "application/javascript" => true

A outra mudança é que agora o framework utiliza o Mime::JS quando checa por javascript em vários lugares, tornando o tratamento dessas alternativas limpo.

Otimização do respond_to

Em alguns dos primeiros frutos da união entre o Rails e o Merb, o Rails 2.3 inclui algumas otimizações para o método respond_to, que é certamente bastante utilizado em muitas aplicações Rails para permitir que seu controller formate resultados diferentemente baseado no tipo MIME da requisição de entrada. Após eliminar uma chamada ao method_missing e alguns recortes e aprimoramentos, nós estamos vendo uma melhoria de 8% no número de requisições por segundo servidas por um simples respond_to que altera entre três formatos. A melhor parte? Nenhuma mudança é requerida em todo o código de sua aplicação para obter vantagem deste ganho.

Melhoria na Performance do Caching

O Rails agora mantém um cache local a cada requisição de leitura a partir dos armazenamentos remotos de cache, reduzindo leituras desnecessárias e melhorando o desempenho do site. Embora este trabalho era originalmente limitado ao MemCacheStore, ele está disponível para qualquer armazenamento remoto que implemente os métodos necessários.

Views Localizadas

O Rails agora pode fornecer views localizadas, dependendo do locale que você tiver definido. Por exemplo, suponha que você tem um controller Posts com uma ação show. Por padrão, isto irá renderizar app/views/posts/show.html.erb. Mas se você setar I18n.locale = :da, ele irá renderizar app/views/posts/show.da.html.erb. Se o template localizado não existe, a versão normal será usada. O Rails inclui também I18n#available_locales e I18n::SimpleBackend#available_locales, que retornam um array das traduções disponíveis no projeto Rails atual.

Além disso, você pode utilizar o mesmo esquema para localizar os arquivos de erro no diretório public: public/500.da.html ou public/404.en.html funcionam, por exemplo.

Escopo Parcial para Traduções

Uma mudança na API de tradução torna as coisas mais fáceis e menos repetitivas para escrever traduções de chaves dentro de partials. Se você chamar translate(".foo") a partir do template people/index.html.erb, na verdade você estará chamando I18n.translate("people.index.foo"). Se você não iniciar a chave com um ponto, então a API não usará o escopo, assim como antes.

Outras Mudanças do Action Controller
  • A manipulação de ETag foi um pouco organizada: O Rails agora pula o envio de um cabeçalho ETag quando não há corpo para a resposta ou quando enviar arquivos com send_file.
  • O fato do Rails checar por IP spoofing pode ser um incômodo para sites com tráfego pesado de telefones celulares, porque os proxies deles geralmente não ajustam as coisas de maneira correta. Se você é um desses, pode agora definir ActionController::Base.ip_spoofing_check = false para desabilitar esta checagem por completo.
  • O ActionController::Dispatcher implementa agora sua própria pilha de middleware, que você pode ver executando rake middleware.
  • Sessões em cookies possuem agora identificadores de sessão persistentes, com compatibilidade de API com o armazenamento no lado servidor.
  • As opções :only e :except para o map.resources não são mais herdadas por recursos aninhados.
  • Agora você pode utilizar símbolos para as opções :type do send_file e send_data, como por exemplo: send_file("fabulous.png", :type => :png).
  • O pacote memcached client foi atualizado para a versão 1.6.4.99.
  • Os métodos expires_in, stale?, e fresh_when aceitam agora uma opção :public para fazê-las funcionar bem com proxy caching.
  • A opção :requirements agora funciona corretamente com rotas RESTful member adicionais.
  • Rotas shallow agora respeitam namespaces de maneira correta.
  • polymorphic_url faz um trabalho melhor ao tratar objetos com nomes irregulares no plural.

Action View

O Action View no Rails 2.3 traz formulários com modelos aninhados, melhorias no render, prompts mais flexíveis para os helpers de seleção de data, e um ganho no cache de assets, dentre outras coisas.

Formulários com Objetos Aninhados

Contanto que o model pai aceite atributos aninhados para os objetos filhos (como discutido na seção do Active Record), você pode criar formulários aninhados usando form_for e field_for. Estes formulários podem ser aninhados em profundidade arbitrária, permitindo que você edite hierarquias complexas de objetos em uma única view sem código excessivo. Por exemplo, dado este model:

class Customer < ActiveRecord::Base
  has_many :orders

  accepts_nested_attributes_for :orders, :allow_destroy => true
end

Você pode escrever esta view no Rails 2.3:

<% form_for @customer do |customer_form| %>
<div>
    <%= customer_form.label :name, 'Customer Name:' %>
    <%= customer_form.text_field :name %></div>
<!-- Aqui nós chamamos fields_for na instância do construtor
   customer_form. O bloco é chamado para cada membro da coleção orders. -->
  <% customer_form.fields_for :orders do |order_form| %>
<div>
        <%= order_form.label :number, 'Order Number:' %>
        <%= order_form.text_field :number %></div>
<!-- A opção allow_destroy no model habilita a exclusão dos
   registros filhos. -->
      <% unless order_form.object.new_record? %>
<div>
          <%= order_form.label :_delete, 'Remove:' %>
          <%= order_form.check_box :_delete %></div>
<% end %>

  <% end %>

  <%= customer_form.submit %>
<% end %>
Renderização Inteligente de Partials

O método render vem se tornando mais inteligente ao longo dos anos, e ele está ainda mais inteligente agora. Se você tem um objeto ou uma coleção e um partial apropriado, e os nomes casam, agora você pode renderizar somente o objeto e as coisas irão funcionar. Por exemplo, no Rails 2.3, estas chamadas ao render funcionarão na sua view (supondo uma nomeação sensata):

# Equivalente de render :partial => 'articles/_article',
# :object => @article
render @article

# Equivalente de render :partial => 'articles/_article',
# :collection => @articles
render @articles
Prompts para Helpers de Seleção de Datas

No Rails 2.3, você pode fornecer prompts customizados para os vários helpers de seleção de data (date_select, time_select, e datetime_select), do mesmo modo que pode com helpers de seleção de coleções. Você pode fornecer uma string ou um hash de strings individuais para os vários componentes. Você também pode definir apenas o :prompt para true para usar o prompt genérico:

select_datetime(DateTime.now, :prompt => true)

select_datetime(DateTime.now, :prompt => "Choose date and time")

select_datetime(DateTime.now, :prompt =>
  {:day => 'Choose day', :month => 'Choose month',
   :year => 'Choose year', :hour => 'Choose hour',
   :minute => 'Choose minute'})
Caching de Assets com Timestamps

É provável que você conheca a prática do Rails de adicionar timestamps para caminhos estáticos de assets como um “cache buster”. Isto ajuda a garantir que cópias antigas de coisas como imagens e stylesheets não fiquem desatualizadas no cache do navegador dos usuários quando você os modifica no servidor. Agora você pode modificar este comportamento com a opção de configuração cache_asset_timestamps para o Action View. Se você ativar a cache, o Rails calculará o timestamp uma vez quando ele servir um asset a primeira vez, e salvará este valor. Isto significa menos (custosas) chamadas ao sistema de arquivos para servir assets estáticos – mas também significa que você não pode modificar nenhum dos assets enquanto o servidor está executando e esperar que as mudanças sejam obtidas pelos clientes.

Hosts de Asset como Objetos

Hosts de assets tornam-se mais flexíveis no Rails edge com a habilidade de declarar um host de assets como um objeto específico que responda a uma chamada. Isto permite que você implemente qualquer lógica complexa que precisar no seu hosting de asset.

Método Helper grouped_options_for_select

O Action View já possui um monte de helpers para auxiliar na geração de controles select, mas agora existe mais um: grouped_options_for_select. Este aceita um array ou hash de strings, e os converte em uma string de tags option dentro de tags optgroup. Por exemplo:

grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]],
  "Cowboy Hat", "Escolha um produto...")

retorna

<option value="">Escolha um produto...</option>
<optgroup label="Hats">
  <option value="Baseball Cap">Baseball Cap</option>
  <option selected="selected" value="Cowboy Hat">Cowboy Hat</option>
</optgroup>
Tags com Opção Disabled para Helpers Select de Formulários

Os helpers select de formulários (tais como select e options_for_select) agora suportam uma opção :disabled, que pode levar um único valor ou um array de valores para disabilitar as tags resultantes:

select(:post, :category, Post::CATEGORIES, :disabled => 'private')

retorna

<select name="post&#91;category&#93;">
<option>story</option>
<option>joke</option>
<option>poem</option>
<option disabled="disabled">private</option>
</select>

Você também pode utilizar uma função anônima para determinar em tempo de execução quais opções das coleções serão selecionadas e/ou desabilitadas:

options_from_collection_for_select(@product.sizes, :name, :id, :disabled => lambda{|size| size.out_of_stock?})
Uma Nota sobre Carregamento de Template

O Rails 2.3 inclui a capacidade de ativar ou desativar cache de templates para qualquer ambiente específico. Cache de templates impulsionam a velocidade porque eles não checam por um novo arquivo de template quando são renderizados – mas também significam que você não pode substituir um template “on the fly” sem reiniciar o servidor.

Na maioria dos casos, você desejará o cache de templates habilitado em produção, o que pode ser feito através de uma configuração no seu arquivo production.rb:

config.action_view.cache_template_loading = true

Esta linha será gerada para você por padrão em uma nova aplicação com Rails 2.3. Se você tiver atualizado de uma versão mais antiga do Rails, ele irá por padrão fazer o cache de templates em produção e teste mas não em desenvolvimento.

Outras Mudanças do Action View
  • Geração de token para proteção CSRF foi simplificada; agora o Rails utiliza uma string aleatória simples gerada pelo ActiveSupport::SecureRandom ao invés de gastar tempo com IDs de sessão.
  • auto_link agora aplica corretamente opções (tais como :target e :class) para os links de e-mail gerados.
  • O helper autolink foi refatorado para torná-lo um pouco menos bagunçado e mais intuitivo.
  • current_page? agora funciona corretamente mesmo quando existem vários parâmetros na URL.

Active Support

O Active Support possui algumas mudanças interessantes, incluindo a introdução do Object#try.

Object#try

Muita gente adotou a idéia de usar try() para tentar executar operações em objetos. Isto é especialmente útil em views onde você pode evitar a checagem de nil escrevendo código como <%= @person.try(:name) %>. Bem, agora isto está incorporado direto no Rails. Como implementado no Rails, ele gera um NoMethodError em métodos privados e sempre retorna nil se o objeto é nil.

  • Mais Informações: try.
Backport do Object#tap

Object#tap é uma adição ao Ruby 1.9 e 1.8.7 que é similar ao método returning que o Rails tinha até então: ele retorna para um bloco, e então retorna o objeto que foi passado. Agora o Rails inclui código para disponibilizar isto também em versões mais antigas do Ruby.

Parsers Configuráveis para XMLmini

O suporte para parsing XML no ActiveSupport tornou-se mais flexível permitindo que você troque entre diferentes parsers. Por padrão, ele utiliza a implementação REXML padrão, mas você pode facilmente especificar as implementações mais rápidas LibXML ou Nokogiri para suas próprias aplicações, contanto que você possua as gems apropriadas instaladas:

XmlMini.backend = 'LibXML'
Segundos Fracionários para TimeWithZone

As classes Time e TimeWithZone incluem um método xmlschema que retorna o tempo em uma string XML amigável. A partir do Rails 2.3, TimeWithZone suporta o mesmo argumento para especificar o número de dígitos na parte fracionária do segundo para a string retornada, assim como o Time faz:

>> Time.zone.now.xmlschema(6)
=> "2009-01-16T13:00:06.13653Z"
Chaves JSON com Aspas

Se você verificar a especificação no site “json.org”, descobrirá que todas as chaves em uma estrutura JSON devem ser string, e elas devem estar dentro de aspas duplas. Começando com o Rails 2.3, nós fazemos a coisa certa aqui, mesmo com chaves numéricas.

Outras Mudanças do Active Support
  • Você pode usar Enumerable#none? para verificar se nenhum dos elementos batem com o bloco fornecido.
  • Se você está usando delegates do Active Support, a nova opção :allow_nil permite que você retorne nil em vez de gerar uma exceção quando o objeto alvo é nil.
  • Agora o ActiveSupport::OrderedHash: implementa each_key e each_value.
  • ActiveSupport::MessageEncryptor fornece uma maneira simples para encriptar informações para armazenamento em uma localização não confiável (como cookies).
  • O método from_xml do Active Support não depende mais do XmlSimple. Em vez disso, o Rails inclui agora sua própria implementação XmlMini, somente com a funcionalidade que ele precisa. Isto permite que o Rails se livre da cópia embutida do XmlSimple que ele tem carregado.
  • Se você memoizar um método privado, o resultado agora será privado.
  • String#parameterize aceita um separador opcional: "Quick Brown Fox".parameterize('_') => "quick_brown_fox".
  • number_to_phone agora aceita números de telefone com 7 dígitos.
  • ActiveSupport::Json.decode agora trata seqüências de estilo escapadas \u0000.

Railties

Além das modificações do Rack cobridas acima, Railties (o código principal do próprio Rails) ostenta uma quantidade de mudanças significante, incluinto Rails Metal, templates de aplicação, e backtraces silenciosos.

Rails Metal

Rails Metal é um novo mecanismo que proporciona endpoints super rápidos dentro de suas aplicações Rails. As classes Metal passam por cima do roteamento e do Action Controller para lhe dar velocidade pura (ao custo de todas as coisas no Action Controller, claro). Isto baseia-se em todo o trabalho recente para tornar o Rails uma aplicação Rack com uma pilha de middleware exposta. Endpoints Metal podem ser carregados a partir de sua aplicação ou de plugins.

Templates de Aplicação

O Rails 2.3 incorpora o gerador de aplicações rg do autor Jeremy McAnally. O que isto significa é que temos agora geração de aplicações com base em templates diretamente no Rails; se você tem um conjunto de plugins que inclui em cada aplicação (entre muitos outros casos de uso), pode apenas criar um template uma vez e usá-lo quantas vezes quiser quando executar o comando rails. Também há uma tarefa rake para aplicar um template em uma aplicação existente:

rake rails:template LOCATION=~/template.rb

Isto irá jogar as modificações do template em cima de qualquer código que o projeto já contenha.

Backtraces Silenciosos

Criado com base no plugin Quiet Backtrace da Thoughtbot, que permite que você remova linhas seletivamente dos backtraces do Test::Unit, o Rails 2.3 implementa no core ActiveSupport::BacktraceCleaner e Rails::BacktraceCleaner. Isto suporta ambos filtros (para realizar substituições com expressões regulares em linhas do backtrace) e silenciadores (para remover por completo linhas do backtrace). O Rails adiciona silenciadores automaticamente para livrar-se do barulho mais comum em uma nova aplicação, e cria um arquivo config/backtrace_silencers.rb para armazenar as suas próprias adições. Esta funcionalidade também ativa uma impressão melhor a partir de qualquer gem no backtrace.

Tempo de Boot Mais Rápido em Modo de Desenvolvimento com Lazy Loading/Autoload

Um pouco de trabalho foi feito para se certificar que partes do Rails (e suas dependências) somente são carregadas em memória quando são efetivamente necessárias. Agora os frameworks core – Active Support, Active Record, Action Controller, Action Mailer e Action View – estão usando autoload para carregar suas classes individuais quando necessário (lazy-load). Este trabalho deve ajudar a manter o uso de memória baixo e melhorar a performance geral do Rails.

Você também pode especificar (usando a nova opção preload_frameworks) se as bibliotecas do core devem ser carregadas de forma automática na inicialização. Esta opção tem como padrão false para que o Rails se auto-carregue peça por peça, mas existem algumas circunstâncias onde você ainda precisa carregar tudo de uma vez – ambos Passenger e JRuby precisam ter o Rails carregado por completo.

Reescrita da Tarefa rake gem

Várias tarefas rake gem foram substancialmente revisadas internamente, fazendo com que o sistema trabalhe melhor em uma variedade de casos. O sistema de gems agora sabe a diferença entre dependências de desenvolvimento e execução, tem um sistema de desempacotamento mais robusto, traz melhores informações quando procurar pelo status de gems, e é menos propenso a problemas de dependência do tipo “galinha e ovo” quando você está começando com as coisas do zero. Existem também correções para a utilização de comandos gem com JRuby e para dependências que tentam importar cópias externas de gems que já estão vendoziradas.

Outras Mudanças no Rails
  • As instruções para atualizar um servidor CI para construir o Rails foram atualizadas e ampliadas.
  • Os testes internos do Rails foram trocados do Test::Unit::TestCase para o ActiveSupport::TestCase, e o core Rails requer Mocha para os testes.
  • O arquivo padrão environment.rb foi reorganizado.
  • O script dbconsole permite que você use uma senha totalmente numérica sem falhar.
  • Agora o Rails.root retorna um objeto Pathname, o que significa que você pode usá-lo diretamente com o método join para limpar o código existente que usa File.join.
  • Vários arquivos no /public que tratam com dispatch CGI e FCGI não são mais gerados em toda aplicação Rails por padrão (você ainda pode obtê-los se precisar adicionando —with-dispatches quando executar o comando rails, ou adicioná-los mais tarde com rake rails:generate_dispatchers).
  • Rails Guides foram convertidos da marcação AsciiDoc para Textile.
  • Controllers e Views geradas com o scaffold foram um pouco limpos.
  • script/server aceita agora um argumento —path para subir uma aplicação Rails a partir de um caminho específico.
  • Se algumas gems configuradas estão faltando, as tarefas rake de gems irão pular a carga da maior parte do ambiente, Isto deve resolver muitos dos problemas do tipo “galinha e ovo” onde o rake gems:install não poderia rodar porque as gems estavam faltando.
  • As gems agora são desempacotadas exatamente uma vez. Isto corrige problemas com gems (hoe, por exemplo) que são empacotadas com permissões somente-leitura nos arquivos.

Deprecado Depreciado

Alguns pedaços de código antigo foram deprecados depreciados nesta versão:

  • Se você é um dos (bastante raros) desenvolvedores Rails que faz deploy em uma modo que depende dos scripts inspector, reaper, e spawner, precisa saber que estes scripts não estão mais inclusos no core Rails. Se você precisa deles, pode obter cópias através do plugin irs_process_scripts.
  • render_component vai de “deprecado” “depreciado” para “naoexistente” no Rails 2.3. Se você ainda precisa dele, pode instalar o plugin render_component.
  • O suporte para componentes Rails foi removido.
  • Se você é uma das pessoas que costumava executar script/performance/request para verificar a performance com base nos testes de integração, precisa aprender um novo truque: este script agora foi removido do core Rails. Existe um novo plugin request_profiler que você pode instalar para obter a mesma funcionalidade de volta.
  • ActionController::Base#session_enabled? está deprecado depreciado porque as sessões são agora carregadas sob demanda (lazy-load).
  • As opções :digest e :secret para o protect_from_forgery estão deprecadas depreciadas e não tem efeito.
  • Alguns helpers de testes de integração foram removidos. response.headers["Status"] e headers["Status"] não retornarão mais nada. O Rack não permite “Status” nos seus headers de retorno. Contudo você ainda pode usar os helpers status e status_message. response.headers["cookie"] e headers["cookie"] não retornarão nenhum cookie CGI. Você pode inspecionar headers["Set-Cookie"] para ver o header do cookie sem ser processado ou utilizar o helper cookies para obter um hash dos cookies enviados para o cliente.
  • formatted_polymorphic_url está deprecado depreciado. Utilize no lugar polymorphic_url com :format.
  • A opção :http_only no ActionController::Response#set_cookie foi renomeada para :httponly.
  • As opções :connector e :skip_last_comma do método to_sentence foram substituídas pelas opções :words_connnector, :two_words_connector, e :last_word_connector.
  • Postar um form multipart com um controle file_field vazio costumava enviar uma string vazia para o controller. Agora ele envia nil, devido a diferenças entre o parser multipart do Rack e o antigo parser do Rails.

Créditos

Notas de lançamento compiladas por Mike Gunderloy. Esta versão das notas de lançamento do Rails 2.3 foi compilada com base no RC2 do Rails 2.3.

Tradução para o português das notas de lançamento do Rails 2.3 por Carlos A. da Silva.