Projetos Open Source de Ruby, by Nando Vieira

2010 December 19, 07:06 h

Ontem estava conversando com alguns amigos e vi um projeto que usava várias gems e plugins do Nando Vieira. Para quem não conhece, o @fnando é um rubista bastante ativo, trabalhou na WebCo e está atualmente na Locaweb. E pelo menos na nossa roda de amigos é conhecido por ser uma metralhadora de gems :-) Sem brincadeira, basta abrir o Github dele para ver isso: nada menos do que 89 repositórios. Acho que já passou da hora de eu ajudar a divulgar isso porque lá deve ter muitas coisas que muitas pessoas estão precisando mas não sabiam onde procurar.

São muitos projetos no Github e vou pular alguns deles. Mesmo assim, acho que consegui formatar uma lista bem completa com as principais bibliotecas e ferramentas. Dividi as sub-seções em:


Produtos


Curiosos

1
2
3
4
5
6
7
starts = Date.parse("2008-09-21") #=> sunday
@recurrence = recurrence(
  :every  => :week,
  :on     => [:monday, :wednesday, :friday],
  :starts => starts,
  :until  => "2009-01-01"
)

E o que obtemos é:

1
2
3
4
5
6
@recurrence.events[0].to_s.should == "2008-09-22"
@recurrence.events[1].to_s.should == "2008-09-24"
@recurrence.events[2].to_s.should == "2008-09-26"
@recurrence.events[3].to_s.should == "2008-09-29"
@recurrence.events[4].to_s.should == "2008-10-01"
@recurrence.events[5].to_s.should == "2008-10-03"

Veja o arquivo de Rspec para exemplos de como usar.

1
2
3
4
5
6
7
8
9
10
require "redis/settings"

# Reuse an existing Redis connection.
Redis::Settings.configure do |config|
  config.connection = Redis.new(:host => "localhost", :port => 6379)
end

settings = Redis::Settings.new("app") # Create settings namespaced to app
settings[:items_per_page] = 10 # Set values
@items_per_page = settings[:items_per_page] # Get values

Leia a documentação, tem mais funcionalidades interessantes para Rails 3, por exemplo. E não esqueça de instalar a gem Yajl-Ruby, que é usado para lidar com Json.

1
2
3
4
<script type="text/javascript">
  I18n.defaultLocale = "<%= I18n.default_locale %>";
  I18n.locale = "<%= I18n.locale %>";
</script>

Dentro dos arquivos Javascript podemos fazer:

1
I18n.t("hello", {name: "John Doe"});

E para isso funcionar colocamos o arquivo de tradução normalmente dentro de config/locales/*.yml:

1
2
en:
    hello: "Hello {{name}}!"
1
2
3
<% if browser.ie6? %>
  <p class="disclaimer">Your're running an older IE version. Please update it!</p>
<% end %>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
require "sinatra"
require "sinatra/basic_auth"

# Specify your authorization logic
authorize do |username, password|
  username == "john" && password == "doe"
end

# Set protected routes
protect do
  get "/admin" do
    "Restricted page that only admin can access"
  end
end


Linha de Comando

1
2
3
4
5
# add a new plugin
pez add git://github.com/fnando/has_cache.git

# update the repository
pez update has_cache


Alternativas

Isso para testes de integração. Para testes unitários temos ferramentas como o Blue Ridge, que encapsula a engine Rhino, escrita em Java, e o Env.js, que é uma implementação de DOM, para executar testes unitários de Javascript. O Blue Ridge permite escrever testes unitários em Javascript com um certo gosto de RSpec:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require("spec_helper.js");
require("../../public/javascripts/application.js");

Screw.Unit(function() {
  describe("Your application javascript", function() {
    it("does something", function() {
      expect("hello").to(equal, "hello");
    });

    it("accesses the DOM from fixtures/application.html", function() {
      expect($('.select_me').length).to(equal, 2);
    });
  });
});

Tudo isso foi para dar o contexto para o Spec-Js do Nando que é um framework para testes unitários, muito parecida com o Blue Ridge, que também usa a engine Rhino, Env.js e por padrão vem com jQuery. Seus testes podem ser escritos assim:

1
2
3
4
5
6
describe("A sample suite", function(){
  it("increases a number", function(){
    number += 1;
    expect(number).toBeGreaterThan(0);
  });
 });

Agora uma coisa que eu não sei dizer: não parei para comparar o Blue Ridge com o Spec.Js. Se alguém tem experiência no uso dos dois, por favor não deixem de colocar nos comentários suas impressões. Mas de qualquer forma, a idéia é que se você quer teste unitários Javascript, existem pelo menos duas boas opções no mundo Ruby. E claro, se você usa Textmate, o Nando preparou um bundle para ajudar a usar o Spec.js.


Active Record

1
2
3
4
5
class User < ActiveRecord::Base
  validates_email_format_of :email
  validates_url_format_of :site
  validates_ip_address :address
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# migration:
create_table :pages do |t|
  t.string    :name
  t.text      :body
  t.binary    :meta
end

# app/models/page.rb
class Page < ActiveRecord::Base
  marshaled :meta
end

@page = Page.new(:meta => {:last_comment_id => 100})
@page.meta
#=> {:last_comment_id => 100}
1
2
3
4
5
6
7
8
9
class User < ActiveRecord::Base
  has_many :projects
  activities_for :projects do
    track :renamed, :if => proc {|r| !r.new_record? && r.name_changed? }, :on => :save
    track :create
    track :update
    track :destroy
  end
end

Toda vez que o projects mudar, essa atividade será gravada e daí você pode exibir numa página de status assim:

1
2
3
<% for activity in @activities %>
  <%= render_activity @activity %>
<% end %>

Essa gem é bem customizável, você deve gerar as partials para cada tipo de atividade, mas isso deve ser suficiente para gerar modelos auditáveis de forma simples.

1
2
3
4
5
6
7
8
9
10
# mary accepts john's request if it exists;
# makes a friendship request otherwise.
mary.be_friends_with(john)

# check if paul is mary's friend
mary.friends?(paul)

# if you're dealing with a friendship object,
# the following methods are available
friendship.accept!
1
2
3
4
5
6
7
class Post < ActiveRecord::Base
  has_markup :content,
    :format       => :markdown,
    :tidy         => true,
    :tags         => %w(p a em strong ul li),
    :attributes   => %w(href)
end

Esta gem suporta Tidy, Markdown, Textile e sanitize.


Miscelânea

1
2
3
4
class PagesController < ApplicationController
  set_layout 'site', :only => %w(faq feedback)
  set_layout 'custom', :except => %w(faq feedback)
end
1
2
3
4
post_commit :twitter do
  authorize :username => "johndoe", :password => "mypass"
  post "Hi Twitter!"
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require "sinatra"
require "sinatra/subdomain"

# Specify which subdomain you want
subdomain :foo do
  get '/' do
    "render page for FOO"
  end
end

# If any subdomain is set
subdomain do
  get '/' do
    "render page for #{subdomain} subdomain"
  end
end
1
2
3
@user = _1_user
@user, @comments = _1_user_with_10_comments
@user, @comments, @messages = _1_user_with_10_comments_and_10_messages

tags: obsolete ruby

Comments

comentários deste blog disponibilizados por Disqus