Blog do Urubatan
msgbartop
Desenvolvedor, Palestrante, Escritor, Nerd Assumido e Pai do Marcus :D
msgbarbottom

17 Feb 10 Agile Brazil 2010 – A chamada para trabalhos está aberta!

Estou de férias, e eu não ia escrever nada aqui no blog antes de voltar ao trabalho, mas isto merece o post :D
A chamada de trabalhos para o Agile Brazil 2010 esta aberta.
Se você tem algo interessante sobre Agile para falar, envie sua proposta de palestra, tutorial ou workshop por este link.

A Agile Brazil 2010 é um evento nacional organizado por representantes das principais comunidades ágeis brasileiras. Junte-se a nós submetendo trabalhos, participando do concurso do logo e divulgando o evento.

Acompanhe as novidades do @agilebrazil pelo Twitter.

O evento vai acontecer em Porto Alegre de 22 a 25 de Junho 2010.

Espero ver alguns de vocês por lá!

Tags: , , , , , , , ,

11 Jan 10 Ruby on Rails 101 – Encurtador de URLs = Novo Blog

Ok, o titulo do post não ficou legal, mas a idéia é que tem tanto encurtador de URLs por ai que eu resolvi fazer um em rails também para brincar um pouco, e como a implementação ficou muito simples, vou tentar transformar isto em um tutorial bem básico de Rails.
Mas vejam bem, a idéia é só mostrar o básico, não vou colocar mais um no ar, já tem um excelente feito pelo nosso amigo Manoel Lemos, o zapt.in onde ele esta adicionando recursos muito legais. Só peguei a idéia por que achei que se tornaria um tutorial mais divertido do que o famoso blog em rails :D

Primeiro, você vai precisar do Rails[bb] instalado, e para ter o Rails instalado você vai precisar do interpretador Ruby instalado, tem diversos posts sobre isto por ai, mas basicamente numa maquina windows, sugiro instalar o “Instant Rails”, num linux instale o Ruby e depois o Ruby Gems e logo depois execute o comando “gem install rails”.

Deste ponto em diante vou considerar que você já tem o rails instalado e funcionando.

Agora com o Rails instalado, vamos começar a desenvolver a aplicação, vou chamar de “us” para “URL Shortener”, como qualquer projeto rails, vamos começar digitando:

1
2
rails us
cd us

Uma aplicação rails tem inicialmente a seguinte estrutura de diretórios:

  • app
    • controllers
    • helpers
    • models
    • views
      • layouts
  • config
    • environments
    • initializers
    • locales
  • db
  • doc
  • lib
    • tasks
  • log
  • public
    • images
    • javascripts
    • stylesheets
  • script
    • performance
  • test
    • fixtures
    • functional
    • integration
    • performance
    • unit
  • tmp
    • cache
    • pids
    • sessions
    • sockets
  • vendor
    • plugins

Não vou explicar para que serve cada um deles, mas os mais importantes para este mini tutorial são:

  • app/controllers – onde vão ficar os controladores, o código que faz o meio de campo entre a lógica e a view.
  • app/models – onde vão ficar os models, a interface da aplicação com o banco de dados e toda a lógica
  • app/views – onde vamos renderizar os dados para os usuários
  • public/* – onde ficam os recursos estáticos, como imagens, estilos, javascripts
  • config – onde ficam as configurações da aplicação
  • scripts – scripts para poupar trabalho, gerar código, rodar servidores, …

A nossa aplicação vai ser composta de dois controladores, um model e algumas views.

O ideal seria começar escrevendo testes, mas como este é um post estilo “introdução ao rails” vou deixar os testes de lado.

A primeira coisa que vamos fazer é criar um cadastro básico de URLs, para isto vamos utilizar o gerador do rails, com o seguinte comando:

1
ruby script/generate scaffold url_info href:string clicks:integer

Este comando vai gerar uma série de arquivos, vamso dar uma olhada em alguns deles:

1
2
class UrlInfo < ActiveRecord::Base
end

Este é o conteúdo do arquivo app/models/url_info.rb, toda a implementação do nosso model para um cadastro simples e, por enquanto, sem validações.

E já podemos inclusive criar o banco de dados padrão da aplicação, o rails veio configurado por padrão para utilizar o banco de dados sqlite3, mas isto pode ser facilmente alterado, mas por enquanto vamos aceitar esta configuração e executar o comando:

1
rake db:migrate

Isto vai executar as migrations da aplicação, uma migration foi criada no último comando, vamos dar uma olhada rápida nela:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CreateUrlInfos < ActiveRecord::Migration
  def self.up
    create_table :url_infos do |t|
      t.string :href
      t.integer :clicks
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :url_infos
  end
end

Esta migration possui o código para criar uma tabela de nome “url_infos”, com um campo de nome “href” de tipo “string” e um campo “clicks” de tipo “integer”, o mapeamento do tipo ruby para o tipo SQL vai depender do banco de dados, do driver que o rails utilizar para acessar o banco.

Em uma migration é importatne sempre implementar os dois métodos, o self.up cria coisas no banco de dados, e o self.down apaga coisas do banco de dados, tudo o que for criado no self.up tem que ser apagado no self.down, desta forma permitindo que voltemos a qualquer versão da aplicação para corrigir algum bug se necessário.

No exemplo estamos utilizando os métodos create_table e drop_table da migration, mais informações sobre estes métodos podem ser obtidas nesta página da documentação do Rails.

A configuração de qual banco a aplicação esta acessando fica no arquivo config/database.yml que podemos ver abaixo com o conteúdo padrão:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# SQLite version 3.x
#   gem install sqlite3-ruby (not necessary on OS X Leopard)
development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000
 
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  adapter: sqlite3
  database: db/test.sqlite3
  pool: 5
  timeout: 5000
 
production:
  adapter: sqlite3
  database: db/production.sqlite3
  pool: 5
  timeout: 5000

Este arquivo tem 3 sessões, correspondentes aos ambientes de desenvolvimento, testes e produção, ou seja, já podemos deixar estes 3 bancos de dados[bb] configurados, o que pode facilitar bastante a vida, ou complicar as vezes :D

Mas a idéia básica é que em cada ambiente é possível configurar qual o driver do banco de dados “adapter”, e os parâmetros deste driver, neste caso apenas o nome do banco é o suficiente, não vou entrar em maiores detalhes aqui por que não é a idéia deste post, quero fazer o encurtador de URLs funcionar antes de você dormir ou cansar de ler …

Então vamos lá, o rails criou um cadastro completo, que se você digitar o seguinte comando para inicializar o servidor, já pode acessar:

1
ruby script/server

Agora abra o seu browser preferido e acesse o endereço: http://localhost:3000/url_infos

Você vai ver uma listagem de informações de URLs, e quantos clicks cada URL já recebeu, você já pode até cadastrar algumas URLs ai, não vamos mexer muito neste controlador que foi criado, vamos alterar só um pouquinho, não faz sentido na hora do cadastro de uma URL ser necessário informar o número de clicks, então vamos abrir o arquivo app/views/url_infos/edit.html.erb e deixe ele como o que esta abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h1>Editing url_info</h1>
<% form_for(@url_info) do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :href %><br />
    <%= f.text_field :href %>
  </p>
  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>
 
<%= link_to 'Show', @url_info %> |
<%= link_to 'Back', url_infos_path %>

(Dica, eu removi o parágrafo que continha o campo “clicks”)

Nesta página podemos ver alguns dos helpers do rails para a geração de formulários HTML, e para tratamento de mensagens, a idéia do helper “form_for” é que a variável passada como argumento para o bloco representa um formulário para “aquele elemento”, isto torna possível utilizar os outros helpers “formulário.text_field”.
O Rails tem diversos helpers, tanto para formulários, para options, para AJAX e diversos outros.

Agora vamos duplicar a mudança no outro formulário no arquivo app/views/url_infos/new.html.erb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h1>New url_info</h1>
 
<% form_for(@url_info) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :href %><br />
    <%= f.text_field :href %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>
 
<%= link_to 'Back', url_infos_path %>

Claro que estes dois arquivos são bem parecidos, e que poderíamos juntar todo o código repetido dos dois, mas vamos deixar isto para depois, por enquanto isto não nos interessa muito.

Agora vamos editar o controlador no arquivo app/controllers/url_infos_controller.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class UrlInfosController < ApplicationController
  # GET /url_infos
  # GET /url_infos.xml
  def index
    @url_infos = UrlInfo.all
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @url_infos }
    end
  end
 
  # GET /url_infos/1
  # GET /url_infos/1.xml
  def show
    @url_info = UrlInfo.find(params[:id])
 
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @url_info }
    end
  end
 
  # GET /url_infos/new
  # GET /url_infos/new.xml
  def new
    @url_info = UrlInfo.new
 
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @url_info }
    end
  end
 
  # GET /url_infos/1/edit
  def edit
    @url_info = UrlInfo.find(params[:id])
  end
 
  # POST /url_infos
  # POST /url_infos.xml
  def create
    @url_info = UrlInfo.new(params[:url_info])
    @url_info.clicks = 0
    respond_to do |format|
      if @url_info.save
        flash[:notice] = 'UrlInfo was successfully created.'
        format.html { redirect_to(@url_info) }
        format.xml  { render :xml => @url_info, :status => :created, :location => @url_info }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @url_info.errors, :status => :unprocessable_entity }
      end
    end
  end
 
  # PUT /url_infos/1
  # PUT /url_infos/1.xml
  def update
    @url_info = UrlInfo.find(params[:id])
 
    respond_to do |format|
      if @url_info.update_attributes(params[:url_info])
        flash[:notice] = 'UrlInfo was successfully updated.'
        format.html { redirect_to(@url_info) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @url_info.errors, :status => :unprocessable_entity }
      end
    end
  end
 
  # DELETE /url_infos/1
  # DELETE /url_infos/1.xml
  def destroy
    @url_info = UrlInfo.find(params[:id])
    @url_info.destroy
 
    respond_to do |format|
      format.html { redirect_to(url_infos_url) }
      format.xml  { head :ok }
    end
  end
end

A única alteração do código gerado foi a adição da linha “@url_info.clicks = 0″ no método create, que informa aquele parâmetro que removemos do formulário.

Neste arquivo podemos também ver alguns métodos interessantes do rails, veja na lista abaixo a explicação de alguns deles:

  • UrlInfo.all – A classe ActiveRecord::Base do rails tem diversos métodos para pesquisa, o all é um alias para find(:all) e aceita os mesmos parâmetros
  • respond_to – O bloco respond_to informa ao rails como responder para diferentes tipos mime
  • render – Este é o método que realmente envia a resposta para o cliente, ele possui diversos parâmetros que permitem o envio de respostas AJAX, XML, HTML e diversas outras de forma normalmente transparante, a documentação pode ser encontrada aqui.
  • @url_inf.save – save é o método da classe ActiveRecord::Base que insere ou altera o conteúdo de um registro de uma tabela.
  • @url_info.update_attributes – este é o método da classe ActiveRecord::Base que atualiza os atributos de um registro alterados e salva as alterações no banco de dados
  • params[...] – params é um hash que permite acesso aos parâmetros enviados pelo usuário
  • @url_info.destroy – este é o método utilizado para apagar um registro do banco de dados
  • format. – format. dentro de um bloco “respond_to” informa ao rails quais tipos mime este método sabe retornar, assim o rails decide qual o mais adequado a solicitação do usuário
  • UrlInfo.find – A classe ActiveRecord::Base do rails tem diversos métodos para pesquisa, o método find é a base para a maioria deles
  • redirect_to – este método permite enviar ao browser um código de redirecionamento HTTP

Acho que por enquanto já esta bom de alterações no cadastro, vamos fazer o encurtador de URLs funcionar.

Para isto vamos criar mais um controlador, execute no console o seguinte comando:

1
ruby script/generate controller redirector index

Como o nome diz, este é o controlador que vai fazer os redirecionamentos, depois deste comando executado, o arquivo app/controllers/redirector_controller.rb foi criado, vamos editar este arquivo para que ele fique mais ou menos assim:

1
2
3
4
5
6
7
class RedirectorController < ApplicationController
  def index
	  ui = UrlInfo.find params[:id]
	  redirect_to ui.href if ui
  end
 
end

Isto já faz o redirecionador funcionar, mas não exatamente da maneira que gostaríamos :D

Por enquanto para ele funcionar precisamos acessar http://localhost:3000/redirector?id=… a idéia é que funcione acessando http://localhost:3000/[id]

Quando o id for passado o redirecionamento deve ocorrer automagicamente, quando não for passado devemos ver a lista de links conhecidos com quantos clicks cada um já teve.

Para que isto funcione vamos editar o arquivo config/routes.rb como no exemplo abaixo (vou apagar todos os comentários para facilitar a leitura do arquivo, comentários em Ruby são as linhas começadas por “#”).

1
2
3
4
5
ActionController::Routing::Routes.draw do |map|
  map.resources :url_infos
 
  map.connect ':id', :controller => 'redirector', :action => 'index'
end

A linha map.resources :url_infos foi gerada automaticamente com o scaffold, ela configura todas as rotas para o cadastro de URLs.
Esta linha configura as seguitnes rotas na aplicação:

Nome Método HTTP Caminho Mapeamento
url_infos GET /url_infos(.:format) {:action=>”index”, :controller=>”url_infos”}
  POST /url_infos(.:format) {:action=>”create”, :controller=>”url_infos”}
new_url_info GET /url_infos/new(.:format) {:action=>”new”, :controller=>”url_infos”}
edit_url_info GET /url_infos/:id/edit(.:format) {:action=>”edit”, :controller=>”url_infos”}
url_info GET /url_infos/:id(.:format) {:action=>”show”, :controller=>”url_infos”}
  PUT /url_infos/:id(.:format) {:action=>”update”, :controller=>”url_infos”}
  DELETE /url_infos/:id(.:format) {:action=>”destroy”, :controller=>”url_infos”}

A segunda linha configura a aplicação para quando receber apenas um parâmetro passar isto para o controlador de nome “redirector” para a action “index”, agora se acessarmos o endereço http://localhost:3000/1 a aplicação vai nos redirecionar para a primeira URL cadastrada, mas ainda não esta legal, precisamos contar os clicks tabém.

Para contar o clicks vamos alterar o redirector controller que editamos antes, o código dele vai ficar assim:

1
2
3
4
5
6
7
8
9
10
class RedirectorController < ApplicationController
  def index
        ui = UrlInfo.find params[:id]
        if ui
                ui.clicks += 1
                ui.save
                redirect_to ui.href
        end
  end
end

Agora antes de redirecionar a quantidade de clicks é incrementada e a informação é salva no banco de dados.

Agora vamos mudar a página inicial para a listagem de URLs, temos duas formas de fazer isto, forma chinelona:
Editar o arquivo public/index.html e configurar um meta refresh, o conteúdo fica como abaixo (HTML padrão).

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <meta http-equiv="refresh" content="0;url=url_infos" />
    <title>Mega URL Shortener Sample</title>
  </head>
  <body>
  <a href="url_infos">Link List</a>
  </body>
</html>

Ou apagar o arquivo public/index.html, e editar novamente o arquivo config/routes.rb, verifique abaixo o conteúdo alterado.

1
2
3
4
5
ActionController::Routing::Routes.draw do |map|
  map.resources :url_infos
  map.root :controller => 'url_infos'
  map.connect ':id', :controller => 'redirector', :action => 'index'
end

Foi adicionada a linha “map.root :controller => ‘url_infos’” que informa qual a ação padrão da aplicação.

E com isto já temos o encurtador de URLs quase pronto, faltam alguns detalhes, primeiro no arquivo app/views/redirector/index.html.erb vamos adicionar uma mensagem dizendo que a URL não esta cadastrada.

1
<b>A URL informada não esta cadastrada no sistema</b>

Isto vai funcionar por que o controlador “redirector” só chama o redirect se a “UrlInfo” for encontrada, caso contrário ele executa a ação default, que é renderizar a “view” correspondente ao método.

Agora vamos apagar alguns arquivos no diretório app/views/url_infos/, siga a lista:

  • edit.html.erb
  • new.html.erb
  • show.html.erb

Vamos editar o arquivo index.html.erb no mesmo diretório:

1
2
3
4
5
6
7
<h1>Shortened URLs</h1>
<div id="form">
<%= render :partial => 'editor_form' %>
</div>
<div id="table">
<%= render :partial => 'urls_table' %>
</div>

Todo o conteúdo deste arquivo foi movido para dois partials, partials são uma forma de reutilizar código de views no rails, mas neste caso estaremos utilizando partials para implementar um pouco de AJAX.

A idéia é que o formulário do topo da página seja submetido via ajax e que atualize apenas o pedaço da página que for necessário, veja abaixo como ficaram os dois partials:
_editor_form.html.erb

1
2
3
4
5
6
7
8
<% form_remote_for(@url_info) do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :href, 'URL:' %>
    <%= f.text_field :href %>
    <%= f.submit 'Create' %>
  </p>
<% end %>

Neste formulário estamos utilizando o helper “form_for_remote” que cria um formulário que sera submetido via AJAX, não fazendo refresh da página toda de uma só vez.
_urls_table.html.erb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<table width="100%">
  <tr>
    <th>Original URL</th>
    <th>Shortened URL</th>
    <th>Clicks</th>
  </tr>
<% @url_infos.each do |url_info| %>
  <tr>
    <td><%=h url_info.href %></td>
    <td><%=h url_for(:controller => 'redirector', :id => url_info.id, :only_path => false) %></td>
    <td><%=h url_info.clicks %></td>
    <td><%= link_to 'Go To', :controller => 'redirector', :id => url_info.id %></td>
    <td><%= link_to 'Destroy', url_info, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

A tabela não sofreu alterações grandes, apenas foi colocado mais um campo para mostrar qual a URL no sistema correspondente a uma URL cadastrada, e para que isto ficasse dinâmico, o helper “url_for” for utilizado, com o parâmetro “:only_path” setado para false, desta forma a URL completa seria impressa.

Para que este formulário via AJAX[bb] funcione, algumas alterações precisaram ser feitas no controlados “url_infos”, como pode ser visto abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class UrlInfosController < ApplicationController
  # GET /url_infos
  # GET /url_infos.xml
  def index
    @url_infos = UrlInfo.all
    @url_info = UrlInfo.new
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @url_infos }
    end
  end
 
  # POST /url_infos
  # POST /url_infos.xml
  def create
    @url_info = UrlInfo.new(params[:url_info])
    @url_info.href = params[:href] if params[:href]
    @url_info.clicks = 0
    respond_to do |format|
      if @url_info.save
        format.html  do
          flash[:notice] = 'UrlInfo was successfully created.'
          redirect_to root_url
        end
        format.xml  { render :xml => @url_info, :status => :created, :location => @url_info }
	format.js  do
          @url_infos = UrlInfo.all
          @url_info = UrlInfo.new
          render :update do |page|
            page.replace_html 'form', :partial => 'editor_form'
            page.replace_html 'table', :partial => 'urls_table'
            page.alert 'UrlInfo was successfully created.'
          end 
        end
      else
        format.html { render :action => "index" }
        format.xml  { render :xml => @url_info.errors, :status => :unprocessable_entity }
        format.js do
          render :update do |page|
            page.alert @url_info.errors.full_messages.join '\n'
          end
        end
      end
    end
  end
 
  # DELETE /url_infos/1
  # DELETE /url_infos/1.xml
  def destroy
    @url_info = UrlInfo.find(params[:id])
    @url_info.destroy
 
    respond_to do |format|
      format.html { redirect_to(url_infos_url) }
      format.xml  { head :ok }
    end
  end
end

Alguns métodos foram removidos, e o metodo create sofreu algumas alterações dentro do bloco “respond_to” adicionando suporte a respostas tipo “javascript”. E tem mais um detalhe no mesmo método, a segunda linha foi adicionada para quebrar todo o suporte “REST” do rails, como este é um encurtador de URLs eu quero que seja possível adicionar uma URL via uma chamada a uma URL do sistema, neste caso vai ser “/add/” e para isto na segunda linha do método “create” se o parâmetro “href” existir este é utilizado como valor da URL sendo criada no sistema, mas para isto funcionar a alteração abaixo é necessária no arquivo config/routes.rb:

1
2
3
4
5
6
7
ActionController::Routing::Routes.draw do |map|
  map.resources :url_infos
 
  map.root :controller => 'url_infos'
  map.connect '/add/:href', :controller => 'url_infos', :action => 'create', :href => /http[s]{0,1}:\/\/.*/
  map.connect ':id', :controller => 'redirector', :action => 'index'
end

A alteração feita foi a adição da linha “map.connect ‘/add/…”, preste atenção na utilização de uma expressão regular na especificação do parâmetro “href” no final da linha, isto permite que a URL completa seja utilizada como parâmetro, se isto não for utilizado o parâmetro vai terminar na primeira “/” da URL e o roteamento não vai funcionar corretamente.

Agora para que o AJAX funcione vamos alterar o layout gerado quando executamos o primeiro comando “script/generate scaffold …”, naquele momento foi gerado também o arquivo app/views/layouts/url_infos.html.erb.

Como este arquivo de layout[bb] tem o nome de um controlador, ele é utilizado apenas por este controlador, se o nome do arquivo fosse “application.html.erb” ele seria utilizado por todos os controladores da aplicação que não tivesse um layout próprio.

O conteúdo do arquivo é semelhante a qualquer outra view, uma coisa interessante de se reparar no nome do arquivo é que ele contem o “mime type” no nome, então se quisermos criar um “layout” para respostas XML vale a mesma lógica (application.xml.erb).

Vamos ver o conteúdo deste layout:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>UrlInfos: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
  <%= javascript_include_tag :defaults %>
</head>
<body>
 
<p style="color: green"><%= flash[:notice] %></p>
 
<%= yield %>
 
</body>
</html>

Foi adicionada a linha “<%= javascript_include_tag :defaults %>” que adiciona na página gerada a chamada para o javascript padrão do rails (que utiliza por padrão a biblioteca prototype).

O conteúdo das views é renderizado no lugar em que se encontra “<%= yield %>” neste arquivo de layout.

A última alteração que falta é impedir que sejam cadastradas URLs duplicadas ou em branco, para isto vamos voltar ao arquivo do model app/models/utl_info.rb

1
2
3
4
class UrlInfo < ActiveRecord::Base
	validates_uniqueness_of :href
	validates_presence_of :href
end

O suporte a validações do rails é bem flexível, e possui helpers para diversas validações, neste caso estamos garantindo que a URL seja única e esteja preenchida.

Bom, acho que era isto, temos um encurtador de URLs bem simples pronto. Esepro que o exemplo tenha sido útil para mostrar alguns dos recursos do Rails fugindo um pouco do exemplo padrão do blog.

Siga os links para a documentação do Rails, e lembre-se de programar sempre com o site da API do rails aberto em um browser.

PS.: o código completo para este exemplo esta disponível no github.

Tags: , , , ,

22 Oct 09 Ruby On Rails: Produtividade? Agilidade? Apenas uma Ferramenta?

Este foi o título da Palestra, se é que se pode chamar assim, que eu apresentei ontem na semana acadêmica da faculdade de tecnologia do SENAC/RS.
Como prometi, os slides estão no SlideShare, e embedded abaixo:

Não vou colocar o código aqui por que praticamente não teve código, foi mais uma conversa com algumas demonstrações de código, não sei se era bem isto que eles estavam esperando, mas espero que tenha sido útil.
Se alguem que estava la vir este post, deixe um comentário aqui dizendo o que achou da conversa, e podem fazer perguntas também.

Tem mais uma palestra no JugDay no sábado, espero ver vocês por lá, vou sortear mais uma copia do meu livro por lá :D

Tags: , , , ,

31 Aug 09 Rs On Rails 2009 – Ótimo evento, espero que aconteça novamente em 2010

RS On Rails

O Rs On Rails que aconteceu no fim de semana passado estava excelente, palestras muito boas, a organização estava show debola também.
Tinha mais gente no evento do que eu achei que teria …
Acho que só temos a agradecer ao pessoal da Softa pela realização deste evento …
Infelizmente eu pude ficar pouco tempo por lá, meu filho esta com 3 meses agora e eu só tenho os fins de semana pra babar um pouco com ele acordado, e pra poder ajudar a Aline a cuidar dele (Não basta ser pai, tem que participar) :D
Mas este post tem 5 objetivos:

  1. Agradecer ao pessoal da organização pelo ótimo evento, que ja fiz
  2. Avisar que os slides da minha palestra já estão no SlideShare (embedded abaixo), e que o código esta no GitHub (clique aqui)
  3. Perguntar aos leitores do blog o que acharam da minha palestra, o que preciso melhorar para a próxima :D
  4. Tirar um pouco da poeira do blog, já que não tenho tido muito tempo de escrever por aqui
  5. Lembrar vocês que quem quiser comprar o meu livro com 30% desconto, pode utilizar o código URUBATAN no site da Novatec

Bom, acho que era isto, seguem os slides …

Quaisquer dúvidas é só deixar um comentário por aqui …

PS.: fiz o upload errado como um usuário guest no slideshare também, mas o oficial é o acima que esta na minha conta do slideshare :D

Tags: , , , , , , ,

04 Jul 09 RS On Rails – Muita produtividade para um evento só :D

RS On Rails

É isso ai pessoal :D (Como dizia o perna longa no final dos desenhos).
Sábado, dia 29 de agosto de 2009 das 8h as 20h vai acontecer o 1o RS On Rails, no Centro de Eventos da PUCRS – Sala 601
A grade de palestras esta bem interessante, incluindo uma palestra deste que vos escreve :D
Deem uma olhadinha rápida na grade atual …

  • CouchDB vs Postgres em Rails – Diogo Biazus e Johalf Farina
  • TDD no Rails: Ferramentas, técnicas e experiências – Jony dos Santos Kostetzer
  • Introdução a Ruby on Rails – Juan Maiz Lulkin Flores da Cunha
  • Olá mundo OpenSocial! – O Tutorial bem rápido usando Sinatra – José Peleteiro
  • Segurança em Ruby on Rails – Marcelo Castellani
  • Câmara Municipal nos Trilhos – Márcia Almeida e Henrique Testa
  • Reutilização de código em aplicações Rails: Plugins, Gem e Engines – Rodrigo Urubatan Ferreira Jardim

Quem usa o twitter pode “seguir” o evento, e ficar sabendo das novidades (quando forem postadas :D )
E se ja estão no twitter mesmo, não custa nada me seguir também :D
Devemos agradecer ao pessoal do grupo Rails-RS e a Softa pela organização do evento, na minha temporada na organização do RSJUG tive certeza de que organizar um evento da muito trabalho mesmo.
Mas acho que era isto, propaganda do evento feita, poeira do blog sacudida.
Espero ver vocês no evento, vai estar muito legal.

PS.: Gostaria de agradecer ao Carlos Brando pelo meu novo apelido: Rodrigo Urubatan “Nome Comprido” Ferreira Jardim.
É por estas e outras que eu prefiro que me chamem só de “Urubatan”, até por que não tem tantas pessoas assim com Urubatan no nome por ai :D
hehehe

Tags: , , ,

11 May 09 Até propaganda internacional tem meu livro agora :D

É issai :D

rubylearning

Em parceria com o pessoal do RubyLearning.org, e com a Novatec, estamos fazendo mais um sorteio do melhor livro sobre Ruby on Rails em português que eu já escrevi até hoje :D
O RubyLearning é um dos maiores e melhores sites disponíveis hoje para quem quer aprender Ruby, e o meu livro é uma ótima forma de se aprender Rails (pelo menos eu acho que é, e pelos reviews publicados, tem mais gente que concorda :D )

Quem quiser participar do sorteio, é só se cadastrar neste link, e informar o código BPCE101.

E tem também desconto para quem não ganhar o livro sorteado. Informações sobre o desconto de 30% no mesmo link, ou então na home do meu blog, logo abaixo da capa do livro :D

Bom, espero que gostem de mais esta promoção, que gostem do desconto, e que comprem muitas copias do meu livro, pra quem estiver com preguiça de acessar o blog para pegar o código de desconto, segue o banner :D




PS.: eu sei que só tenho falado do livro aqui, mas prometo que esta semana vou publicar uns posts muito legais, e que não vão ter nada a ver com o livro …

Tags: , , ,

25 Apr 09 Porto Alegre Agileweekend 2009 – Slides e código fonte

Hoje a tarde eu estive no Porto Alegre Agile Weekend 2009 apresentando a palestra “Implementando Com Rails As Histórias Dos Usuários”.
Tinha pouca gente assistindo a minha palestra, mas a palestra estava bem legal, o pessoal que estava por ali fez diversas perguntas e acho que aproveitaram bastante da palestra.
Eu falei um pouco de Rails, um pouco de TDD, um pouco de BDD e bastante do Cucumber e do Webrat.
Se não estou enganado, o pessoal da TV Software livre gravou as palestras, se eles gravaram mesmo, então as palestras devem ser liberadas pela web em algum momento :D
Mas enquanto elas não são liberadas, eu coloquei os slides da palestra no Slide Share, e o código fonte no GitHub.
Os slides estão abaixo.

O projeto no github ta aqui.
Se tiverem dúvidas é só deixar um comentário aqui :D

Eu fiz algumas referências ao meu livro durante a palestra, quem quiser comprar ele, tem links para as lojas virtuais que estão vendendo o livro na página do livro.

Tags: , , ,

22 Apr 09 Frases da promoção Ruby Brasil

O pessoal do Ruby Brasil fez uma promoção em parceria com a Novatec, quem seguisse o Ruby Brasil no twitter, e mandasse a melhor frase dizendo por que deveria ganhar o meu livro de Ruby On rails, ganharia uma copia do mesmo.

Eu acabei de responder um email dizendo qual era a melhor frase de uma lista (pelo menos na minha opinião). Acho que a que eu apontei vai ganhar o livro, mas eu achei que os autores destas tres mereciam um prêmio, e como a grana anda curta, só vou listar as 3 aqui no blog mesmo e parabenizar os autores (Não tenho os nomes dos autores das frases, então se quiserem se acusar aqui, sem problemas :D ).

As tres frases estão listadas na ordem em que apareceram na lista, não na minha ordem de preferência por que eu achei as três muito boas, e principalmente criativas.

  • Ruby Nerd – Henrymax.read(Urubatan.books.last).change_level! if Rubybrasil.promotion.premium.delivered_to? Henrymax.address
  • Músico – Eu sou apenas um rapaz latino americano sem desenvolvimento ágil,sem códigos importantes e vindo do desktop. Por isto eu mereço!
  • Nerd – A resposta para a questão da vida, do Universo e de tudo mais (inclusive da promoção do livro do Urubatan) é 42.

Novamente, meus parabéns aos autores destas 3 frases.

Tags: , ,

20 Apr 09 Segunda errata do livro de Ruby on Rails

Mais alguns erros foram encontrados no meu livro de Ruby On Rails o erro anterior esta neste post :(
O agradecimento desta vez vai para o Alexandre Morgado que me avisou deste erro.
Nas páginas 107 e 108 onde esta escrito app/views/task_types/*.html.erb deveria estar escrito app/views/time_logs/*.html.erb
E também ao Victor Sobreira que me avisou que na página 96 no código ‘link_to “sair do sistema”‘ o parametro method esta escrito sem o “h”.

Se acharem mais alguma coisa agradeço se me avisarem.
T+

Tags: , , , ,

17 Apr 09 Ruby on Rails na segunda bienal de informática do Rio Grande do Norte

De 16 a 19 de abril quem estiver na cidade em que é natal o ano todo (que piada porca e sem graça) e quiser aprender um pouquinho mais sobre Ruby on Rails, pode assistir a palestra “Desenvolvimento Ágil com Rails” do Rafael Uchôa e do Elomar, figurinhas carimbadas na quando se fala em Ruby on Rails no Brasil :D

PS.: Fiquei sabendo que o Rafael falou com o pessoal da Novatec e conseguiu um desconto bem legal para quem for assistir a palestra deles e quiser comprar o meu livro (Ruby On Rails : Desenvolvimento Fáci le Rápido de aplicações web), então assistam a palestra, peguem o código de desconto e comprem o meu livro depois :D

De 16 até 19 de abril vai acontecer em Natal a II Bienal de Informática do RN [http://www.bienaldeinformatica.com.br]. Além de estandes de várias empresas e grupos do ramo a bienal vai palestras voltadas para o público em geral e para profissionais da área.

O ruby+web [http://rubymaisweb.ning.com], grupo de usuários Ruby on Rails de Natal, vai marcar presença no evento sábado, dia 18. Às 17h, Elomar França [http://maisweb.org/blogdoelomar] e Rafael Uchôa [http://putshelloworld.wordpress.com] vão dar a palestra “Desenvolvimento pra Web Ágil com Ruby on Rails”. Das 18h às 20h vai acontecer o Encontro de Usuários Ruby on Rails do RN, no estande do PSL-RN [http://rn.softwarelivre.org], onde a galera vai se reunir pra bater um papo sobre Rails e apresentar pra quem ainda não conhece. Haverá, ainda, sorteios de brindes após a palestra.
Confira a programação completa [http://www.bienaldeinformatica.com.br/programacao.php].

Quem não estiver em Natal pode participar fazendo parte do grupo ruby+web [http://rubymaisweb.ning.com]. Qualquer dúvida, email pra ruby@maisweb.org.

Tags: , ,

25 Mar 09 Primeira errata do livro de Ruby on Rails

Acabei de responder um email do Ricardo Santos Cyrillo com uma dúvida sobre o livro que se mostrou na verdade um erro no meu livro “Ruby on Rails | Desenvolvimento fácil e rápido de aplicações web.” este link é só para melhorar a indexação do google :D
No capitulo 3 do livro, na página 92, mais ou menos no meio da página.
Onde esta escrito:

1
ruby script/generate controller sessions

O correto seria

1
ruby script/generate controller sessions new create destroy

E onde diz para editar o arquivo routes.rb e colocar o seguinte código:

1
map.resources :sessions new create destroy

O correto é só

1
map.resources :sesions

Desculpem pelo engano.
Vou publicar aqui quaisquer erros encontrados, e se for necessário crio também uma página no site do livro com uma lista das correções necessárias.

Tags: , , , ,

24 Mar 09 Códigos do livro publicados

Capa Livro Ruby On Rails Urubatan

Acabei de atualizar o site do livro de Rby On Rails com os códigos desenvolvidos no livro.
Por enquanto é só o código resultante do passo a passo do livro, ou seja, se você seguir o livro vai obter o mesmo resultado (no segundo exemplo apenas dois testes passam, os outros foram gerados automaticamente e não foram corrigidos).
Peço desculpas pela demora na publicação destes exemplos, mas este mês esta realmente corrido para mim, o meu filho resolveu que quer nascer antes da hora, e é a segunda vez que a minha esposa baixa hospital para convencer o guri a esperar mais um pouquinho para nascer.
Mas nada de grave, só atrasei um pouco a publicação dos exemplos por causa desta correria. Vou ver se consigo publicar os exemplos com os exercicios e com os testes finalizados ainda esta semana.
Novamente peço desculpas pela demora.
Quaisquer dúvidas podem entrar em contato comigo pelo formulário aqui do blog mesmo. Responderei todos os emails.

é issai galera. t+

Tags: , , ,

05 Feb 09 Mais um livro sobre Ruby On Rails publicado!!

Capa Livro Ruby On Rails Urubatan

Desta vez é o meu livro que acaba de ser lançado (na verdade ele esta em pré lançamento, mas me disseram que ele chega nas bancas rapidinho :D ) pela editora Novatec (http://www.novatec.com.br).
É um Livro focado em Ruby On Rails, tentando mostrar todo o necessário para ser produtivo com o Rails de uma forma 100% prática …
Por que comprar este livro e não algum outro que ja exista por ai? A tradução de algum livro conhecido?
Bom, este livro foi escrito originalmente em portugues, utiliza uma linguagem bem descontraida.
Tentei escreve-lo como se estivesse conversando com o leitor.
O livro é 100% prático.

Durante o livro são desenvolvidas duas aplicações, que você vai poder utilizar como referência mais tarde.
Depois do capitulo sobre testes, a segunda aplicação é desenvolvida utilizando BDD com RSpec.
Todos os conceitos e recursos do Rails são apresentados utilizando as aplicações desenvolvidas, ou seja, você vai desenvolvendo uma aplicação e aprendendo a trabalhar com Rails.
No livro falo de Ruby (uma breve introdução, não é um curso completo de Ruby)
Rails
Ajax
BDD
TDD
Recursos avançados do Active Record
Recursos avançados do Rails
Boas práticas
CSS
XHTML
Um pouquinho de Javascript
Como escrever menos código
DRY

Mas mesmo assim, o livro é recomendado para iniciante e intermediario no máximo, pois existem alguns tópicos mais avançados que não são tratados, mas nada que faça falta no dia a dia.

Acho que o maior diferencial do livro é ser 100% prático, apresentar todos os conceitos utilizando exemplos desenvolvidos pelo próprio leitor, facilitando o aprendizado.
Garanto que se você ler o livro e fizer todos os exercícios e as duas aplicações propostas no livro, no final você vai conseguir desenvolver as suas aplicações em RoR sem maiores problemas.
Se tiver dúvidas, vou ficar feliz em responde-las e com certeza, se vocês gostarem do livro, as dúvidas vão ajudar a melhorar a próxima versão do livro :D
Então agora é só vocês comprarem o livro e começar a estudar.

Para quem quiser dar uma olhada antes do livro chegar nas bancas, segue o “indice” com o título dos capítulos:

  1. Dedicatória
  2. Agradecimentos
  3. Sobre o autor
  4. Prefácio
  5. Introdução ao Ruby
    • Instalação do Ruby
    • Primeiros passos
    • Variáveis e escopo
    • Tipos básicos do Ruby
    • Blocos de código
    • Procs
    • Números
    • Valores booleanos
    • Strings
    • Constantes
    • Intervalos numéricos
    • Arrays
    • Hashes
    • Símbolos
    • Expressões regulares
    • Classes e métodos
    • Métodos
    • Módulos
    • Operadores condicionais e loops
    • If elsif else end
    • case when else end
    • Operadores de loop
    • while
    • for
    • until
    • begin
    • loop
    • Padrões importantes
      • Nomes de arquivos
      • Classes, e atributos e métodos de acesso
      • Nomenclatura de métodos
      • Dominando o Ruby!
  6. Ambiente de desenvolvimento
    • Multi plataforma
      • Aptana RadRails
      • NetBeans
      • IntelliJ IDEA
      • Vim
    • Windows
      • Notepad++
      • E-TextEditor
    • Linux
      • GEdit
      • Kate
    • Mac
      • TextMate
    • Plug-ins para os editores
    • Escolhendo o seu
  7. Rails básico
    • Criando a primeira aplicação
    • Estrutura de diretórios de uma aplicação
      Rails

      • Scripts padrão do Rails
      • Gerando código, um cadastro instantâneo
      • A primeira Migration
      • O primeiro model
      • O primeiro controlador
      • Métodos básicos do ActiveRecord
      • Recebendo parâmetros nos controladores
    • Respondendo a requisições
    • As primeiras views
    • Precisando de ajuda para limpar o código das
      views?
    • Configurando rotas, um nome bonito para URLs
    • Continuando o desenvolvimento
    • Conferindo as migrations geradas
    • Escrevendo modelos
    • Gerando todo o código
    • Um pouco de segurança na aplicação
    • Um layout menos ruim para a aplicação
    • Associando usuários a projetos
    • Adicionando tipos de tarefa a um projeto
      • Cadastrando as horas trabalhadas
      • Um relatório para a aplicação
      • Limpando um pouco o código e se livrando um pouco do
        inglês
  8. Suporte a testes no Rails
    • RUnit básico
    • Testando modelos
    • Escrevendo fixtures
      • Testando as validações
      • Asserções disponíveis
      • Testes funcionais, testando os controladores e
        helpers
      • Tornando testes mais divertidos e úteis (inclusive
        para o seu chefe)
      • Notificação de testes executados
      • De volta às User Stories
      • Uma olhada nas especificações
      • Utilizando objetos falsos ou mocks
      • Finalizando a definição de comportamento do
        sistema com as User Stories
  9. ActiveRecord avançado
    • Utilizando o ActiveRecord para consultas
      • Métodos de busca dinâmicos por atributos
      • ActiveRecord::Base.find
      • ActiveRecord::Base.find_bysql
    • Associações polimorficas
    • Mais sobre associações
      • Callbacks para associações
    • Outros métodos úteis do ActiveRecord
  10. Use todo o poder do RESTful
    • Introdução ao REST
    • Métodos do protocolo HTTP
    • Princípios do REST
    • RESTful: The Rails way
      • Tema de casa
  11. Paginação
    • Paginação manual
    • Will_paginate
    • Outros plug-ins
      • paginating_find
      • Paginator
  12. Upload de arquivos
    • Attachment_fu
    • File_column
  13. Outros plug-ins úteis
    • Brazilian-rails
    • Exception_logger
    • Exception_notifier
    • JRails
    • Restful_authentication
    • Annotate_models
    • Acts_as_taggable_on_steroids
    • Juggernaut
    • Mydry
    • Calendar_date_select
    • Css_graph
    • Backgroundrb
    • Quais plug-ins utilizar na sua aplicação
  14. AJAX on Rails Quase sem JavaScript
  15. Reutilizando código entre projetos
    • O plug-in biblioteca
    • Plug-ins de geração de código
    • Finalizando o assunto
  16. Colocando tudo isto em produção
    • CGI
    • FastCGI
    • Mongrel
    • Mod_rails
    • JRuby
    • Opções de deployment

Junto com o livro vou colocar no ar o site http://livro.urubatan.com.br onde vou publicar mais exemplos, quaisquer correções que sejam necessárias, e qualquer um que comprar o livro vai poder deixar a opinião e fazer perguntas.

PS.: Este livro não vai te transformar em um ninja fodão que desenvolve qualquer sistema em 2 horas. Mas é um bom começo se você quer aprender Ruby On Rails.

Tags: , , , ,

07 Nov 08 IDE REVIEW: RubyMine – a melhor IDE para Rails até agora

Em todos os meus trabalhos com Ruby On Rails até agora eu não achei necessária uma IDE, pois eu sempre fui mais produtivo com simples editores de texto (tudo bem, não eram editores tão simples assim), As IDEs eram sempre lentas, muito mais lentas que os editores de texto. Mas o pessoal da JetBrains se superou, na verdade não se superou, pois o IntelliJ IDEA ja é expetacular.
Mas o RubyMine é a IDE para Rails [bb]mais rápida até agora, com performance similar ao GEdit e GVim que são os meus editores favoritos (mesmo preferindo o KDE não consigo me acostumar com o Kate).
Eu não sei direito como eles fizeram, mas o code completion para Ruby e Rails esta muito rápido.
A IDE ficou Leve, o que é uma novidade interessante, pois o IntelliJ IDEA é quase tão pesado quanto o Eclipse.
E o melhor de tudo! O RubyMine tem Refactorings para código Ruby, coisa que não encontrei em nenhuma outra IDE (o NetBeans tem algumas tentativas, mas no meu último teste não funcionaram muito bem).
Bom, segue então uma lista do que faz o RubyMine ser uma ótima IDE para desenvolvimento Rails na minha opinião, com alguns screenshots :D


Como o Aptana e o Netbeans o Rubymine tem integração com o “script/generate”, com dialogos bonitinhos para criar cada item, mas isto o Netbeans também tem, e fora os dialogos no GVim com um :Rgen faço a mesma coisa :D


O RubyMine também tem code completion simples, como todas as outras IDEs para Ruby e Rails, o Eclipse tem isto, o Aptana tem, até o GVim tem quando rodando em um Linux (No windows não consegui fazer o Omnicompletion funcionar :D )


Mas aqui a coisa começa a ficar mais divertida, o code completion do RubyMine é inteligente o suficiente para saber quais são os parâmetros possívels para a maioria dos métodos do Rails.
Claro que ele não inferiu isto pelo código, é a integração com o Rails que ja conhece os métodos, mas mesmo assim, este é um recurso que eu não encontrei em nenhuma outra IDE para Ruby ou Rails até agora.


Outra coisa interessante são os refactorings disponíveis.
Este do screenshot é um extract local variable, que substitui uma expressão por uma variável em todo o arquivo.
Alem deste, testei alguns outros refactorings como rename, extract class, …
Só não consegui fazer funcionar o Extract Method que eu realmente queria que funcionasse, seria muito bom ter um Extract Method para código Ruby.

Isto fora os recursos ja conhecidos do IntelliJ IDEA para edição de HTML e Javascript, com refactorings para ambos. E o fato de o RubyMine ser a IDE mais rápida para Ruby que eu encontrei até agora. Fazem ela ser a minha preferida desde ontem também :D

Claro que trabalhei com ela muito pouco tempo, mas mesmo assim, ja gostei bastante do que vi.
Só falta ver como vão ficar os preços, ja que é uma IDE comercial.
Se o preço for bom, por exemplo, próximo ao preço do TextMate, vai valer a pena com certeza!

Tags: , , , , , ,

07 Oct 08 Carregando o Rails no bolso – e programando em qualquer lugar

Sei que o blog anda meio jogado as traças, é que depois que terminei o livro a umas duas semanas fiquei meio cansado de escrever, mas acho que ja estou me recuperando :D
Este post aqui vai ser bem curto, é só uma dica para os programadores Rails por ai que não estão sempre na frente dos seus computadores e não gostam de perder tempo ou gostam de poder prototipar aquela idéia espetacular que vai te deixar rico!
Ou seja, é uma dica para os nerds de plantão :D
Também pode ser encarado como uma continuação do post onde falei sobre o PortableApps, já que utilizo o Ruby On Rails Portable e o GVim Portable junto com o PortableApps!
É isto mesmo, o pessoal da Simbisoft empacotou o Rails e o SciTE de forma que eles fiquem instalados em um Pendrive. Não gosto do SciTE para programar em Rails, mas para resolver isto, instalo o GVim Portable no mesmo pendrive e o rails.vim no GVim do pendrive!
Tudo funcionando!
E ambos funcionam integrados com o launcher do portable apps!
É quase um sonho nerd :D

(Esta última frase ficou muito gay … )

PS.: Uma última novidade, falei com o pessoal da novatec e o meu livro sobre Ruby On Rails deve chegar nas livrarias em novembro :D

Tags: , , ,