Como muitos sabem, as versões mais recentes do Rails estão vindo com uma proteção muito bacana: Cross-Site Request Forgery. Basicamente, o Rails insere uma chave secreta, token, em cada formulário para validá-lo no servidor. Isso significa alguma proteção contra códigos de outros lugares que podem acessar sua aplicação Rails se passando por um formulário comum e confiável.
O problema é que isso interfere nas chamadas Ajax do plugin AutoComplete. Esse plugin faz chamadas Ajax afim de criar listas de opções filtradas de acordo com o que o usuário digita, como no campo de emails do GMail.
Para corrigir isso foi muito simples: no controller onde está a action para auto complete do campo, coloque:
class EmpresasController < AdministracaoController
protect_from_forgery :except => [:auto_complete_for_record_cidade]
active_scaffold do |config|
config.columns = [:nome, :contato, :email, :telefone,
:celular, :endereco, :bairro, :numero, :cidade, :ativo]
config.list.columns = [:id, :nome, :contato, :email,
:celular, :ativo]
config.columns[:endereco].label = "Endereço"
config.columns[:numero].label = "Número"
config.actions.exclude :delete
end
def auto_complete_for_record_cidade
@cidades = []
if not params[:record][:cidade].blank? and params[:record][:cidade].size>1
@cidades = Cidade.find(:all,
:conditions =>["LOWER(descricao) LIKE ?","%#{params[:record][:cidade]}%"],
:limit => 10,:order => "descricao ASC")
end
render :inline => "<%= auto_complete_result(@cidades,'descricao') %>"
end
end
O protect_from_forgery continua funcionando para todas as actions, com exceção da que é utilizada para o auto complete. Isso aí é bem melhor do que desabilitar de vez a proteção direto no seu application.rb…
Ah, quer saber como integrei o plugin AutoComplete com o ActiveScaffold para o campo cidade?
def cidade_form_column(registro, nome)
text_field_with_auto_complete :record,:cidade,{:class => "text-input"}
end
Bastou sobrescrever a geração automática do campo definindo o método para isso no helper do controller Empresa. O helper text_field_with_auto_complete aí substitui o text_field que o ActiveScaffold iria colocar por padrão!