Programar em Ruby on Rails muitas vezes parece mágica, pois com pouco código pode-se fazer muita coisa. No entanto, como mágicos do Rails, devemos conhecer bem nossos truques, ou não faremos mágicas impressionantes ou realistas. Podemos construir código desnecessariamente complexo se não soubermos dos artifícios dos quais dispomos.
Além disto, quero alertar aqui para a importância da Refatoração: quando vermos um código e acreditarmos ser possível simplificá-lo, esclarecê-lo ou deixá-lo mais aderente ao modelo MVC, devemos fazê-lo. Este exercício não só nos faz comprender melhor o código (se não foi criado por nós) como minimiza problemas futuros que venhamos a ter. Façam sempre refatoração quando forem adicionar algo ao código. Não podemos focar somente nas funcionalidades e ir carregando um código legado, ou então no futuro (não tão distante) iremos pagar dobrado.
Dei uma olhada no código do controller de cadastro, e fiz umas boas refatorações nela, deixando o código bem mais enxuto.
Código original:
def new@network_list = Network.find(:all, :order => "name")
@user = User.new(params[:user])
if request.post?
membership = Membership.new( :network_id => params[:network] )
if @user.save
membership.user_id = @user.id
if membership.save
MailRobot.deliver_confirmation_email(@user, confirmation_hash(@user.id.to_s))
flash[:notice] = "O usuário foi criado com sucesso "
redirect_to :action =>"index"
else
flash[:notice] = "O usuário não foi criado "
@user.destroy
end
end
end
end
1a Refatoração:
def new
@network_list = Network.find(:all, :order => "name")
@user = User.new(params[:user])
if request.post?
@user.memberships << Membership.new( :network_id => params[:network] )
if @user.save
MailRobot.deliver_confirmation_email(@user, confirmation_hash(@user.id.to_s))
flash[:notice] = "O usuário foi criado com sucesso "
redirect_to :action =>"index"
else
flash[:notice] = "O usuário não foi criado "
end
end
end
Economizamos umas boas linhas de código e ele ficou mais fácil de entender. Tem menos ifs aninhados (de 3 para 1), que geralmente causam confusão (muitos ifs aninhados são indicadores de código a ser refatorado). Faz exatamente a mesma coisa. Qual foram os truques?
- Não Precisamos salvar um model para depois criarmos um filho para ele; É melhor criar os dois, adicionar o filho ao pai, e salvar somente o pai (o filho será salvo automaticamente); Não só é mais fácil como é melhor: o tratamento de erros é superior, o Rails cria uma transação e só faz a operação se tudo der certo.
Ainda podemos melhorar? Claro. Seria interessante fazer o próprio model criar a Membership. Assim podemos, por exemplo, fazer validação no model e facilitar a criação de Users através de outras views e controllers. Vou fazer isto num próximo artigo.
Luiz respondeu em 16 Abr 2007 às 15:32 #
Muito boa a refatoração! O código ficou bem mais simples.
Em relação a fazer a criação de Memberships no modelo do User, acho melhor não. É possível que um User (administração) não esteja associado a nenhuma Network (através de Membership).