Guilherme's Blog

Individuals and interactions over processes and tools.

Limpando CSS com Ruby

leave a comment »

Essa dica é para quem trabalha com um ou vários arquivos CSS. Geralmente esquecemos de remover as classes criadas para teste, etc. Há uma maneira simples e eficaz para verificar as classes que não estão sendo utilizadas no projeto. A gem deadweight permite executar uma Rake Task que faz essa verificação.

Instalação:

gem install deadweight

Task:

require 'deadweight'

Deadweight::RakeTask.new do |dw|
  dw.stylesheets = %w( /stylesheets/style.css )
  dw.pages = %w(  /page/1 /about )
end

Execução:

rake deadweight

Primeiro informamos ao deadweight onde está localizado o arquivo css e depois as páginas que serão verificadas. Para executar essa task é necessário que você inicie o WEBrick (ou outro servidor que você esteja usando).

Ao executar a task, é exibido um relário completo de classes por página e um relatório contendo as classes que não são utilizadas.

Written by guinascimento

março 8, 2010 at 3:22 pm

Publicado em Rails

Rodando processos do sistema com Ruby

leave a comment »

Após pesquisar um pouco sobre automatização, resolvi criar alguns scripts para me ajudar a obter maior produtividade no dia-a-dia. Comecei criando um script para me ajudar a realizar merge de branchs com o GIT. O primeiro passo foi descobrir como executar comandos com o Ruby. Encontrei os métodos: Kernel.system e Kernel.exec.

Há uma diferença na utilização desses métodos. Ao utilizar o método Kernel.exec só conseguimos rodar um comando, pois perdemos o controle do processo corrente. Felizmente existe o método Kernel.system. Esse método permite executar comandos em um sub shell, e então continuar processando os comandos seguintes.

O script de automatização ficou assim:

require 'optparse'

class GitUtil
	REMOTE = "origin"
	MASTER_BRANCH = "master"

	def parsed_options
		options = {}
		OptionParser.new do |opts|
			opts.on("-m [BRANCH]") do |branch|
				list_local_branches
				merge branch
				push_remote_branch MASTER_BRANCH
				delete_local_branch branch
			end
		end.parse!
	end

	def list_local_branches
		puts "\nListing all local branches"
		system "git branch"
	end

	def push_remote_branch branch
		puts "\nPushing -> #{branch}"
		system "git push #{REMOTE} #{branch}"
	end

	def merge branch
		puts "\nMerging master and #{branch}"
		system "git checkout master"
		system "git merge #{branch}"
	end

	def delete_local_branch branch
		puts "\nDeleting local branch -> #{branch}"
		system "git branch -D #{branch}"
	end

	if __FILE__ == $PROGRAM_NAME
		g = GitUtil.new
		g.parsed_options
	end

end

Esse script executa os seguintes comandos:

  • Lista todos os branches
  • Faz o merge entre o branch master e o branch selecionado
  • Faz o push do branch master
  • Deleta o branch local selecionado

Para rodar o script basta executar a seguinte linha:

ruby gitutil.rb -m [BRANCH]

Written by guinascimento

agosto 22, 2009 at 3:05 pm

Publicado em Uncategorized

#Tip 2 – Merge de branches com o GIT no Windows

leave a comment »

Essa dica é para quem utiliza o GIT no windows através do msysgit. Ao realizar o merge de branchs, frequentemente encontramos alguns conflitos. Para ajudar a resolver esses conflitos, você pode utilizar o KDiff3, uma ferramenta de diff e merge.

Configuração

Para utilizar o KDiff3, basta executar a seguinte linha:

git config --global merge.tool kdiff3

E colocar o executável do KDiff3 no diretório: Git/bin

Após realizar a configuração, já é possível executar o KDiff3 como ferramenta de diff e merge:

git mergetool

Written by guinascimento

agosto 19, 2009 at 5:38 pm

Publicado em GIT

Mensagens flash dinâmicas no Rails

with one comment

Uma funcionalidade interessante nas aplicações rails é a utilização do objeto Flash. Ele fornece uma forma de passar objetos entre ações. Essa é uma boa opção para enviar mensagens de alerta, erros, sucesso, etc.

Para criarmos uma mensagem notificando determinada operação na aplicação, definimos um controller da seguinte forma:

  class PostsController < ActionController::Base
    def create
      flash&#91;:notice&#93; = "Successfully created post"
      redirect_to posts_path(@post)
    end
  end
&#91;/code&#93;

Para exibir a mensagem no template:

&#91;code language="ruby"&#93;
   <% if flash&#91;:notice&#93; %>
      <div class="notice"><%= flash&#91;:notice&#93; %></div>
    <% end %>

Podemos melhorar a forma como essas mensagens são exibidas para o usuário. A melhor forma de fazer isso, é utilizar o JQuery.

O primeiro passo é criar um helper para exibir as mensagens:

	FLASH_NOTICE_KEYS = [:error, :notice, :warning]

	def flash_message
		messages = ""
		FLASH_NOTICE_KEYS.each {|type|
	  		if flash[type]
                messages += "<div id='flash_messages'>"
				messages += "<p class=\"#{type}\">#{flash[type]}</p>"
                messages += "</div>"
	  		end
		}
		messages
	end

Para exibir as mensagens no template:

<%= flash_message %>

Agora podemos tornar a exibição das mensagens mais interativa utilizando os efeitos que o JQuery disponibiliza:

  <script type="text/javascript">
    $(document).ready(function() {
      setTimeout(
        function() {
          $("#flash_messages").fadeOut(800)
        }, 
        2500);
    });
  </script>

O código javascript criado é responsável por realizar um efeito fadeOut no DIV que contém a mensagem. Dessa forma, a mensagem de erro é exibida para o usuário e depois de 8ms o DIV é escondido automaticamente.

Se você estiver utilizando o Prototype, pode criar o mesmo efeito assim:

  <script type="text/javascript">
    document.observe('dom:loaded', function() {
        setTimeout(hideFlashes, 2500);
    });

    var hideFlashes = function() {
        $$('.notice', '.warning', '.error').each(function(e) {
        if (e) Effect.Fade(e, { duration: 1.5 });
        })
    }
  </script>

Written by guinascimento

agosto 18, 2009 at 10:45 pm

Publicado em Javascript, Rails

Utilizando JQuery no Rails

leave a comment »

Atualmente estou trabalhando em uma aplicação Rails que utiliza o framework javascript Prototype através dos helpers. Decidimos migrar essa aplicação para o JQuery:

jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages. jQuery is designed to change the way that you write JavaScript.

Essa mudança casou um problema: Não queremos perder toda a flexibilidade e facilidade dos helpers do Prototype.

A solução encontrada foi o jRails:

jRails is a drop-in jQuery replacement for Prototype/script.aculo.us on Rails. Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library.

Instalação

script/plugin install git://github.com/aaronchi/jrails.git

Após instalar o plugin, copie os arquivos javascript do plugin para o diretório plublic/javascripts da sua aplicação.

Configuração

Adicione a seguinte linha no arquivo application.html.erb:

<%= javascript_include_tag :defaults %>

Essa linha adicionará os arquivos do jRails em vez dos arquivos do prototype/script.aculo.us. Após realizar os passos descritos, você já pode utilizar os helpers normalmente. O jRails faz todo o trabalho sujo pra você. 😉

O jRails também adiciona o JQuery UI ao projeto:

jQuery UI provides abstractions for low-level interaction and animation, advanced effects and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications.

Em breve vou postar sobre as facilidades que o JQuery UI fornece para tornar as aplicações Web mais interativas.

Written by guinascimento

agosto 18, 2009 at 9:47 pm

Publicado em Javascript, Rails

#Tip 1 – Editor Ruby/Rails para o Windows

leave a comment »

Essa dica é para quem desenvolve aplicações Ruby/Rails no Windows. Se você está procurando um editor leve, simples e customizável, dê uma olhada no Intype.

O Intype é bem parecido com o famoso editor para MacOs, o TextMate. O Intype possui suporte a temas e bundles de diversas linguagens (PHP, Python, Ruby, etc).

Customização
É possível converter temas do TextMate para o modelo de temas do Intype através de um script Python. Todas as informações para realizar a conversão estão disponíveis aqui.

O site http://www.tmthemes.com/ possui diversos temas do TextMate para download.

É possível também utilizar a mesma fonte do Editor do TextMate, a fonte Monaco. Você pode fazer o download da fonte aqui.

Written by guinascimento

agosto 18, 2009 at 5:26 pm

Publicado em Editor, Rails, Uncategorized

WeatherFinder – Biblioteca para previsão de tempo

leave a comment »

Há um tempo atrás, eu estava envolvido na construção de uma funcionalidade que precisava de informações relacionadas com previsão do tempo. Pois bem, fiz algumas pesquisas atrás de algumas bibliotecas para previsão do tempo com Ruby e nenhuma me agradou totalmente.

Como um bom curioso, coloquei a mão na massa e resolvi implementar uma biblioteca para previsão do tempo acessando o serviço do site Weather.com. O site permite ter acesso a previsão do tempo através de um feed XML.

O WeatherFinder foi criado utilizando basicamente o Hpricot para fazer o parser do XML e o MemCached para operações de cache.

Instalação

gem install weatherfinder
gem install hpricot

Para utilizar o WeatherFinder, é preciso obter o partner_id e license_key do Weather.com. Acesse o seguinte endereço para obter os dados: http://www.weather.com/services/xmloap.html

Após se registrar, você receberá um email contendo o partner_id e license_key que serão utilizados no WeatherFinder.

Após a instalação da biblioteca já é possível recuperar informações sobre a previsão do tempo:

Condições atuais

  require "weatherfinder"

  service = Weather::WeatherFinder.new

  # Partner ID and License Key provided by Weather.com
  service.partner_id = your partner id
  service.license_key = your license key

  # Fetching current forecast from Rio de Janeiro
  forecast = service.load_forecast("BRXX0201", 2)

  puts "Current Description: " + forecast.current.description
  puts "Current Temperature: " + forecast.current.temp
  puts "Current Icon: " + forecast.current.icon
  puts "Current Wind Speed: " + forecast.current.wind.speed

Previsão do tempo para amanhã

  puts "Tomorrow's High Temperature: " + forecast.tomorrow.high
  puts "Tomorrow's Low Temperature: " + forecast.tomorrow.low
  puts "Tomorrow's Sunrise: " + forecast.tomorrow.sunrise 
  puts "Tomorrow's Sunset: " + forecast.tomorrow.sunset
  puts "Tomorrow's Wind Speed" + forecast.tomorrow.wind.speed

Previsões futuras

Previsões futuras podem ser recuperadas através do método day() da classe Forecast. Esse método aceita um parâmetro indicando o número de dias que serão recuperados. Essa funcionalidade depende do parâmetro days, que foi definido no método load_forecast() da classe WeatherFinder.

  puts "High Temperature 2 days from now: " + forecast.day(2).high
  puts "High Temperature 2 days from now: " + forecast.day(2).low
  puts "Sunrise 2 days from now: " + forecast.day(2).sunrise
  puts "Sunset 2 days from now: " + forecast.day(2).sunset

Cache

O WeatherFinder usa o Memcached para suportar o cache de dados. Essa funcionalidade é muito interessante quando há uma grande quantidade de acessos realizados pelos clientes.

Instalando o Ruby-MemCache

gem install Ruby-MemCache

Após a instalação do Ruby-MemCache, é preciso habilitar o cache:

  service.enable_cache
  service.cache.servers = "localhost:11211"
  service.cache_expiry = 10

Para mais informações, dê uma olhada no código que está hospedado no Github e na página do projeto no RubyFourge.

Written by guinascimento

julho 21, 2009 at 8:41 pm

Publicado em Ruby

Validação customizada no RoR

leave a comment »

Quando um formulário possui erros, o ActionView adiciona um div envolvendo o campo que contém o erro. Esse div possui uma classe chamada “fieldWithErrors”:

<p>
   <div class="fieldWithErrors">
      <input id="user_name" name="user&#91;name&#93;" type="text" value="" />
   </div>
</p>

A classe CSS correspondente:

.fieldWithErrors {
   border: 2px solid red;
   display: inline;
   padding: 2px;
}

Nós podemos melhorar a forma como a validação é exibida nos formulários. O primeiro passo é criar o arquivo config/initializers/field_with_errors.rb com o seguinte conteúdo:

require 'hpricot'

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  doc = Hpricot(html_tag)
  elem = (doc/"/").first
  css_class = elem.attributes['class']
  css_class ||= ""
  css_array = css_class.split(" ")
  css_array << "fieldWithErrors"
  elem.attributes&#91;'class'&#93; = css_array.uniq.join(" ")
  doc.to_s
end
&#91;/source&#93;

Repare que no codigo acima nós utilizamos o <a href="http://github.com/why/hpricot/tree/master">hpricot</a> para customizar a tag HTML. O hpricot é um parser HTML bastante flexível e simples de utilizar. Se você não possui a gem hpricot instalada, execute o seguinte comando:

gem install hpricot

Após essa pequena customização, o campo que contém o erro será exibido da seguinte forma:

<p>
   <input id="user_name" name="user&#91;name&#93;" type="text" value="" class="fieldWithErrors" />
</p>

O formulário contendo erros será exibido assim:

Image and video hosting by TinyPic

Written by guinascimento

julho 15, 2009 at 6:48 pm

Publicado em Rails

Restful Authentication + RoleRequirement

with 2 comments

Uma funcionalidade importante nos sistemas que desenvolvemos é a autenticação baseada em roles. Para quem utiliza plugin Restful Authentication, existe o plugin RoleRequirement que fornece toda a infra-estrutura necessária.

Instalação Restful Authentication

script/plugin install git://github.com/technoweenie/restful-authentication.git

script/generate authenticated user sessions

Instalação RoleRequirement

script/plugin install git://github.com/timcharper/role_requirement.git

script/generate roles Role User

O Generator do plugin RoleRequirement executa as seguintes modificações:

  • Adiciona o método has_role? ao arquivo user.rb
  • Gera uma migration com as modificações necessárias no banco de dados
  • Escaneia o ApplicationController e insere as linhas “include AuthenticatedSystem“, e “include RoleRequirementSystem“, se ainda não foram incluídas.

Restrição no Controller

Para informar que somente administradores podem acessar determinado controller:

class Users < ApplicationController
  require_role "admin"
  ...
end&#91;/source&#93;

Para informar que readers podem acessar tudo e somente administradores podem acessar a action destroy:

&#91;source language="ruby"&#93;class Blog < ApplicationController
  require_role "reader"
  require_role "admin", :for => :destroy # não permite readers deletarem posts
  ...
end

Restrição na View

Para restringir trechos de códigos na view, basta utilizar o helper has_role?:

<% if current_user.has_role?("admin") %>
   ...
<% end %> 

Written by guinascimento

julho 15, 2009 at 4:50 pm

Publicado em Rails

Testando envio de emails com Cucumber

leave a comment »

A maioria dos sitemas que construímos utiliza algum mecanismo para o envio de emails. Em certos cenários, precisamos testar se o usuário recebeu um email de ativação de cadastro ou um email informando que sua conta no sistema vai expirar em determinado dia.

Para realizar esses testes com o Cucumber, é necessário utilizar o plugin email-spec do Ben Mabey. Esse plugin possui uma série de steps que podem ser incluídos nos cenários:

Given no emails have been sent

When I open the email

When I follow "[link]" in the email

When "[address]" opens the email with subject "[some text]"

When "[address]" opens the email with text "[some text]"

When I click the first link in the email

Then I should receive an email

Then "[address]" should receive n emails

Then "[address]" should have n emails

Then "[address]" should not receive an email

Then I should see "[some text]" in the subject

Then I should see "[some text]" in the email

Instalação

script/plugin install git://github.com/bmabey/email-spec.git

O próximo passo é adicionar a seguinte linha no arquivo features/support/env.rb. Adicione após a linha: “require ‘cucumber/rails/world”

require 'email_spec/cucumber'

Execute o seguinte comando:

script/generate email_spec

Esse comando criará o arquivo features/step_definitions/email_steps.rb. Esse arquivo contém uma série de steps que podem ser utilizados na descrição dos cenários.

Um cenário que utiliza envio de emails pode ser escrito da seguinte forma:

Scenario: Register new user
    Given I am on the login page
    Then I follow "Cadastre-se"
    And I fill in "Nome" with "Carlos"
    And I fill in "Login" with "carlos"
    And I fill in "Email" with "carlos@gmail.com"
    And I fill in "Senha" with "123456"
    And I fill in "Confirmação da Senha" with "123456"
    And I press "Sign up"
    Then I should see "Obrigado por se registrar! Você receberá um email com o seu código de ativação."
    And I should receive an email
    When I open the email
    Then I should see "Por favor ative sua nova conta." in the subject
    When I click the first link in the email
    Then I should see "Registro completo! Por favor, efetue o login."

Configurando o current_email_address
O arquivo email_steps.rb possui um método chamado current_email_address. Esse método define o endereço de email que será utilizado para testar o envio de emails.

Por exemplo, essa é a configuração que utilizo em meus projetos:

def current_email_address
  @email || (@current_user && @current_user.email) || "guilherme.ruby@gmail.com"
end

Você também pode criar seus próprios steps combinando os helpers que o plugin email-spec fornece.

Written by guinascimento

julho 10, 2009 at 4:33 pm

Publicado em BDD, Rails

Crie um site como este com o WordPress.com
Comece agora