<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>

</description><title>Diego Nogueira</title><generator>Tumblr (3.0; @diegoalvareznogueira)</generator><link>http://diegonogueira.com.br/</link><item><title>Realizando tarefas longas em um servidor de forma segura</title><description>&lt;p&gt;Fala galera, gostaria de deixar um dica, que particulamente utilizo muito!
Sabe quando temos que acessar um servidor via &lt;b&gt;ssh&lt;/b&gt; e rodar um script? Então, caso o seu script demore um bom tempo para ser executado, pode acontecer de sua internet cair e abortar todo os processo&amp;#8230;&lt;br/&gt;
Para resolver isso, basta rodar seu script dessa maneira:
&lt;pre&gt;
./seu_script.sh &amp;gt; log_do_seu_script.txt &amp;amp;
&lt;/pre&gt;
Depois podemos monitorar sua saída com o comando &lt;b&gt;tail&lt;/b&gt;:
&lt;pre&gt;
tail -f log_so_seu_script.txt
&lt;/pre&gt;
Só isso! Agora esse serviço merda de internet que pagamos pode cair a vontade, basta somente voltar ao servidor e monitorar o arquivo &lt;b&gt;log_so_seu_script.txt&lt;/b&gt; novamente, pois ele não foi interrompido!!!!
&lt;br/&gt;
É isso ai galera, abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/17268549779</link><guid>http://diegonogueira.com.br/post/17268549779</guid><pubDate>Wed, 08 Feb 2012 13:04:00 -0400</pubDate><category>linux</category><category>script</category><category>servidor</category><category>server</category></item><item><title>Comandos git exageradamente lentos...</title><description>&lt;p&gt;Fala galera!&lt;/p&gt;
&lt;p&gt;Recentemente instalei o &lt;b&gt;git&lt;/b&gt; em uma máquina zero bala, até ai tudo bem, porém algo muito estranho estava acontecendo, TODOS os comandos git estavam exageradamente lentos, alguns chegando a demorar cerca de 1 minuto.&lt;/p&gt;
&lt;p&gt;Se alguém tiver um problema parecido, basta somente configurar algumas variáveis, rodando esses comandos no console:&lt;/p&gt;
&lt;pre&gt;
git config --global user.name "Your Name"
git config --global user.email you@example.com
git commit --amend --reset-author
&lt;/pre&gt;
&lt;p&gt;Bem, é isso ai, comigo funcionou 100%! Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/14121875221</link><guid>http://diegonogueira.com.br/post/14121875221</guid><pubDate>Mon, 12 Dec 2011 13:21:00 -0400</pubDate><category>git</category><category>lento</category><category>slow</category><category>commands</category><category>comando</category><category>demorando</category></item><item><title>Precisando ressuscitar o lion?</title><description>Fala galera! 
&lt;p&gt;Não sei se muita gente já passou por isso, sinceramente pensei que nunca passaria, mas foi extremamente irritante.&lt;/p&gt;
&lt;h3&gt;Migrando de um Mac para outro.&lt;/h3&gt;
&lt;p&gt;Recentemente precisei migrar minha aplicações para uma outra máquina. Decidi usar o aplicativo do Mac para isso, o &lt;b&gt;Migration Assistent&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;O programa é bem tranquilo de usar e foi desenvolvido justamente para essa causa, porém no meu caso não deu muito certo.&lt;/p&gt;
&lt;p&gt;Tudo estava indo muito bem até o momento de abrir um aplicativo migrado&amp;#8230; simplesmente travou! Hmm&amp;#8230; achei estranho isso&amp;#8230; tentei fechar&amp;#8230; nada&amp;#8230; Hmm&amp;#8230; olha só&amp;#8230; sentindo faro de problemas&amp;#8230; na mosca! Quando reiniciei a máquina não conseguia mais iniciar o sistema, ficava travado na tela da maça&amp;#8230;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;center&gt;&lt;img src="http://media.tumblr.com/tumblr_lw0ia71Y0V1qkgnk3.gif"/&gt;&lt;/center&gt;
&lt;p&gt;A minha reação naquele momento foi:&lt;/p&gt;
&lt;center&gt;&lt;img src="http://media.tumblr.com/tumblr_lw0ij3SuPH1qkgnk3.png" width="200px"/&gt;&lt;/center&gt;
&lt;p&gt;Tentei fazer todos os procedimentos padrões no primeiro momento:&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Desligar, esperar 5 minutos e ligar novamente.&lt;/li&gt;
&lt;li&gt;Reiniciar o computador segurando &lt;b&gt;command + option + p + r&lt;/b&gt; para dar o famoso &lt;b&gt;Resetting PRAM and NVRAM.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Reiniciar computador segurando o &lt;b&gt;command + r&lt;/b&gt; para entrar em modo de segurança e utilizar o &lt;b&gt;Disk Utilities&lt;/b&gt; para tentar encontrar erros no &lt;b&gt;HD&lt;/b&gt; ou nas &lt;b&gt;permissões&lt;/b&gt; dos arquivos e pastas.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Nesses casos, a Apple orienta a reinstalar o lion por esse modo de recuperação(Reiniciando o computador e segurando command + r). Até ai tudo bem, o problema é quando você não tem o DVD de restauração&amp;#8230; O assistente de restauração irá baixar o lion para reinstalar por cima.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;OBS: Se você não apagar o seu HD por inteiro, a instalação será realizada em cima da outra, a fim de não perder seus dados.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;No meu caso, optei por apagar o HD por inteiro mesmo, não queria re-aproveitar nenhum dado.&lt;/p&gt;
&lt;p&gt;Agora você me pergunta: Tá e o que tem de mal nisso? Baixar e instalar automaticamente? Bem, se você esta disposto a esperar &lt;b&gt;DIAS&lt;/b&gt; para isso tudo bem&amp;#8230; Com uma conexão de 5mb, deixei aproximadamente 6 horas e não chegou a concluir nem &lt;b&gt;4%&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Diante disso, lógico que abortei esse plano&amp;#8230; :(&lt;/p&gt;
&lt;h3&gt;Novo plano&lt;h3&gt;
&lt;center&gt;&lt;img src="http://media.tumblr.com/tumblr_lw0jh4gz9z1qkgnk3.jpg"/&gt;&lt;/center&gt;
&lt;/h3&gt;&lt;/h3&gt;&lt;p&gt;Pensei, irei baixar o lion por outro computador e colocar no pendrive para fazer a instalação via USB. Ahh legal!! Boa idéia!! Agora como baixar o lion uma vez que a minha máquina já possui o lion? E mais, a apple não disponibiliza nenhum link direto para download&amp;#8230; :(&lt;/p&gt;
&lt;p&gt;Pesquisando um pouco na internet, éis que existe uma solução muito fácil. Basta apenas ao abrir a &lt;b&gt;App Store&lt;/b&gt; no computador que deseja baixar o lion, segurando a tecla &lt;b&gt;option&lt;/b&gt; e clicando em &lt;b&gt;Purchases&lt;/b&gt;. Isso irá habilitar novamente o botão para baixarmos o Lion. :)&lt;/p&gt;
&lt;p&gt;Agora basta somente darmos o boot pelo USB e instalar o lion.&lt;/p&gt;
&lt;i&gt;OBS: Lembrando que para dar boot no Mac pelo USB, basta iniciar a máquina segurando a tecla &lt;b&gt;option&lt;/b&gt;.&lt;/i&gt;
&lt;p&gt;Irei deixar os dois links que me ajudaram a fazer tudo!&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.trickyways.com/2011/07/how-to-make-mac-os-x-lion-10-7-bootable-usb-flash-drive/" target="_blank"&gt;&lt;a href="http://www.trickyways.com/2011/07/how-to-make-mac-os-x-lion-10-7-bootable-usb-flash-drive"&gt;http://www.trickyways.com/2011/07/how-to-make-mac-os-x-lion-10-7-bootable-usb-flash-drive&lt;/a&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learningmac.com.br/site/2011/07/25/instalando-o-lion-do-zero-em-um-mac/" target="_blank"&gt;&lt;a href="http://learningmac.com.br/site/2011/07/25/instalando-o-lion-do-zero-em-um-mac"&gt;http://learningmac.com.br/site/2011/07/25/instalando-o-lion-do-zero-em-um-mac&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;É isso ai pessoal, abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/14077147253</link><guid>http://diegonogueira.com.br/post/14077147253</guid><pubDate>Sun, 11 Dec 2011 15:34:00 -0400</pubDate><category>Lion</category><category>Mac</category><category>Reinstalar</category><category>Reinstall</category><category>Repair</category><category>Migration Assistent</category></item><item><title>Ordenando documentos embutidos no mongodb</title><description>&lt;p&gt;Fala galera! Precisei recentemente fazer um ordenação de um documento embutido no &lt;a href="http://www.mongodb.org/" title="mongodb" target="_blank"&gt;mongodb&lt;/a&gt; utilizando a gem &lt;a href="http://mongoid.org/" title="mongoid" target="_blank"&gt;mongoid&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Imagine a estrutura a seguir:&lt;/p&gt;
&lt;h3&gt;user.rb&lt;/h3&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class User
  include Mongoid::Document
  field :name, :type =&amp;gt; String,  :index =&amp;gt; true
  embeds_many :lists
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;list.rb&lt;/h3&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class List
  include Mongoid::Document
  field :name, :type =&amp;gt; String, :index =&amp;gt; true
  embedded_in :user
  embeds_many :items
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;item.rb&lt;/h3&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Item
  include Mongoid::Document
  field :name, :type =&amp;gt; String, :index =&amp;gt; true
  field :price, :type =&amp;gt; Float
  embedded_in :list
end
&lt;/code&gt;&lt;/pre&gt;
&lt;!-- more --&gt;
&lt;p&gt;Agora a pergunta que não quer calar! Como consigo ordernar todos os itens de todas as listas de um usuário por um determinado atributo do item, por exemplo &lt;strong&gt;price&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;Éis a solução!&lt;/p&gt;
&lt;h3&gt;user.rb&lt;/h3&gt;
&lt;pre&gt;&lt;code class=""&gt;class User
  include Mongoid::Document
  field :name, :type =&amp;gt; String,  :index =&amp;gt; true
  embeds_many :lists

  def items(sort="price", ord="asc")
    self.lists.map(&amp;amp;:items).flatten.sort do |x,y|
      if ord == "desc"
        y[sort]  x[sort]
      else
        x[sort]  y[sort]
      end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;É isso ai! Espero que tenha ajudado!  Abraços&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/13637224084</link><guid>http://diegonogueira.com.br/post/13637224084</guid><pubDate>Fri, 02 Dec 2011 12:33:00 -0400</pubDate><category>embed documents</category><category>mongodb</category><category>mongoid</category><category>ruby on rails</category><category>sort</category><category>sub-documents</category></item><item><title>Trabalhando com tarefas em background usando o resque</title><description>&lt;p&gt;Fala galera! Vou escrever um pouquinho sobre um recurso muito bacana e ao mesmo tempo muito importante, que é o de trabalhar com tarefas em background.&lt;/p&gt;
&lt;h3&gt;Cenário&lt;/h3&gt;
&lt;p&gt;Como exemplo para nosso post, iremos adotar o envio de e-mail em massa, ok? Onde o usuário ao clicar em &amp;#8220;disparar e-mails&amp;#8221; será disparado cerca de 1000 e-mails.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTA: Não irei abordar a aplicação como um todo, irei focar somente no método do envio de e-mail no modelo de mensagem, até porque é o que mais nos interessa.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Problema&lt;/h3&gt;
&lt;p&gt;Imagine o momento que o usuário clicar em &amp;#8220;disparar e-mails&amp;#8221;&amp;#8230; Dependendo da quantidade disparada, o usuário pode não ter uma experiência muito boa em seu site, pois o mesmo terá de esperar até o final da execução da tarefa. E como todos nós sabemos que alguns usuário são um pouco impacientes(Eu), o que pode acontecer para piorar? Isso mesmo! Ele irá tentar &lt;strong&gt;1000.times { puts &amp;#8220;novamente&amp;#8230;&amp;#8221; } &lt;/strong&gt;achando que a ação não esta acontecendo.&lt;/p&gt;
&lt;h3&gt;Solução&lt;/h3&gt;
&lt;p&gt;Existem outras ferramentas para nos ajudar a resolver este problema, mas neste post irei abordar o &lt;a target="_blank" href="https://github.com/defunkt/resque"&gt;resque&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A implementação do resque é bem simples, vamos lá?&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h3&gt;Implementação&lt;/h3&gt;
&lt;p&gt;A primeira coisa a ser feita é a instalação o banco utilizado pelo resque para armazenar tarefas a serem executadas. Então vamos instalar o &lt;a target="_blank" href="http://redis.io/"&gt;redis&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#No Mac
brew install redis


#No Ubuntu/Debian
apt-get install redis-server&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Após a instalação, vamos instalar a gem do resque, então basta adicionar a gem ao seu arquivo &lt;strong&gt;Gemfile&lt;/strong&gt; e rodar o &lt;strong&gt;bundle install&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gem 'resque'&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;bundle install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Precisamos criar o arquivo &lt;strong&gt;lib/tasks/resque.rake&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require 'resque/tasks'
task "resque:setup" =&amp;gt; :environment&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos criar agora o arquivo de conexão com o redis. Então crie o arquivo &lt;strong&gt;config/resque.yml&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;development: localhost:6379
test: localhost:6379
staging: redis1.se.github.com:6379
fi: localhost:6379
production: redis1.ae.github.com:6379&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;ATENÇÃO: Não se esqueça de mudar a configuração no ambiente de produção.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Agora iremos criar o nosso initializer em &lt;strong&gt;config/initializers/resque.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
rails_env = ENV['RAILS_ENV'] || 'development'

resque_config = YAML.load_file(rails_root + '/config/resque.yml')
Resque.redis = resque_config[rails_env]
Resque.inline = ENV['RAILS_ENV'] == "test"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pronto! Vamos ao nosso código agora!&lt;/p&gt;
&lt;p&gt;Vamos imaginar que temos um modelo &lt;strong&gt;message.rb&lt;/strong&gt; desta forma:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTA: Não irei abordar a configuração do envio do e-mail em si, estou supondo que seu envio de e-mail já esteja funcionando.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Message &amp;lt; ActiveRecord::Base
  after_create :send_message

  def send_message
    MessageMailer.deliver_message(self)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos alterar nossa classe para:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Message &amp;lt; ActiveRecord::Base
  after_create :async_send_message

  def async_send_message
    Resque.enqueue(AsyncSendMessage, self.id)
  end

  def send_message
    MessageMailer.deliver_message(self)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Repare que o método &lt;strong&gt;Resque.enqueue(AsyncSendMessage, self.id) &lt;/strong&gt;irá enfileirar o envio do e-mail, passando como parâmetro a classe do nosso &lt;strong&gt;Worker&lt;/strong&gt;(que iremos criar no próximo passo) e o &lt;strong&gt;id&lt;/strong&gt; da nossa mensagem(que acabou de ser salva).&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Vamos ao nosso worker agora! Crie um arquivo em &lt;strong&gt;app/workers/async_send_message.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class AsyncSendMessage
  @queue = :async_send_message
  def self.perform(message_id)
    message = Message.find(message_id)
    message.send_message
  end  	
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Agora tudo faz sentido! Quando nossa mensagem for criada, será chamado o método &lt;strong&gt;async_send_message&lt;/strong&gt;, que irá enfileirar o e-mail na lista de tarefas a serem executadas. Quando chegar a vez do e-mail ser enviado, nosso worker entra em ação, invocando o método &lt;strong&gt;send_message.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTA: Poderíamos também ao invés de criar o método &lt;strong&gt;async_send_message&lt;/strong&gt;, ter enfileirado o e-mail diretamente no método &lt;strong&gt;send_message&lt;/strong&gt; e ter chamado o método &lt;strong&gt;deliver_message&lt;/strong&gt; diramente do nosso worker.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Testando&lt;/h3&gt;
&lt;p&gt;Antes de testar, precisamos iniciar o servidor do redis(caso ainda não esteja iniciado). No Ubuntu/Debian ele será automaticamente iniciado na instalação, no caso do Mac, basta executarmos:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo redis-server /usr/local/etc/redis.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dessa forma, quase tudo irá funcionar, o usuário irá achar que esta enviando o e-mail naquele momento, mas, o e-mail será enfileirado para o envio. Para executar o que esta na lista de tarefas, temos que deixar rodando:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QUEUE=* rake environment resque:work&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Veja que usei &lt;strong&gt;*&lt;/strong&gt;, então todos os workers irão rodar(caso você tenha mais de um), porém se você quiser especificar um somente, basta executar o comando dessa forma:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QUEUE=async_send_message rake environment resque:work&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;NOTA: Veja, o &lt;strong&gt;async_send_message &lt;/strong&gt;está especificado em &lt;strong&gt;@queue&lt;/strong&gt; dentro de  nosso worker &lt;strong&gt;AsyncSendMessage&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;É isso ai pessoal, espero que tenha ajudado!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/10494088805</link><guid>http://diegonogueira.com.br/post/10494088805</guid><pubDate>Wed, 21 Sep 2011 19:05:00 -0300</pubDate><category>ruby on rails</category><category>resque</category><category>background jobs</category><category>tarefas em background</category></item><item><title>Phusion Passenger com várias versões de ruby</title><description>&lt;p&gt;Fala galera! Depois de um tempo sumido, estou voltando a escrever! Vamos lá então que já estou atrasado!&lt;/p&gt;
&lt;p&gt;Recentemente precisei configurar meu servidor de modo que rodasse o &lt;strong&gt;passenger&lt;/strong&gt; com &lt;strong&gt;várias versões do ruby&lt;/strong&gt;. Achei um post muito bacana sobre o assunto, foi nele que me baseei para conseguir colocar tudo para funcionar e nele que me basearei para escrever esse post aqui também.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Irei utilizar &lt;strong&gt;nginx&lt;/strong&gt; neste post, mas caso você queira usar o apache, visite o post original abaixo.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a target="_blank" href="http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/"&gt;&lt;a href="http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/"&gt;http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Estratégia, em grego strateegia, em latim strategi, em francês stratégie..&lt;/h3&gt;
&lt;p&gt;Nossa estratégia será a seguinte:&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h4&gt;Com sudo&lt;/h4&gt;
&lt;p&gt;Instalar o &lt;a target="_blank" href="http://beginrescueend.com/rvm/install/"&gt;rvm&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;bash &amp;lt; &amp;lt;(curl -s &lt;a href="https://rvm.beginrescueend.com/install/rvm"&gt;https://rvm.beginrescueend.com/install/rvm&lt;/a&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Configurar o &lt;strong&gt;/etc/profile&lt;/strong&gt;, adicionando ao final:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;if [ -s "$HOME/.rvm/scripts/rvm" ] ; then
  . "$HOME/.rvm/scripts/rvm"
elif [ -s "/usr/local/rvm/scripts/rvm" ] ; then
  . "/usr/local/rvm/scripts/rvm"
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esse grupo será criado para que o mesmo tenha permissão na pasta do rvm:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;addgroup rvm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Aqui adicionaremos os usuários(projetos) que utilizaram o rvm:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;usermod -aG rvm projeto1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Com as permissões abaixo, qualquer usuário que estiver no grupo rvm poderá utilizar normalmente o rvm.&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;chown -R root:rvm /usr/local/rvm
chmod -R g+w /usr/local/rvm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos escolher versão do ruby que será mais utilizada, como exemplo usarei a 1.8.7. Então, vamos a instalação:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;rvm install 1.8.7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Precisamos instalar e configurar o passenger com nginx agora:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;gem install passenger --pre
passenger-install-nginx-module&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos editar o arquivo &lt;strong&gt;/opt/nginx/conf/nginx.conf&lt;/strong&gt; para configurar nossas aplicações:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note que podemos ter vários aplicativos rodando sobre o ruby 1.8.7. Não esqueça de adicionar cada projeto ao grupo rvm.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class="bash"&gt;server {
 listen 80;
 server_name projeto1.com.br &lt;a href="http://www.projeto1.com.br"&gt;www.projeto1.com.br&lt;/a&gt;;
 root /home/projeto1/current;
 passenger_enabled on;
}
server {
 listen 80;
 server_name projeto2.com.br &lt;a href="http://www.projeto2.com.br"&gt;www.projeto2.com.br&lt;/a&gt;;
 root /home/projeto2/current;
 passenger_enabled on;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Agora vamos instalar o ruby 1.9.2:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;rvm install 1.9.2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mais uma vez iremos editar o arquivo &lt;strong&gt;/opt/nginx/conf/nginx.conf&lt;/strong&gt; para adicionar nossas aplicações rodando em ruby 1.9.2:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Repare que aqui usaremos um &lt;strong&gt;proxy reverso&lt;/strong&gt;, direcionando nossa aplicação da porta 80 para uma instancia do passenger aberta em modo standalone na porta 3000 e a outra para a 3001.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class="bash"&gt;server {
 listen 80;
 server_name projeto3.com.br &lt;a href="http://www.projeto3.com.br"&gt;www.projeto3.com.br&lt;/a&gt;;
 root /home/projeto3/current;
 location / {
  proxy_pass &lt;a&gt;&lt;a href="http://127.0.0.1:3000"&gt;http://127.0.0.1:3000&lt;/a&gt;&lt;/a&gt;;
  proxy_set_header Host $host;
 }
}
server {
 listen 80;
 server_name projeto4.com.br &lt;a href="http://www.projeto4.com.br"&gt;www.projeto4.com.br&lt;/a&gt;;
 root /home/projeto4/current;
 location / {
  proxy_pass &lt;a&gt;&lt;a href="http://127.0.0.1:3001"&gt;http://127.0.0.1:3001&lt;/a&gt;&lt;/a&gt;;
  proxy_set_header Host $host;
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Sem sudo&lt;/h4&gt;
&lt;p&gt;Precisamos agora iniciar o passenger em modo standalone em nossos projetos. Você pode criar uma gemset para cada projeto:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Repare no parâmetro &lt;strong&gt;-d&lt;/strong&gt; no momento do start no passenger, ele servirá para deixar o passenger rodando em background. Caso precise parar o processo, basta executar &lt;strong&gt;passenger stop -p 3000&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class="bash"&gt;cd /home/projeto3/current
rvm use 1.9.2@projeto3 --create
gem install passenger --pre
passenger start -a 127.0.0.1 -p 3000 -d
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Lembre-se startar o passenger em portas diferentes em cada projeto que usar o proxy reverso.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Finalizando&lt;/h4&gt;
&lt;p&gt;Se você leu o post citado no início, verá que o autor menciona em utilizarmos Unix domain sockets ao invés de TCP socket para ganho de performance. Fiz um teste usando o Unix domain sockets e tive um problema de encode na minha aplicação. Como não quis perder tempo, voltei a usar o TCP socket mesmo e tudo voltou ao normal!&lt;/p&gt;
&lt;p&gt;Bem, por hoje é só pessoal, espero que tenham gostado do post!&lt;/p&gt;
&lt;p&gt;Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/10445701520</link><guid>http://diegonogueira.com.br/post/10445701520</guid><pubDate>Tue, 20 Sep 2011 14:04:00 -0300</pubDate><category>passenger</category><category>StandAlone</category><category>Rvm</category><category>Ruby</category><category>Servidor</category><category>nginx</category><category>apache</category></item><item><title>Rvm, Ruby e  ImageMagick no Lion</title><description>&lt;p&gt;Se você não se conteve e atualizou seu &lt;strong&gt;Mac OS X&lt;/strong&gt; para a nova versão &lt;strong&gt;lion&lt;/strong&gt; antes de seus amigos cobaias, acredito que tenha tido alguns probleminhas com o &lt;strong&gt;rvm&lt;/strong&gt;, &lt;strong&gt;ruby&lt;/strong&gt; e &lt;strong&gt;ImageMagick&lt;/strong&gt;, acertei? Claro que acertei! eu fui uma coabia&amp;#8230; :(&lt;/p&gt;
&lt;p&gt;Para poupar sua navegação ao google, irei facilitar um pouco como resolver esses problemas, vamos lá?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;OBS:&lt;/strong&gt; Todo o passo a passo abaixo estarei me baseando que você não tenha instalado o rvm, ruby e o ImageMagick.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Git&lt;/h3&gt;
&lt;p&gt;Assim que eu instalei o meu lion, tive problemas com o git, caso você tenha o mesmo problema, basta reinstalar baixando um .dmg:&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://code.google.com/p/git-osx-installer/downloads/list?can=3"&gt;&lt;a href="http://code.google.com/p/git-osx-installer/downloads/list?can=3"&gt;http://code.google.com/p/git-osx-installer/downloads/list?can=3&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Rvm&lt;/h3&gt;
&lt;p&gt;Vamos agora instalar o rvm. No terminal entre com o comando:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;bash &amp;lt; &amp;lt;(curl -s &lt;a href="https://rvm.beginrescueend.com/install/rvm"&gt;https://rvm.beginrescueend.com/install/rvm&lt;/a&gt;)&lt;/code&gt;&lt;/pre&gt;
&lt;!-- more --&gt;
&lt;h3&gt;Ruby&lt;/h3&gt;
&lt;p&gt;Na instalação do lion, não está incluso a atualização do &lt;strong&gt;X-code 3.2.1&lt;/strong&gt;, porém precisaremos das bibliotecas &lt;strong&gt;gcc 4.2&lt;/strong&gt; atualizadas para instalar nosso querido ruby.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Pegue um café bem quentinho&lt;/li&gt;
&lt;li&gt;Abra o aplicativo App Store&lt;/li&gt;
&lt;li&gt;Procure por X-code 4.1&lt;/li&gt;
&lt;li&gt;Clique em instalar&lt;/li&gt;
&lt;li&gt;Saboreie seu café, pois irá demorar&amp;#8230;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Com o X-code atualizado, podemos instalar o ruby.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Antes precisamos rodar:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;export CC=/usr/bin/gcc-4.2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Agora sim vamos ao ruby:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;rvm install 1.9.2&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ImageMagick&lt;/h3&gt;
&lt;p&gt;Vamos instalar o ImageMagick via port, então:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;sudo port install ImageMagick&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Bundle install&lt;/h3&gt;
&lt;p&gt;Agora estamos prontos para um &lt;strong&gt;bundle instal&lt;/strong&gt;l!!&lt;/p&gt;
&lt;p&gt;Bem, é isso ai galera! Aqui só tive esses probleminhas, agora esta a todo vapor!!&lt;/p&gt;
&lt;p&gt;Abraços&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7905971258</link><guid>http://diegonogueira.com.br/post/7905971258</guid><pubDate>Thu, 21 Jul 2011 21:27:00 -0300</pubDate><category>image magick</category><category>lion</category><category>mac</category><category>ruby on rails</category><category>rvm</category><category>osx</category></item><item><title>Chega de "RAILS_ENV=production"!!</title><description>&lt;pre&gt;&lt;code class="bash"&gt;rake db:migrate RAILS_ENV=production&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="bash"&gt;rails c production&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nossa.. como é chato ter que especificar o ambiente de produção a cada comando executado em nosso servidor&amp;#8230;&lt;/p&gt;
&lt;p&gt;Será que podemos fazer algo para automatizar isso? Infelizmente não&amp;#8230; teremos que conviver com isso pra sempre&amp;#8230;&lt;/p&gt;
&lt;p&gt;Brincadeira! Sempre tem algo que possamos fazer! E vamos ver agora!&lt;/p&gt;
&lt;p&gt;Para isso, em nosso servidor de produção, basta adicionar o código abaixo no arquivo &lt;strong&gt;&amp;#8221;~/.bashrc&amp;#8221;.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;export RAILS_ENV='production'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Somente isso! Da para acreditar? Agora podemos rodar nosso comandos prediletos assim:&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;rake db:migrate&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="bash"&gt;rails c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bem legal né?&lt;/p&gt;
&lt;p&gt;É isso ai pessoal, abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7800265407</link><guid>http://diegonogueira.com.br/post/7800265407</guid><pubDate>Tue, 19 Jul 2011 09:12:00 -0300</pubDate><category>RAILS_ENV</category><category>environment</category><category>production</category><category>ruby on rails</category><category>server</category><category>servidor</category><category>tips</category></item><item><title>Criando "alias" para todos os seus projetos de uma só vez!</title><description>&lt;p&gt;Essa dica é bem bacana, principalmente para poupar nosso tempo e saco! Toda vez que temos que ir para a pasta de um projeto é a mesma coisa, &lt;strong&gt;&amp;#8220;cd pasta/pasta_do_projeto/projeto&amp;#8221;&lt;/strong&gt;, fala sério né? muito chato isso&amp;#8230;&lt;/p&gt;
&lt;p&gt;Montei uma pequena função para me ajudar nesse trabalho. Basta colocar o código abaixo dentro do arquivo &lt;strong&gt;&amp;#8221;~/.bash_profile&amp;#8221;&lt;/strong&gt; se você estiver no Mac e no &lt;strong&gt;&amp;#8221;~/.bashrc&amp;#8221;&lt;/strong&gt; caso esteja no Linux e alterar o valor da variável &lt;strong&gt;&amp;#8220;projects_folder&amp;#8221;&lt;/strong&gt; para a pasta onde contenham os seus projetos.&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;projects_folder="$HOME/Documents/&lt;span&gt;projects&lt;/span&gt;"&lt;br/&gt;for i in $(ls "$&lt;span&gt;projects&lt;/span&gt;_folder")&lt;br/&gt;do
  alias "$i"="cd $&lt;span&gt;projects&lt;/span&gt;_folder/$i"&lt;br/&gt;done&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Feche e abra seu terminal para que as alterações sejam aplicadas e agora como num passe de mágica, basta digitar o nome do seu &lt;strong&gt;projeto&lt;/strong&gt; e teclar &lt;strong&gt;[enter]&lt;/strong&gt; que você será teletransportado para o seu projeto!&lt;/p&gt;
&lt;p&gt;Bem, é isso ai pessoal!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;ATENÇÃO: &lt;/strong&gt;Só tome muito cuidado com o nome do projeto para não conflitar com algum comando existente.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://diegonogueira.com.br/post/7773303506</link><guid>http://diegonogueira.com.br/post/7773303506</guid><pubDate>Mon, 18 Jul 2011 17:39:00 -0300</pubDate><category>linux</category><category>bash</category><category>alias</category><category>atalho</category><category>projetos</category></item><item><title>Exibindo o nome da branch atual no terminal</title><description>&lt;p&gt;Para quem trabalha com &lt;strong&gt;git&lt;/strong&gt;, sabe que as vezes diante de muitos projetos, fica confuso saber em que &lt;strong&gt;branch&lt;/strong&gt; estamos, precisamos usar o comando &lt;strong&gt;git branch -a&lt;/strong&gt; para nos localizar, certo?&lt;/p&gt;
&lt;p&gt;Para facilitar esse trabalho, podemos simplesmente exibir o nome da branch no prompt do nosso terminal. Para usuários de Mac, basta adicionar o código abaixo no arquivo &lt;strong&gt;~/.bash_profile&lt;/strong&gt;, usuários de linux, adicione no arquivo &lt;strong&gt;~/.bashrc&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;# SHOW GIT BRANCH
function parse_git_branch {
 git branch --no-color 2&amp;gt; /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="\u@\h:\W \$(parse_git_branch)\$ " &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pronto, agora toda vez que você entrar em um diretório que contenha uma estrutura git, será informado em qual branch você esta trabalhando, veja:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;diegoalvareznogueira@diego-macbook projeto (&lt;strong&gt;master&lt;/strong&gt;) $ &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Prático não?!&lt;/p&gt;
&lt;p&gt;Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7760714208</link><guid>http://diegonogueira.com.br/post/7760714208</guid><pubDate>Mon, 18 Jul 2011 10:17:00 -0300</pubDate><category>mac</category><category>linux</category><category>console</category><category>shell</category><category>git</category><category>branch</category><category>terminal</category><category>bash</category></item><item><title>Pesquisando dentro de um array</title><description>&lt;p&gt;Saindo uma dica bem fresquinha sobre como pesquisar dentro de um array!&lt;/p&gt;
&lt;p&gt;Imagine a seguinte situação:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;@users = User.all(:conditions =&amp;gt; ["country = ?", params[:country]])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Imagine que diante do resultado obtido em &lt;strong&gt;@users&lt;/strong&gt;, precisemos filtrar por usuários que morem no Estado do Rio de Janeiro. Sabemos que isso pode ser feito apenas adicionando mais uma condição como a de &lt;strong&gt;country&lt;/strong&gt; ao carregar os usuários&amp;#8230; só estou usando como exemplo, não vá me trazer todos os usuários do banco de dados e filtrar depois, ok?&lt;/p&gt;
&lt;p&gt;Bem, iremos utilizar o método &lt;a target="_blank" href="http://www.ruby-doc.org/core/classes/Array.html#M000251"&gt;select&lt;/a&gt; para fazer o filtro:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;@users.select { |user| user.state == "Rio de Janeiro" }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pronto! Molezinha né?&lt;/p&gt;
&lt;p&gt;Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7627195784</link><guid>http://diegonogueira.com.br/post/7627195784</guid><pubDate>Thu, 14 Jul 2011 18:23:12 -0300</pubDate><category>ruby on rails</category><category>array</category><category>hash</category><category>filter</category><category>select</category><category>find</category><category>tips</category></item><item><title>Construindo um sistema de autorização de usuário com herança</title><description>&lt;p&gt;Que tal construir um sistema simples e funcional de autorização de usuários de forma rápida e bem elegante?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Lembrando:&lt;/strong&gt; Quando falamos em autorização, estamos nos referindo as permissões dos usuários, o que cada tipo de usuário pode fazer ou não.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Acredito que a maioria das pessoas quando estudou orientação a objetos, teve como exemplo uma classe Cachorro que herda de uma classe Animal, certo? Vamos relembrar exemplo?&lt;/p&gt;
&lt;h3&gt;Relembrando&lt;/h3&gt;
&lt;h4&gt;Classe Animal&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Animal
  def comer
    ...
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Aqui temos uma classe Animal que possui um método &lt;strong&gt;comer&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;Classe Cachorro&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Cachorro &amp;lt; Animal
  def latir
    ...
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Já aqui, temos uma classe Cachorro que herda tudo de Animal, inclusive o método &lt;strong&gt;comer&lt;/strong&gt;. Sendo que a classe Cachorro possui um método único que não esta disponível na classe Animal, o método o &lt;strong&gt;latir&lt;/strong&gt;, pois não queremos que todos que herdarem de Animal tenham o método &lt;strong&gt;latir&lt;/strong&gt;, certo? Imaginem um gato latindo&amp;#8230; hmm seria meio estranho isso&amp;#8230; enfim, continuando&amp;#8230;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h4&gt;Classe Gato&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Gato &amp;lt; Animal
  def miar
    ...
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Da mesma forma que foi implementado a classe Cachorro, foi implementado a classe Gato, porém com seu método exclusivo &lt;strong&gt;miar&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Tá, e o que tudo isso tem haver com o sistema de autorização de usuários? Estamos querendo que pessoas utilizem nossas aplicações, não animais! Imagine chegar em casa e ver seu cachorro twittando?! Se bem que nos dias de hoje não duvido mais de nada&amp;#8230; ok, vamos em frente&amp;#8230; Se pararmos para analisar a estrutura acima, veremos que é exatamente isso que precisamos, não de cachorros twittando, mas sim em termos conceituais, vejam:&lt;/p&gt;
&lt;h3&gt;Cenário&lt;/h3&gt;
&lt;p&gt;Vamos imaginar um blog, não! Chega de exemplo de blog&amp;#8230; Vamos imaginar uma rede social, o Facebook por exemplo, onde:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Teremos usuários&lt;/li&gt;
&lt;li&gt;Apenas usuários com o tipo Manager podem ter grupos&lt;/li&gt;
&lt;li&gt;Um grupo terá comentários, porém somente quem estiver participando do grupo poderá postar um comentário&lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;Vamos lá?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Observação1:&lt;/strong&gt; Irei apenas tratar das permissões em si, não irei mencionar relacionamentos, validações e etc&amp;#8230;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Observação2:&lt;/strong&gt; Estou utilizando &lt;a title="STI" target="_blank" href="http://fernandoluizao.wordpress.com/2009/08/12/rails-otimizando-sti-com-default_scope/"&gt;STI&lt;/a&gt; para tratar tipos de usuários.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Primeiro vamos definir as permissões no modelo de grupos:&lt;/p&gt;
&lt;h4&gt;group.rb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Group &amp;lt; ActiveRecord::Base
  ... # associations, validations, scopes

  def is_owner?(_user)
    self.user == _user
  end

  def is_participant?(_user)
    self.participants.include?(_user)
  end

  # Permissions
  # Who can create a gruop?
  def self.can_create?(_user)
    _user.can_create_group?
  end

  # Who can edit this group?
  def can_edit?(_user)
    self.is_owner?(_user)
  end

  # Who can destroy this group?
  def can_destroy?(_user)
    self.is_owner?(_user)
  end

  # Who can create comments?
  def can_create_comment?(_user)
    self.is_owner?(_user) || self.is_participant?(_user)
  end

  # Who can destroy this comment?
  def can_destroy_comment?(_user, _comment)
    self.is_owner?(_user) || _comment.user == _user
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Começamos a definir aqui as permissões do grupo, quem pode criar, quem pode editar e quem pode remover. Cada permissão poderá ser chamada através de uma variável de instância.&lt;/p&gt;
&lt;h4&gt;user.rb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class User &amp;lt; ActiveRecord::Base
  ... # associations, validations, scopes

  # Permissions
  # Can create a gruop?
  def can_create_group?
    false
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;manager.rb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class Manager &amp;lt; User
  ... # associations, validations, scopes

  # Permissions
  # Can create a gruop?
  def can_create_group?
    true
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note que aqui algo interessante acontece, a classe &lt;strong&gt;User&lt;/strong&gt; possui o método &lt;strong&gt;can_create_group?&lt;/strong&gt; retornando &lt;strong&gt;false&lt;/strong&gt;, já a classe &lt;strong&gt;Manager&lt;/strong&gt; retornando &lt;strong&gt;true&lt;/strong&gt;, o que indica exatamente o que foi especificado nos nossos requisitos, onde somente os usuários do tipo &lt;strong&gt;Manger&lt;/strong&gt; poderão criar grupos. Dessa maneira, cada classe que herdar de &lt;strong&gt;User&lt;/strong&gt; automaticamente não poderá criar um grupo! Vamos implementar?&lt;/p&gt;
&lt;p&gt;Precisamos tratar para que somente usuários com permissão vejam o botão &amp;#8220;Criar novo grupo&amp;#8221;.&lt;/p&gt;
&lt;h4&gt;views/groups/index.html.erb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;...
  &amp;lt;%- if Group.can_create?(current_user) -%&amp;gt;
    &amp;lt;%= link_to "New Group", new_group_path %&amp;gt;
  &amp;lt;%- end -%&amp;gt;
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assim, onde tiver link para criar um novo grupo, será verificado se o usuário logado(&lt;strong&gt;current_user&lt;/strong&gt;) possui permissão ou não.&lt;/p&gt;
&lt;p&gt;Fácil, não? Então acabamos? Não&amp;#8230; imagine se o usuário souber a url para criar um novo grupo? ele poderá burlar seu sistema apenas copiando e colando na barra de endereço&amp;#8230;&lt;/p&gt;
&lt;p&gt;Então quer dizer que eu li esse post inteiro pra você vir e dizer que não funciona bem? Que não tem segurança?&lt;/p&gt;
&lt;p&gt;&lt;img width="250px" src="http://media.tumblr.com/tumblr_lo93tjmSAz1qkgnk3.png"/&gt;&lt;/p&gt;
&lt;p&gt;Fique tranquilo! Basta somente mudar as rotas para que fiquem bem difíceis! Brincadeira! Vamos a uma solução decente!&lt;/p&gt;
&lt;h3&gt;A solução&lt;/h3&gt;
&lt;h4&gt;groups_controller.rb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class GroupsController &amp;lt; ApplicationController
  before_filter :can_create?, :only =&amp;gt; [:new, :create] 
  ...
  private
  def can_create?
    redirect_to(groups_path, :notice =&amp;gt; "Malandrão!") unless Group.can_create?(current_user)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Problema resolvido! Caso o usuário tente forçar a url, passará pelo &lt;strong&gt;before_filter&lt;/strong&gt; no &lt;strong&gt;groups_controller.rb&lt;/strong&gt;, que verificará se o usuário possui permissão para criar um grupo! &lt;/p&gt;
&lt;p&gt;Da mesma forma iremos tratar quem poderá criar/remover um comentário em um grupo, utilizando os métodos &lt;strong&gt;can_create_comment?&lt;/strong&gt; e &lt;strong&gt;can_destroy_comment?&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Bem, é isso ai pessoal. Isso foi somente um exemplo de como você pode tratar autorização de usuários com herança, logicamente você terá de criar mais permissões para toda sua aplicação, mas seguindo esse modelo não tem erro!&lt;/p&gt;
&lt;p&gt;Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7586076499</link><guid>http://diegonogueira.com.br/post/7586076499</guid><pubDate>Wed, 13 Jul 2011 18:09:00 -0300</pubDate><category>autorização</category><category>boas práticas</category><category>herança</category><category>ruby on rails</category><category>tips</category><category>permissões</category></item><item><title>Ordenando uma lista a partir de uma tradução - I18n</title><description>&lt;p&gt;Bem, acredito que muitos já passaram por essa situação:&lt;/p&gt;
&lt;p&gt;Tenho uma tabela de categorias, por exemplo, com apenas os campos id e nome, porém o que é exibido ao usuário será a tradução desse campo nome, que esta definido nos arquivos do I18n, hummm complicado? que nada!&lt;/p&gt;
&lt;h3&gt;A Solução&lt;/h3&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;@categories = Category.all.collect{|i| [t(i.name),i.id]}.sort
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Basta somente varrer cada item, traduzindo e ordenando pelo campo name, retornando assim, um array como um todo.&lt;/p&gt;
&lt;p&gt;É isso ai! Espero que tenha ajudado de alguma forma!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7549847354</link><guid>http://diegonogueira.com.br/post/7549847354</guid><pubDate>Tue, 12 Jul 2011 19:57:00 -0300</pubDate><category>ruby on rail</category><category>i18n</category><category>tips</category><category>dicas</category><category>tradução</category><category>lista</category></item><item><title>NoSql - O que é? Porque usar? Quando usar?</title><description>&lt;h4&gt;Vídeo&lt;/h4&gt;
&lt;p&gt;&lt;iframe frameborder="0" height="225" width="400" src="http://player.vimeo.com/video/20994328?title=0&amp;amp;byline=0&amp;amp;portrait=0"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vimeo.com/20994328"&gt;NoSQL Databases: What, Why and When - Lorenzo Alberton&lt;/a&gt; from &lt;a href="http://vimeo.com/user6188686"&gt;PHP UK Conference&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Slide da apresentação&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;&lt;a title="NoSQL Databases: Why, what and when" target="_blank" href="http://www.slideshare.net/quipo/nosql-databases-why-what-and-when"&gt;NoSQL Databases: Why, what and when&lt;/a&gt;&lt;/strong&gt; &lt;iframe scrolling="no" marginheight="0" marginwidth="0" frameborder="0" height="497" width="595" src="http://www.slideshare.net/slideshow/embed_code/7080449"&gt;&lt;/iframe&gt; View more &lt;a target="_blank" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a target="_blank" href="http://www.slideshare.net/quipo"&gt;Lorenzo Alberton&lt;/a&gt;&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7547570701</link><guid>http://diegonogueira.com.br/post/7547570701</guid><pubDate>Tue, 12 Jul 2011 18:54:00 -0300</pubDate><category>ruby on rails</category><category>nosql</category><category>mongodb</category><category>couchdb</category><category>graph database</category><category>tips</category></item><item><title>Sim! Os "caches" são mágicos!</title><description>&lt;h3&gt;O problema&lt;/h3&gt;
&lt;p&gt;O que fazer quando nossa aplicação começa a demorar a responder?&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Otimizar o código?&lt;/li&gt;
&lt;li&gt;Rever os índices do banco?&lt;/li&gt;
&lt;li&gt;Aumentar a memória? &lt;/li&gt;
&lt;li&gt;Contratar um novo servidor?&lt;/li&gt;
&lt;li&gt;Escalar minha aplicação?&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Logicamente todas as opções são válidas, porém existem uma que pode nos surpreender, o uso de &lt;strong&gt;caches&lt;/strong&gt;! O rails possui nativamente esse recurso, porque não usa-lo?&lt;/p&gt;
&lt;h3&gt;Tipos de caches&lt;/h3&gt;
&lt;p&gt;Podemos trabalhar com três tipos de caches:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Page cache&lt;/li&gt;
&lt;li&gt;Action cache&lt;/li&gt;
&lt;li&gt;Fragment cache&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Porém hoje irei abordar somente o fragment cache, acredito ser o mais utilizado. Mas aconselho a conferirem os outros tipos também na &lt;a title="documentação do rails" target="_blank" href="http://guides.rubyonrails.org/caching_with_rails.html"&gt;documentação do rails&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Para quem não sabe, fragment cache nada mais é que guardar um pedaço de html, para que quando alguém acessar sua página, a aplicação não tenha que ir novamente ao banco de dados, coletar os dados e renderizar-lo em html. Funciona assim:&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;Vamos pegar a página do twitter como exemplo:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lo6xnoiLPh1qkgnk3.png"/&gt;&lt;/p&gt;
&lt;p&gt;Imagine se toda hora que alguém visitasse essa página, a aplicação do twitter tivesse que construir esse bloco de usuários? Seria muito custoso!&lt;/p&gt;
&lt;p&gt;Com o uso do fragment cache, a primeira vez que alguém acessa essa página é gerado um arquivo html, salvo em memória ou arquivo físico ( falarei mais sobre isso a baixo). Então quando os próximos usuários acessarem essa página novamente, não será mais necessário passar por todo processo para montar esse bloco, mas sim renderizar o html armazenado anteriormente, bem legal né?&lt;/p&gt;
&lt;p&gt;Não parece mas isso faz muita diferença, ainda mais se você levar em conta que você pode criar vários fragment caches para suas páginas.&lt;/p&gt;
&lt;p&gt;Então quer dizer que após gerado esse arquivo html, nunca mais mudará? Não, se fosse assim não seria nem um pouco útil. Pra isso existe o método &lt;strong&gt;expire_cache!&lt;/strong&gt; Vamos ver um exemplo?&lt;/p&gt;
&lt;h3&gt;Mãos a obra&lt;/h3&gt;
&lt;p&gt;Vamos tentar simular o caso do twitter, onde teremos apenas uma tabela de &lt;strong&gt;usuários&lt;/strong&gt; e uma tabela de &lt;strong&gt;amizades&lt;/strong&gt;, responsável pela associação entre os usuários:&lt;/p&gt;
&lt;h4&gt;users_controller.rb:&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;...
def show
  @user = User.find(params[:id])
  unless fragment_exist?("users_show_friendships_#{@user.id}")
    @friendships = @user.friendships
  end
  respond_to do |format|
    format.html
  end
end
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O método &lt;strong&gt;fragment_exist?(&amp;#8220;users_show_friendships_#{@user.id}&amp;#8221;)&lt;/strong&gt; verifica a existência do nosso cache de amizades do usuário, caso exista, não será necessário carregar a lista de amizades do usuário novamente.&lt;/p&gt;
&lt;p&gt;Repare que foi concatenado o &lt;strong&gt;id&lt;/strong&gt; do usuário ao nome do cache, isso porque o nome e logicamente seu conteúdo deve ser único para cada usuário, não queremos acessar a página de um usuário e visualizar a lista de amizades de outro usuário.&lt;/p&gt;
&lt;p&gt;Aqui já podemos ver uma significante redução de recurso, pois não será carregado a lista de amizades a toda requisição.&lt;/p&gt;
&lt;h4&gt;friendships_controller.rb:&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class FriendshipsController &amp;lt; ApplicationController
  cache_sweeper :friendship_sweeper, :only =&amp;gt; [:create, :destroy]
  ...
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para expirarmos o nosso cache, vamos definir o momento ideal, que no nosso caso será ao criar ou remover uma nova amizade, certo?&lt;/p&gt;
&lt;p&gt;Vamos utilizar pra isso o &lt;strong&gt;&lt;a title="sweepers" target="_blank" href="http://guides.rubyonrails.org/caching_with_rails.html#sweepers"&gt;sweeper&lt;/a&gt;&lt;/strong&gt;. Pense no sweeper como um observer, ele irá observar nosso modelo de &lt;strong&gt;friendship&lt;/strong&gt; nas ações &lt;strong&gt;:create, :destroy&lt;/strong&gt; do controle de friendships.&lt;/p&gt;
&lt;h4&gt;application.rb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;...
module Api
  class Application &amp;lt; Rails::Application
    config.autoload_paths += %W(#{config.root}/app/sweepers)
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos criar uma pasta &lt;strong&gt;app/sweepers&lt;/strong&gt; para colocarmos nosso &lt;strong&gt;friendship_sweeper.rb&lt;/strong&gt;. Não se esqueça de defini-la no &lt;strong&gt;application.rb&lt;/strong&gt;, para que seja carregada no boot da nossa aplicação.&lt;/p&gt;
&lt;h4&gt;friendship_sweeper.rb&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class FriendshipSweeper &amp;lt; ActionController::Caching::Sweeper
  observe Friendship

  def after_create(friendship)
    expire_cache_for(friendship)
  end
  
  def after_destroy(friendship)
    expire_cache_for(friendship)
  end

  def expire_cache_for(friendship)
    expire_fragment("users_show_friendships_#{friendship.user_id}")
    expire_fragment("users_show_friendships_#{friendship.friend_id}")
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Precisamos criar nosso &lt;strong&gt;friendship_sweeper.rb&lt;/strong&gt; na pasta &lt;strong&gt;app/sweepers&lt;/strong&gt;. Note que a sua estrutura é semelhante ao de um observer. Após a criação ou exclusão de uma amizade, será chamado o método expire_cache_for que o mesmo irá destruir os caches.&lt;/p&gt;
&lt;p&gt;Repare que estamos expirando &lt;strong&gt;dois&lt;/strong&gt; caches, pois queremos que tanto a lista de amizades do usuário seguidor como a do usuário seguido seja atualizada, certo?&lt;/p&gt;
&lt;h4&gt;show.html.erb:&lt;/h4&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;...
&amp;lt;%- cache("users_show_friendships_#{@user.id}") -%&amp;gt;
  &amp;lt;%- @friendships.each do |friend| -%&amp;gt;
    &amp;lt;%= friend.name %&amp;gt;
  &amp;lt;%- end -%&amp;gt;
&amp;lt;%- end -%&amp;gt;
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Por último, basta definirmos o bloco que conterá nosso cache.&lt;/p&gt;
&lt;p&gt;É isso ai pessoal, explorem bastante o uso de caches, eles são seus amigos e podem fazer a diferença!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;ATENÇÃO: Só tome cuidado onde irá colocar cache, pois se o bloco tiver atualizações constantes pode ser mais custoso para a aplicação ficar criando e destruindo caches do que simplesmente não te-los.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Abraços e até o próximo post!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7531847294</link><guid>http://diegonogueira.com.br/post/7531847294</guid><pubDate>Tue, 12 Jul 2011 10:20:00 -0300</pubDate><category>ruby on rails</category><category>tips</category><category>boas práticas</category><category>cache</category><category>otimização</category><category>performance</category></item><item><title>Find or create by ...</title><description>&lt;p&gt;Digamos que queremos procurar um usuário pelo seu e-mail e exibir seu nome, mas se esse usuário não existir, teremos que criá-lo.&lt;/p&gt;
&lt;p&gt;Uma maneira de fazer isso seria:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;@user = User.find_by_email("user@email.com")
unless @user
  @user User.create(:email =&amp;gt; "user@email.com", :name =&amp;gt; "User")
end
puts @user.name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Porém, podemos melhorar usando o &lt;strong&gt;find_or_create_by_email:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;@user = User.find_or_create_by_email("user@email.com", :name =&amp;gt; "User")
  puts @user.name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Podemos adicionar também mais condições neste método apenas incrementando com &lt;strong&gt;and&lt;/strong&gt;, por exemplo:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;@user = User.find_or_create_by_email_and_name("user@email.com", "User", :description =&amp;gt; "Olá")
  puts @user.name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Legal né?&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7494349917</link><guid>http://diegonogueira.com.br/post/7494349917</guid><pubDate>Mon, 11 Jul 2011 12:22:00 -0300</pubDate><category>mão na roda</category><category>tips</category><category>ruby on rails</category></item><item><title>Iniciando o blog mais uma vez</title><description>&lt;p&gt;Olá pessoal!&lt;/p&gt;
&lt;p&gt;Depois de um tempo sem escrever sobre desenvolvimento web, tentarei voltar a escrever.&lt;/p&gt;
&lt;p&gt;Como o blog anterior os posts ficaram defasados, irei iniciar do zero, sem aproveitar nenhum post. Prefiro criar novos conteúdos do que reaproveitar posts que talvez não funcionem mais como antes.&lt;/p&gt;
&lt;p&gt;É isso ai! Espero que gostem!&lt;/p&gt;
&lt;p&gt;Abraços!&lt;/p&gt;</description><link>http://diegonogueira.com.br/post/7491045497</link><guid>http://diegonogueira.com.br/post/7491045497</guid><pubDate>Mon, 11 Jul 2011 09:36:00 -0300</pubDate></item></channel></rss>

