I’m big fan of JRuby. The Ruby language’s flexibility with the JVM’s power give to us a big weapon to create amazing applications.
I have to say that this one was the best talk about refactoring that I ever watch. I highly recommend it.
While we are waiting for the next release of rack that will come with that fix, I extract a code from a pull request in rack repository and created a monkey patch to fix this problem.
This problem often happens when you are using google analytics or another service
Esse post é o inicio de uma série que estou preparando sobre desenvolvimento desktop com Ruby. Para quem não sabe o Qt é um framework para desenvolvimento de aplicações Desktop muito utilizado pelo comunidade OpenSource. E já provou sua eficácia em grandes projetos. Foi desenvolvido originalmente pela empresa e mais tarde adquirido pela Nokia. Nesse exemplo, será desenvolvido uma simples aplicação “Hello World!” e no futuro aprofundaremos mais no assunto.
require 'Qt4'
app = Qt::Application.new(ARGV)
hello = Qt::PushButton.new('Hello World!')
hello.resize(100, 30)
hello.show()
app.exec()
O is_paranoid é uma gem que faz com que os registros do banco não sejam apagados através do método destroy. Ao chamar o método destroy nosso objeto é apenas marcado como apagado e pode ser restaurado posteriormente, bem como listado através de método fornecidos pelo is_paranoid. Sua utilização é bem simples, primeiro instale a gem:
gem install is_paranoid
Para que funcione em sua aplicação Rails, adicione no enviroment.rb , dentro do bloco de inicialização:config.gem "is_paranoid"Deixando mais ou menos assim:
Rails::Initializer.run do |config| # ... config.gem "is_paranoid" endAgora, nos models que vão utilizar dos recursos do is_paranoid, adicione logo após a declaração da classe ‘is_paranoid’ Exemplo:
class Student < ActiveRecord::Base is_paranoid endE para finalizar, crie uma migrate que adicione na tabela que vai utilizar o is_paranoid, o campo ‘deleted_at’, do tipo ‘timestamp’. Exemplo:
class AddIsparanoidInStudent < ActiveRecord::Migration
def self.up
add_column :students, :deleted_at, :timestamp
end
def self.down
remove_column :students, :deleted_at
end
end
Pronto! Se quiser saber mais sobre o is_paranoid, consulte a documentação oficial no site do projeto.O restful_authentication é um plugin de autenticação para aplicativos ruby on rails, com excelentes recursos, super fácil de configurar. Enfim, não vou falar muito sobre ele, pois não é o propósito desse tutorial. Irei assumir que você já tem o restful_authentication funcionando e quer apenas adicionar a funcionalidade de enviar um código de reset password via email para o usuário que esqueceu sua senha. Ao acessar o link com esse código o sistema irá exibir uma tela de troca de senha, lembrando que esse código deverá ser único e poderá ser usado somente uma vez. Então vamos lá: Primeiro iremos gerar uma migration que adiciona na tabela o usuário a coluna ‘reset_password_code’. script/generate migration reset_password_code Agora editarei a migration gerada, deixando da seguinte forma:
class ResetPasswordCode < ActiveRecord::Migration
def self.up
add_column :users, :reset_password_code, :string
end
def self.down
remove_column :users, :reset_password_code
end
end
em seguida, ‘rake db:migration’ e estaremos pronto para começar!
Na classe UsersController irei criar um método protected que irá gerar um código para ser enviado ao usuário.
protected
def random_code( len = 40 )
chars = (("a".."z").to_a + ("1".."9").to_a )- %w(i o 0 1 l 0)
newpass = Array.new(len, '').collect{chars[rand(chars.size)]}.join
end
Agora criarei o método que chamará a view com o campo para o usuário colocar seu email:
def change_reset_password endAgora criarei a view que receberá o endereço de email do usuário e chamará o método “reset_password” passando o email:
<p>
<%= form_tag (:controller => 'users', :action => 'reset_password' ) %>
<p>
<%= label_tag 'Email' %>
<br/>
<%= text_field_tag (:email) %>
</p>
<p>
<%= submit_tag 'Enviar' %>
</p>
<%= flash[:alert] %>
</p>
Já método reset_password, irá receber o email, procurar o usuário com esse email, gerar o código de reset password, e chamar o UserMailer para enviar o email com o código.
def reset_password
user = User.find_by_email(params[:email])
unless user.nil?
user.reset_password_code = random_code
if user.save!
UserMailer.deliver_new_password(user)
flash[:done] = "Verifique seu email para trocar a senha"
redirect_to ('/')
else
flash[:error] = "Erro ao efetuar trocar de senha"
render :action => 'change_reset_password'
end
else
flash[:error] = "Email Inválido"
render :action => 'change_reset_password'
end
end
Vejam que estou chamando “UserMailer.deliver_new_password(user)” e passando o usuário como parâmetro. Na classe ‘UserMailer’ devo criar o método ‘new_password’ que será usado para enviar o email.
Meu método new_password deverá ficar assim:
def new_password(user)
setup_email(user)
@subject += 'Mudança de senha'
@body[:url] = "#{$SERVER_CONTENT_BASE}/password/#{user.reset_password_code}"
end
Agora criarei a view para esse email, dentro de ‘app/views/user_mailer’ com o nome de ‘new_password.html.erb’
Olá <%=h @user.login %> alguém solicitou a troca de senha para essa conta. Se deseja realmente trocar sua senha, clique no link abaixo: <%=h @url %>Agora de volta ao UsersController, criarei o método que recebe o reset_code e se ele estiver correto será jogado em um campo hidden na view de troca de senha.
def code_password_reset
user = User.find_by_reset_password_code(params[:reset_code])
if user.nil?
flash[:error] = "Código inválido"
redirect_to ('/')
else
@reset_code = params[:reset_code]
render :action => "new_password"
end
end
Criarei a view de troca de senha, chamada ‘new_password’
<p>
<%= form_tag (:controller => 'users', :action => 'reset_password_update', :method => 'put' ) %>
<p>
<%= label_tag 'Nova Senha' %>
<br/>
<%= password_field_tag (:password) %>
</p>
<p>
<%= label_tag 'Confirmação' %>
<br/>
<%= password_field_tag (:password_confirmation) %>
</p>
<%= hidden_field_tag(:reset_code, @reset_code) %>
<p>
<%= submit_tag 'Enviar' %>
</p>
<%= flash[:alert]%>
</p>
E agora o método que de fato executa a troca de senha:
def reset_password_update
@user = User.find_by_reset_password_code(params[:reset_code]) unless params[:reset_code].blank?
if ((params[:password] == params[:password_confirmation]) && !params[:password_confirmation].blank?)
@user.password_confirmation = params[:password_confirmation]
@user.password = params[:password]
@user.reset_password_code = nil
if @user.save!
flash[:done] = "Senha atualizada com sucesso!"
redirect_to ("/")
else
flash[:alert] = "Falha ao atualizar senha."
render :action => 'new_password'
end
else
flash[:alert] = "Senhas diferentes!"
render :action => 'new_password'
end
end
Para finalizar iremos configurar as rotas;
map.resources :users, :collection => { :change_reset_password => :get,
:new_password => :get, :reset_password_update => :post,
:code_password_reset => :get, :reset_password => :get}
map.connect 'password/:reset_code', :controller => 'users', :action => 'code_password_reset'
E assim chegamos ao fim desse tutorial.Essa semana comecei a utilizar o rspec para realizar testes na aplicação que estou trabalhando e estou gostando muito, pra não dizer que estou viciado. O Rspec torna o trabalho de escrever testes divertido, rápido e prático.
Abaixo segue o link de alguns excelentes artigos que tive a chance de ler sobre rspec:
http://blog.wolfman.com/articles/2007/7/6/rspec-testing-views-for-escaped-html
http://www.elevatedrails.com/articles/2007/09/10/testing-controllers-with-rspec/
http://simplesideias.com.br/usando-o-rspec-para-testar-sua-aplicacao-rails-modelos/
http://simplesideias.com.br/7-coisas-que-voce-precisa-conhecer-no-rspec/
http://blog.davidchelimsky.net/2007/05/14/an-introduction-to-rspec-part-i/
Uma maneira fácil de se trabalhar com paginação no Ruby on Rails é utilizar o plugin will_paginate. Nesse breve artigo irei demonstrar como instalar e utilizar em sua aplicação. Primeiro instalaremos o plugin: gem install will_paginate Com o plugin instalado, podemos começar a configura-lo na aplicação. Para isso abra o arquivo environment.rb dentro do diretório config e adicione no final do arquivo a seguinte linha:
require "will_paginate"Com isso, sua aplicação só irá subir se o plugin will_paginate estiver presente. Já no controlador devo usar o método paginate para efetuar a busca pelos registros no banco. No meu caso, tenho uma entidade chamada ‘noticia’ e no método ‘index’ do seu controlador, pelo padrão o rails faz uma busca por todos os registros no banco.
def index
@noticias = Noticia.all
respond_to do |format|
format.html # index.html.erb
format.xml { render : xml => @noticias }
end
E no caso eu irei deixa-lo assim:
def index
@noticias = Noticia.paginate :page => params[:page], : order => 'created_at DESC', :per_page => 10
respond_to do |format|
format.html # index.html.erb
format.xml { render : xml => @noticias }
end
end
Onde o “:order =>” irá definir a ordem de exibição dos registros.
E o “:per_page =>” a quantidade de registros por página.
E pra terminar, abra a view e adicione logo abaixo do término da tabela:
<%= will_paginate @noticias %>
Bom, como muitos de vocês já sabem sou um grande fã da linguagem Ruby, e por isso estou postando dois excelentes artigos.
O primeiro é para quem está iniciando no mundo Ruby, serve como introdução sobre os conceitos da linguagem.
O segundo é sobre o uso de simbolos, que é uma das grandes sacadas do Ruby (não conheço nenhuma outra linguagem com algo parecido, se alguém conhecer posta ai) e ao mesmo tempo um dos assuntos que gera mais dificuldade (eu mesmo tive dificuldade).
Artigo 1:
http://ruby-br.org/tutoriais/?t=4&p=0
Artigo 2:
http://www.akitaonrails.com/2007/11/26/ruby-symbols
Bom eu sei que é meio off-topic, mas ainda em tempo recomendo a todos a leitura do artigo “Como eu desistir de USD 300k da Microsoft para trabalhar full-time no Github” no qual o Tom Preston-Werner conta como ele desistiu do emprego dos sonhos de muitos programadores para trabalhar em um projeto pessoal.
Se é boato ou verdade eu não sei, o fato é: o rails vem crescendo de maneira assustadora e é claro que grandes empresas como RedHat, SUN e etc… não iam ficar de fora disso.
Não é atoa que em 2006 a SUN contratou o Charles Nutter e Tom Enebo para colocar pra frente o projeto JRuby, o que deve permitir codigos Ruby serem executados na JVM.
Agora é esperar para ver.
Fonte:
http://blog.seatecnologia.com.br/articles/2008/10/20/jboss-on-rails