<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2portuguesefull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>AkitaOnRails.com</title><link>http://www.akitaonrails.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AkitaOnRails" /><language>en-US</language><lastBuildDate>Wed, 01 Feb 2012 17:53:31 PST</lastBuildDate><generator>AkitaOnRails http://www.akitaonrails.com</generator><feedburner:info uri="akitaonrails" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><description></description><meta xmlns="http://pipes.yahoo.com" name="pipes" content="noprocess" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FAkitaOnRails" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAkitaOnRails" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FAkitaOnRails" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/AkitaOnRails" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAkitaOnRails" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAkitaOnRails" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAkitaOnRails" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:browserFriendly>Dedicated to all free thinker skeptical inquirer out there.</feedburner:browserFriendly><item><title>Ruby 1.9.3-p0 e gem MySQL2 0.3.7</title><link>http://feedproxy.google.com/~r/AkitaOnRails/~3/MIgajL3Nscg/ruby-1-9-3-p0-e-gem-mysql2-0-3-7</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Fabio Akita</dc:creator><pubDate>Wed, 01 Feb 2012 17:53:31 PST</pubDate><guid isPermaLink="false">tag:www.akitaonrails.com,2008:Post/5417</guid><description>&lt;p&gt;Hoje bati com um probleminha ao tentar iniciar um aplicativo Rails 3.1.x sobre Ruby 1.9.3-p0 com a gem MySQL2 no meu Mac OS X Lion.&lt;/p&gt;
&lt;p&gt;Resumindo, é possível que você esbarre com o seguinte erro:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;dyld: lazy symbol binding failed: Symbol not found: _mysql2_set_field_string_encoding&lt;tt&gt;
&lt;/tt&gt;  Referenced from: /Users/akitaonrails/.rvm/gems/ruby-1.9.3-p0/gems/mysql2-0.3.7/lib/mysql2/mysql2.bundle&lt;tt&gt;
&lt;/tt&gt;  Expected in: flat namespace&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;dyld: Symbol not found: _mysql2_set_field_string_encoding&lt;tt&gt;
&lt;/tt&gt;  Referenced from: /Users/akitaonrails/.rvm/gems/ruby-1.9.3-p0/gems/mysql2-0.3.7/lib/mysql2/mysql2.bundle&lt;tt&gt;
&lt;/tt&gt;  Expected in: flat namespace&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Trace/BPT trap: 5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Esse problema foi reportado como bug no projeto do MySQL2 com o &lt;a href="https://github.com/brianmario/mysql2/issues/216"&gt;número #216&lt;/a&gt;. O criador e mantenedor da gem, Brian Mario já fez um &lt;a href="https://github.com/brianmario/mysql2/commit/d3a96b8"&gt;commit com a correção&lt;/a&gt;, basicamente a mudança é esta:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;-&lt;span class="di"&gt;inline&lt;/span&gt; VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {&lt;tt&gt;
&lt;/tt&gt;          &lt;span class="i"&gt;142&lt;/span&gt;        &lt;tt&gt;
&lt;/tt&gt;+&lt;span class="di"&gt;static&lt;/span&gt; VALUE mysql2_set_field_string_encoding(VALUE val, MYSQL_FIELD field, rb_encoding *default_internal_enc, rb_encoding *conn_enc) {&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Se quiser usar esta correção, modifique seu &lt;tt&gt;Gemfile&lt;/tt&gt; declarando a gem &lt;tt&gt;mysql2&lt;/tt&gt; da seguinte maneira:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;mysql2&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;~&amp;gt; 0.3.7&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;git://github.com/brianmario/mysql2.git&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:ref&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;d3a96b8&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;O Brian ainda não lançou uma nova versão da gem com a correção por isso podemos baixar diretamente do repositório no Github.&lt;/p&gt;
&lt;p&gt;Para atualizar execute &lt;tt&gt;bundle update mysql2&lt;/tt&gt;. Isso deve resolver esse problema.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/D9poLeFhqMPkPF36dQXMms-TMys/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D9poLeFhqMPkPF36dQXMms-TMys/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/D9poLeFhqMPkPF36dQXMms-TMys/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D9poLeFhqMPkPF36dQXMms-TMys/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=U3DQb0OPRIQ:IeIOwMHbxtc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=U3DQb0OPRIQ:IeIOwMHbxtc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=U3DQb0OPRIQ:IeIOwMHbxtc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=U3DQb0OPRIQ:IeIOwMHbxtc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=U3DQb0OPRIQ:IeIOwMHbxtc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=U3DQb0OPRIQ:IeIOwMHbxtc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AkitaOnRails/~4/MIgajL3Nscg" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.akitaonrails.com/2012/02/01/ruby-1-9-3-p0-e-gem-mysql2-0-3-7</feedburner:origLink></item><item><title>Lembrete: Bug de Rack Antigo (1.3.0)</title><link>http://feedproxy.google.com/~r/AkitaOnRails/~3/UcAquNf3svs/lembrete-bug-de-rack-antigo-1-3-0</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Fabio Akita</dc:creator><pubDate>Wed, 01 Feb 2012 06:08:05 PST</pubDate><guid isPermaLink="false">tag:www.akitaonrails.com,2008:Post/5416</guid><description>&lt;p&gt;Ano passado minha equipe colocou um grande projeto em produção. Por conta do &lt;a href="http://en.wikipedia.org/wiki/Non-disclosure_agreement"&gt;&lt;span class="caps"&gt;NDA&lt;/span&gt;&lt;/a&gt; assinado com o cliente, não podemos divulgar, posso dizer que era internacional e com grande tráfego. Porém quero descrever uma situação que passamos que talvez possa ajudar outros projetos mesmo sendo um bug antigo.&lt;/p&gt;
&lt;p&gt;Pesquisando esses dias esbarrei com &lt;a href="https://gist.github.com/1079284"&gt;este Gist&lt;/a&gt; do &lt;a href="https://gist.github.com/jnunemaker"&gt;John Nunemaker&lt;/a&gt;. Não afirmo que é exatamente o mesmo bug mas a descrição é idêntica. Em nosso caso, os servidores de produção estavam todos funcionando bem, mas aleatoriamente quando monitoramos víamos algumas das CPUs em 100%, se deixássemos mais algum tempo em breve todas as CPUs estavam no máximo e parando de responder.&lt;/p&gt;
&lt;p style="text-align: center"&gt;&lt;img src="http://akitaonrails.com/assets/2012/2/1/Screen%20shot%202011-05-04%20at%205.13.51%20_original.png?1328105433" alt="" /&gt;&lt;/p&gt;&lt;p&gt;Não havia uma situação especial, parecia bem aleatório. A única forma de recobrar o servidor era um bem não amigável &lt;tt&gt;kill -9&lt;/tt&gt; nos processsos que estavam a 100% já que o próprio monitor do Passenger também não conseguia reciclar os processos travados. Tentamos reproduzir em ambiente de desenvolvimento ou outro ambiente controlado mas essa situação não acontecia, era apenas em produção.&lt;/p&gt;
&lt;p&gt;Inicialmente achávamos que poderia ser algum bug no Passenger (chute). Procuramos a respeito em fóruns e listas de discussão. Encontramos relatos &lt;a href="https://groups.google.com/group/phusion-passenger/browse_thread/thread/b701df70d3ff9169"&gt;como este&lt;/a&gt;# que nunca foram confirmados como &amp;#8220;bug&amp;#8221;. Pensamos em substituir pelo Unicorn mas como não tínhamos certeza que o bug era no Passenger e nem tínhamos muito tempo, a solução &amp;#8211; nada elegante &amp;#8211; foi fazer um script no cron para matar os processos que ficavam presos em 100% por muito tempo. Não era a solução mas &amp;#8220;resolveu&amp;#8221; o problema.&lt;/p&gt;
&lt;p&gt;Só agora, meses depois, finalmente vi essa descrição do Nunemaker que bate muito com o que passamos e finalmente com um diagnóstico mais preciso. Como ele tentou eu também fiz dumps dos processos com gdb mas me falta conhecimento de gdb, strace e outras ferramentas de debug para encontrar o ponto exato do erro.&lt;/p&gt;
&lt;p&gt;A forma de reproduzir é abrir o &lt;span class="caps"&gt;IRB&lt;/span&gt; e executar:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;str = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http%3A%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26source%3Dweb%26cd%3D1%26sqi%3D2%26ved%3D0CCkQFjAA%26url%3Dhttp%253A%252F%252Fnd.edu%252F%26rct%3Dj%&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;str =~ &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="ch"&gt;\A&lt;/span&gt;&lt;span class="k"&gt;(?:%[0-9a-fA-F]{2}|[^%]+)*&lt;/span&gt;&lt;span class="ch"&gt;\z&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Se sua versão de Ruby ainda tiver o bug de regex, ele vai travar e a &lt;span class="caps"&gt;CPU&lt;/span&gt; vai pra 100%. Ctrl-C no terminal deve matar o processo. Essa situação acontece num aplicativo Web que usa Rack porque especificamente na versão 1.3.0 existe esse &lt;a href="https://github.com/rack/rack/blob/1.3.0/lib/rack/backports/uri/common.rb#L61"&gt;código na linha 61&lt;/a&gt;. Dependendo de quem estiver acessando seu site (crawlers do Google por exemplo) ele pode desencadear o bug travando seu processo (literalmente um Denial of Service).&lt;/p&gt;
&lt;p&gt;Esse erro acontece nos Ruby &lt;span class="caps"&gt;REE&lt;/span&gt; 1.8.7, nos 1.9.2. O teste exato acima não acontece no 1.9.3 porém ele acontece no próximo teste que tentei. Resolvi fazer um micro teste importando exatamente a versão com o bug do Rack:&lt;/p&gt;
&lt;script src="https://gist.github.com/1716989.js?file=test.rb"&gt;&lt;/script&gt;&lt;script src="https://gist.github.com/1716989.js?file=Gemfile"&gt;&lt;/script&gt;&lt;p&gt;Estranho que isso passa no meu Ruby 1.9.3-p0 embora essa mesma versão de Ruby falhe com o teste direto no &lt;span class="caps"&gt;IRB&lt;/span&gt; anterior. Ambos executam a mesma Regex na mesma string, só que um trava e a outra retorna (com exceção mas retorna). Ainda não entendi por que, provavelmente estou fazendo algo errado muito simples mas que não estou vendo (alguém tem idéias?)&lt;/p&gt;
&lt;p&gt;A versão 1.3.0 foi lançada no dia 23 de maio, aproximadamente a época em que colocamos a aplicação em produção. Me parece que as versões anteriores não tinham essa regex (e por outro lado não validavam a &lt;span class="caps"&gt;URI&lt;/span&gt; acima como errada). Porém não tenho certeza que não estávamos usando o Rack 1.2.5 ou anterior e nesse caso o bug não seria este. Infelizmente não temos mais acesso aos servidores de produção do cliente para ter certeza, mas se não for isso seria uma grande coincidência.&lt;/p&gt;
&lt;p&gt;A versão 1.3.1 &amp;#8211; lançada no dia 13 de julho &amp;#8211; já tem uma correção que modifica a regex para que ela não trave. Portanto a janela onde esse bug ficou no ar foi de 23 de maio a 13 de julho, se alguém rodou um &lt;tt&gt;bundle&lt;/tt&gt; nessa época e travou o Rack para a versão &lt;strong&gt;1.3.0&lt;/strong&gt; (cheque no seu &lt;tt&gt;Gemfile.lock&lt;/tt&gt;) esse pode ser um problema ainda ativo no seu servidor e precisa ser verificado.&lt;/p&gt;
&lt;p&gt;Para facilitar, a versão do Rails nessa época era 3.0.7, mas chequem projetos mais antigos também. Especialmente se você já viu, aleatoriamente, algum processo se prendendo a 100% de &lt;span class="caps"&gt;CPU&lt;/span&gt; sem nenhuma explicação aparente.&lt;/p&gt;
&lt;p&gt;Escrevi este artigo mais como um &lt;em&gt;post-mortem&lt;/em&gt; porque passamos por esse problema nessa época de maio a julho no ano passado e ele ficou sem solução, e eu detesto problemas sem solução.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dOF4a8rctkzdzucc3emEpLv53T0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dOF4a8rctkzdzucc3emEpLv53T0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dOF4a8rctkzdzucc3emEpLv53T0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dOF4a8rctkzdzucc3emEpLv53T0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=F8zK78Hf16o:DGpgSQpJW_k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=F8zK78Hf16o:DGpgSQpJW_k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=F8zK78Hf16o:DGpgSQpJW_k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=F8zK78Hf16o:DGpgSQpJW_k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=F8zK78Hf16o:DGpgSQpJW_k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=F8zK78Hf16o:DGpgSQpJW_k:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AkitaOnRails/~4/UcAquNf3svs" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.akitaonrails.com/2012/02/01/lembrete-bug-de-rack-antigo-1-3-0</feedburner:origLink></item><item><title>[Off-Topic] Mensagem de Ano Novo - Filosofia</title><link>http://feedproxy.google.com/~r/AkitaOnRails/~3/kQiKtbZlyFM/off-topic-mensagem-de-ano-novo-filosofia</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Fabio Akita</dc:creator><pubDate>Sat, 31 Dec 2011 15:29:16 PST</pubDate><guid isPermaLink="false">tag:www.akitaonrails.com,2008:Post/5415</guid><description>&lt;div style="float: left; margin: 4px"&gt;&lt;a href="http://www.amazon.com/Why-Businessmen-Need-Philosophy-Rand/dp/0962533629"&gt;&lt;img src="http://akitaonrails.com/assets/2011/12/31/ref=dp_image_0_original.jpeg?1325374073" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;Este foi um longo ano, pessoalmente foi um dos piores e um dos melhores tudo ao mesmo tempo. Uma consequência foi que bloguei muito pouco, mas 2012 deve ser o ano do retorno. Para fechar o ano bem, acho que este ano com tantas novas startups e tantos novos interessados em explorar as oportunidades de serem empreendedores devem levar a sério e entender a verdadeira filosofia por trás de qualquer empreendimento capitalista (verdadeiramente capitalista e não este capitalismo-misto medíocre que a maioria pratica). Sem uma filosofia adequada, o mundo dos negócios não vai muito longe.&lt;/p&gt;
&lt;p&gt;Obviamente, busco minha fonte nos artigos de Ayn Rand e Leonard Peikoff, como uma entrada &lt;em&gt;light&lt;/em&gt; vamos ver o artigo &lt;a href="http://atlasshrugged.com/articles/an-answer-for-businessmen/"&gt;Uma Resposta para Empresários&lt;/a&gt;,  publicado em 15 de maio de 1962, em uma revista de notícias não identificada encontrada entre os documentos de Ayn Rand. Terminando esta introdução, veja o principal, &lt;a href="http://atlasshrugged.com/articles/why-businessmen-need-philosophy/"&gt;Por que Empresários Precisam de Filosofia&lt;/a&gt;, escrito por Leonard Peikoff, e é um trecho do &lt;a href="http://www.amazon.com/Why-Businessmen-Need-Philosophy-Rand/dp/0962533629"&gt;livro de mesmo nome&lt;/a&gt; que todo interessado em empreender deveria ler.&lt;/p&gt;&lt;h2&gt;Uma Resposta para Empresários&lt;/h2&gt;
&lt;p&gt;Se você quer salvar o capitalismo só existe um tipo de argumento que você deve adotar, o único que sempre ganhou em qualquer disputa moral: o argumento da auto-estima. Cheque suas premissas, se convença de que sua causa é correta, então lute pelo capitalismo com completa e certeira moral.&lt;/p&gt;
&lt;p&gt;A crise mundial de hoje é uma crise moral &amp;#8211; e nada menos do que uma revolução moral pode resolvê-la: uma revolução moral para sancionar e completar a conquista política da revolução Americana. Devemos lutar pelo capitalismo, não como uma disputa prática, não como uma disputa econômica, mas, com o maior orgulho de justiça, como uma disputa moral. É isso que o capitalismo merece, e nada menos irá salvá-la.&lt;/p&gt;
&lt;p&gt;Gostaria de dizer que você deve começar aplicando ao mundo das idéias o mesmo critério objetivo, lógico, racional de julgamento que você aplica ao mundo dos negócios. Você não julga disputas de negócios usando padrões emocionais &amp;#8211; não faça isso em disputas ideológicas. Você não constrói fábricas guiado pelas suas emoções &amp;#8211; não deixe suas emoções guiarem suas convicções políticas.&lt;/p&gt;
&lt;h2&gt;Não tente enganar as pessoas nos negócios&lt;/h2&gt;
&lt;p&gt;Você não conta com a estupidez dos homens em negócios, você não lança produtos de qualidade inferior &amp;#8220;porque as pessoas são idiotas demais para apreciar o melhor&amp;#8221;, não faça isso em filosofia política; não endorse ou propague idéias que você sabe serem falsas, na esperança de conquistar o medo, preconceitos ou ignorância das pessoas. Você não engana as pessoas em negócios &amp;#8211; não tente fazer isso na filosofia: os chamados homens comuns são perceptivos de forma incomum.&lt;/p&gt;
&lt;p&gt;Você não duvida de seu próprio julgamento nos negócios &amp;#8211; não duvide no mundo da ideologia; não deixe a bobagem inintelegível dos intelectuais &amp;#8220;liberais&amp;#8221; o intimidar ou desencorajá-lo; não conclua: &amp;#8220;deve ser profundo, porque eu não entendo isso&amp;#8221; ou &amp;#8220;se é assim que as coisas de intelectuais se parecem, então todas as idéias são impraticáveis e não fazem sentido&amp;#8221;. Idéias são o maior e mais crucial poder da Terra.&lt;/p&gt;
&lt;p&gt;Você não contrata homens como cabeças dos seus departamentos de negócios, sem conhecimento prévio da natureza dos seus trabalhos e como julgar suas performances &amp;#8211; não faça isso em relação ao seu departamento de relações públicas; aprenda a julgar se o que estão lhe vendendo é veneno ou não. Você não contrata doutores-bruxos como mecânicos ou engenheiros &amp;#8211; não os contrate como relações públicas.&lt;/p&gt;
&lt;h2&gt;Conheça seus amigos e seus inimigos&lt;/h2&gt;
&lt;p&gt;Aprenda a diferenciar seus amigos de seus inimigos. Saiba quem dar suporte em disputas ideológicas e políticas. Se você não consegue dizer livremente, se estiver preso e engasgado pela desgraçada injustiça de tais maus como leis antitruste &amp;#8211; no mínimo, não elogie, espalhe ou suporte a filosofia de seus próprios destruidores; não lhes dê a sanção das vítimas. Pense um pouco na possibilidade de estabelecer um sindicato de liberdades civis &amp;#8211; para empresários.&lt;/p&gt;
&lt;p&gt;E se tem o desejo de ter uma missão ou propósito &amp;#8220;social&amp;#8221; &amp;#8211; não existe serviço maior à humanidade do que lutar pelos seus próprios direitos e propriedades.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RWpDbJLvr8Vw1r_uauKB-zKbMdg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RWpDbJLvr8Vw1r_uauKB-zKbMdg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RWpDbJLvr8Vw1r_uauKB-zKbMdg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RWpDbJLvr8Vw1r_uauKB-zKbMdg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=gxFNVDwLyY8:rRcMenwXdyU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=gxFNVDwLyY8:rRcMenwXdyU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=gxFNVDwLyY8:rRcMenwXdyU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=gxFNVDwLyY8:rRcMenwXdyU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=gxFNVDwLyY8:rRcMenwXdyU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=gxFNVDwLyY8:rRcMenwXdyU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AkitaOnRails/~4/kQiKtbZlyFM" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.akitaonrails.com/2011/12/31/off-topic-mensagem-de-ano-novo-filosofia</feedburner:origLink></item><item><title>[Journey to Japan #3] Exclusive Video Interviews</title><link>http://feedproxy.google.com/~r/AkitaOnRails/~3/82R9V60ggro/journey-to-japan-3-exclusive-video-interviews</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Fabio Akita</dc:creator><pubDate>Sun, 27 Nov 2011 20:40:20 PST</pubDate><guid isPermaLink="false">tag:www.akitaonrails.com,2008:Post/5414</guid><description>&lt;p&gt;It&amp;#8217;s been a while since I&amp;#8217;ve written about my &lt;a href="http://akitaonrails.com/2011/08/05/journey-to-japan-2-the-final-rubykaigi"&gt;Ruby Kaigi 2011 trip&lt;/a&gt;. Since then I&amp;#8217;ve been really busy and I left out lots of great material shamelessly accumulating dust in my hard drive, but no more. Today I was finally able to edit some of that and upload the interviews I have recorded with some of the most well known Japanese Ruby contributors. Wonderful people that I was lucky to meet and that were very friendly to me and eager to tell their stories.&lt;/p&gt;
&lt;p&gt;These are the first versions of the edited videos, I still didn&amp;#8217;t have time to add English subtitles, but I wanted to upload them as soon as possible so the Japanese community could check them out first. I will try to add the subtitles in the following days (help would be appreciated). The Matz interview in particular has the worst audio as we were in the middle of an after-party in a small bar with very bad acoustics, so I apologize for its quality, I hope you can get most out of it.&lt;/p&gt;
&lt;p&gt;Alencar Koga helped me out a lot during the interviews. Coincidentally he is a Brazilian just like me, but he&amp;#8217;s been living in Japan for a long time and was able to build a great career, being now the &lt;span class="caps"&gt;CTO&lt;/span&gt; of &lt;span class="caps"&gt;MTI&lt;/span&gt; Japan, one of the largest mobile app developers in the country. Akira Matsuda also helped me a lot, and he is also a very well known Rubyist in Japan. Both were edited out of the videos to make them shorter to watch. I appreciate their help a lot as they will be very useful when I do the English subtitles.&lt;/p&gt;&lt;p&gt;The first three videos were recorded at the after-party in the first day of Ruby Kaigi. I have to admit that I was not in my best shape after having a few drinks and after a full day of event :-) By the way, the second and third video interviews were introduced by me in Brazilian Portuguese instead of English, so forgive me for my confusion. All of them have myself making questions in English and the guests replying back in Japanese. Only the Matz interview is all in English.&lt;/p&gt;
&lt;p&gt;Shintaro Kakutani-san was the first one I&amp;#8217;ve interviewed, being one of the main organizers of the event and a long time Ruby evangelist in Japan. He is a very active community leader, helping maintain the Japanese Ruby ecosystem.&lt;/p&gt;
&lt;p&gt;&lt;iframe width="640" height="360" src="http://www.youtube.com/embed/npkrGATZYi0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;The second one was Gotou Yuzou-san, he is one of the oldest Ruby Core Committers being the author of both Webrick and OpenSSL. He wrote a few books about Ruby in Japan and he works for the Tokyo branch of Nacl, the company from Matsue that has been contributing to Ruby since the beginning, hiring Matz as a fellow researcher.&lt;/p&gt;
&lt;p&gt;&lt;iframe width="640" height="360" src="http://www.youtube.com/embed/bpXIIFShCo0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;The third one was recorded when the party was over. I was able to reach the couple Yasuko and Koichiro Ohba. Yasuko-san is well known being the president of the consulting company EveryLeaf. She employs several Ruby developers and does Ruby related projects and now mobile development as well. She is an example of entrepreneurship in the community. Koichiro-san works for a Heroku-like company in Japan, managing Cloud based infrastructure using JRuby technology. He contributes and evangelizes JRuby, specially in terms of documentation, localization (internationalization, etc).&lt;/p&gt;
&lt;p&gt;&lt;iframe width="640" height="360" src="http://www.youtube.com/embed/4tBSXYHGtk4" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;On the second day of the event I was able to catch up with Nobuyoshi Nakada-san. He is &amp;#8220;the&amp;#8221; oldest Ruby Core Contributor, and he probably touched every single part of Ruby. He is also known as &amp;#8220;the patch monster&amp;#8221; as he seems to be a coding machine, being more active through out the last 15 years than Matz himself. He deserved to be the first one Matz chose to follow him at SalesForce.com.&lt;/p&gt;
&lt;p&gt;&lt;iframe width="640" height="360" src="http://www.youtube.com/embed/6A9eq3aaDVw" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Finally, at the Heroku Drink up in the last day of the event, I was finally able to grab Matz himself for an interview. Having been continuously and consistently on this road for that last few years, you can imagine how thrilled I was for having being able to interview Matz himself in person, at my home land in Japan. But as I&amp;#8217;ve warned before, the audio is not good because of all the noise. At least Matz can speak English so everybody will be able to get most of this one.&lt;/p&gt;
&lt;p&gt;&lt;iframe width="640" height="360" src="http://www.youtube.com/embed/JBOWc7U2ed8" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Enjoy them all. This is for all of my friends in Japan! Thanks again for the hospitality.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7YZgAKfjSJEzTEjna6k6Z9gdOXc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7YZgAKfjSJEzTEjna6k6Z9gdOXc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7YZgAKfjSJEzTEjna6k6Z9gdOXc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7YZgAKfjSJEzTEjna6k6Z9gdOXc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=J0f32I4YBzE:jErV9R_LBd4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=J0f32I4YBzE:jErV9R_LBd4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=J0f32I4YBzE:jErV9R_LBd4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=J0f32I4YBzE:jErV9R_LBd4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=J0f32I4YBzE:jErV9R_LBd4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=J0f32I4YBzE:jErV9R_LBd4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AkitaOnRails/~4/82R9V60ggro" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.akitaonrails.com/2011/11/28/journey-to-japan-3-exclusive-video-interviews</feedburner:origLink></item><item><title>Páginas Estáticas no Rails</title><link>http://feedproxy.google.com/~r/AkitaOnRails/~3/TBGkSxRhYdM/paginas-estaticas-no-rails</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Fabio Akita</dc:creator><pubDate>Thu, 10 Nov 2011 19:38:10 PST</pubDate><guid isPermaLink="false">tag:www.akitaonrails.com,2008:Post/5413</guid><description>&lt;p&gt;Faz tempo que não posto uma dica técnica, vou retornando aos poucos. Hoje uma dica bem simples mas que muitos ainda desconhecem.&lt;/p&gt;
&lt;p&gt;Muitos aplicativos Rails tem seções com páginas estáticas, páginas de conteúdo como institucional, instruções, etc. Digamos que para organizar isso você tenha criado um controller chamado &amp;#8220;Page&amp;#8221;, assim:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;bundle exec rails g controller Page&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;O problema é que eu sempre vejo algo parecido com isto no &lt;tt&gt;config/routes.rb&lt;/tt&gt;&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;  match &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page/hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page#hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  match &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page/help&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page#help&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Daí no &lt;tt&gt;app/controllers/page_controller.rb&lt;/tt&gt; encontro:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;hello&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;help&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Actions vazias de &lt;em&gt;placeholder&lt;/em&gt; somente para renderizar páginas estáticas como &lt;tt&gt;app/views/page/hello.html.erb&lt;/tt&gt;. E este exemplo tem apenas duas páginas, agora escale isso para algumas dezenas e você verá logo o &lt;em&gt;code smell&lt;/em&gt; de um clássico &lt;em&gt;efeito shotgun&lt;/em&gt;: múltiplos &lt;tt&gt;match&lt;/tt&gt; redundantes no &lt;tt&gt;routes.rb&lt;/tt&gt; e múltiplos métodos vazios no controller.&lt;/p&gt;
&lt;p&gt;Em vez disso, uma das muitas formas de resolver esse problema é fazer simplesmente isto no arquivo &lt;tt&gt;config/routes.rb&lt;/tt&gt;:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;  get &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page/:id&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page#index&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:as&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:page&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;E no controller &amp;#8220;Page&amp;#8221; ter uma única action:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    render params[&lt;span class="sy"&gt;:id&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Agora você pode colocar quantas views quiser em &lt;tt&gt;app/views/page&lt;/tt&gt; e quando chamar &lt;tt&gt;http://localhost:3000/page/hello&lt;/tt&gt; ele irá automaticamente mapear para &lt;tt&gt;app/views/page/hello.html.erb&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Eu disse &amp;#8220;páginas estáticas&amp;#8221; mas na verdade seriam &amp;#8220;semi-estáticas&amp;#8221; já que normalmente faríamos desta forma porque queremos que a página herde o layout principal e tudo mais. Se for para ser uma página realmente estática, fora do layout padrão do site, etc, você pode simplesmente colocar um html no diretório &lt;tt&gt;public&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Dá para melhorar mais isso, fazendo algumas checagens óbvias como validar se o template da página existe:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; params[&lt;span class="sy"&gt;:id&lt;/span&gt;] &amp;amp;&amp;amp; template_exists?(params[&lt;span class="sy"&gt;:id&lt;/span&gt;], [&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;      render params[&lt;span class="sy"&gt;:id&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      redirect_to &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/404.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:status&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;404&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;A dica é a mesma de sempre: se está parecendo um amontoado de copy &amp;amp; paste em todas as camadas, alguma coisa está definitivamente errada. Como eu disse antes, existem múltiplas maneiras para resolver essa funcionalidade, se tiverem outras melhores, não deixem de comentar.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3nlYB9sg1HBPi-T70CaGDGMkEWs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3nlYB9sg1HBPi-T70CaGDGMkEWs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3nlYB9sg1HBPi-T70CaGDGMkEWs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3nlYB9sg1HBPi-T70CaGDGMkEWs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=YH9MKGKbAlw:gmZIMgBKgJM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=YH9MKGKbAlw:gmZIMgBKgJM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=YH9MKGKbAlw:gmZIMgBKgJM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=YH9MKGKbAlw:gmZIMgBKgJM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?i=YH9MKGKbAlw:gmZIMgBKgJM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AkitaOnRails?a=YH9MKGKbAlw:gmZIMgBKgJM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AkitaOnRails?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AkitaOnRails/~4/TBGkSxRhYdM" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.akitaonrails.com/2011/11/11/paginas-estaticas-no-rails</feedburner:origLink></item></channel></rss>

