<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>alejandro corpeño &#187; rails</title>
	<atom:link href="http://alejandro.corpeno.com/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://alejandro.corpeno.com</link>
	<description>web - programación - arte - negocios</description>
	<lastBuildDate>Thu, 26 Aug 2010 07:33:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Leyendo APIs desde Rails</title>
		<link>http://alejandro.corpeno.com/2009/11/12/leyendo-apis-desde-rails/</link>
		<comments>http://alejandro.corpeno.com/2009/11/12/leyendo-apis-desde-rails/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 23:12:01 +0000</pubDate>
		<dc:creator>corp</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[apis]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://alejandro.corpeno.com/?p=117</guid>
		<description><![CDATA[Esta semana tuve que integrar un sitio hecho en Rails con el API de wine.com. Mientras esta aplicación está en desarrollo se hospeda en un grid container pequeño de media temple.

Todo estaba funcionando bien en mi computadora cuando hice la integración usando el gem "hpricot", pero al subirlo al grid container tuve problemas. El log de Rails indicaba que el archivo hpricot_scan.so no era accesible.]]></description>
			<content:encoded><![CDATA[<p>Esta semana tuve que integrar un sitio hecho en Rails con el <a href="http://api.wine.com/wiki/api-object-dictionary">API de wine.com</a>. Mientras esta aplicación está en desarrollo se hospeda en un <a href="http://mediatemple.net/webhosting/gs/features/containers.php#ror" target="_blank">grid container</a> pequeño de media temple.</p>
<p><strong>El problema&#8230;</strong></p>
<p>Todo estaba funcionando bien en mi computadora cuando hice la integración usando el gem &#8220;hpricot&#8221;, pero al subirlo al grid container tuve problemas. El log de Rails indicaba que el archivo hpricot_scan.so no era accesible.</p>
<p>Encontré la solución <a href="http://www.cherpec.com/2009/06/hpricot-081-on-ruby-185/" target="_blank">en un blog</a>, el problema era que la versión de Ruby bajo la que operan los grid containers es la 1.8.5 y para esta versión hay unos problemas que requiren que se modifique el código fuente del gem.</p>
<p>OK, procedí a hacer los cambios en el código fuente tal como dice el artículo, pero me surgió otro problema&#8230;</p>
<pre><span style="color: #ff0000;">/usr/lib/ruby/1.8/fileutils.rb:754: command not found: ragel -v</span></pre>
<p>El  &#8220;rake&#8221; para regenerar el gem con los cambios requería &#8220;ragel&#8221; en el servidor&#8230;</p>
<p>Ya que los containers son pedazos virtuales de una maquina, no tengo acceso root para instalar nuevos paquetes, esto me impidió solucionar el problema:</p>
<ul>
<li>Instalando una versión más nueva de Ruby, por ejemplo 1.8.6 o 1.8.7</li>
<li>Instalando Ragel y completar el proceso de regenerar la gem hpricot</li>
</ul>
<p>Otra opción era pasar todo a un servidor dedicado y volver a preparar el ambiente de desarrollo, pasar la base de datos, etc&#8230; esto es factible pero no cuando necesito que mi cliente vea el update mañana.</p>
<p>La otra opción era hacer la integración nuevamente con algo diferente a  hpricot&#8230; opte por esta.</p>
<p><strong>La Solución</strong></p>
<p>Encontré <a href="http://railstips.org/2008/8/12/parsing-xml-with-ruby">un blog post</a> que compara tres formas de leer XML desde Rails&#8230; este me salvó ya que pude hacer la integración utilizando un método que no requiere librerías externas.</p>
<p>El artículo compara <a href="http://www.ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html">REXML</a>, <a href="http://wiki.github.com/hpricot/hpricot">Hpricot</a> y <a href="http://libxml.rubyforge.org/">libxml-ruby</a> &#8230; de todas la más lenta es REXML, pero es la que no depende de librerías externas y por lo tanto la que termine utilizando (probé con libxml pero tuve un problema similar).</p>
<p>Claro que esta es una solución temporal, solo para que mi contraparte en el proyecto pueda ver el avance.</p>
<p><strong>Ejemplo de Uso de REXML<br />
</strong></p>
<p>La solución con REXML es fácil de implementar y quiero compartirla en caso que alguien necesite leer XMLs desde una aplicación de Rails sin necesidad de usar librerías separadas.</p>
<p>Para el ejemplo usaremos el API de Twitter&#8230; este es el XML de mi timeline: <a href="http://twitter.com/statuses/user_timeline/corp.xml">http://twitter.com/statuses/user_timeline/corp.xml</a></p>
<p>Primero crearemos una función que recibe como parametro el usuario de twitter que queremos consultar, luego lee el XML correspondiente, lo almacena en un arreglo llamado <strong>twitts </strong>y lo devuelve con <strong>return twitts</strong>:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> get_twitts<span class="br0">&#40;</span>user<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;apiurl = <span class="st0">&quot;http://twitter.com/statuses/user_timeline/#{user}.xml&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;url = <span class="kw4">URI</span>.<span class="me1">parse</span><span class="br0">&#40;</span>apiurl<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;request = <span class="re2">Net::HTTP::Get</span>.<span class="me1">new</span><span class="br0">&#40;</span>apiurl<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;response,body = <span class="re2">Net::HTTP</span>.<span class="me1">new</span><span class="br0">&#40;</span>url.<span class="me1">host</span>, url.<span class="me1">port</span><span class="br0">&#41;</span>.<span class="me1">start</span> <span class="br0">&#123;</span>|http| http.<span class="me1">request</span><span class="br0">&#40;</span>request<span class="br0">&#41;</span> <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;twitts=<span class="br0">&#91;</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;doc = <span class="re2">REXML::Document</span>.<span class="me1">new</span><span class="br0">&#40;</span>body<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;doc.<span class="me1">elements</span>.<span class="me1">each</span><span class="br0">&#40;</span><span class="st0">&#8216;statuses/status&#8217;</span><span class="br0">&#41;</span> <span class="kw1">do</span> |s|</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;h = <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;%w<span class="br0">&#91;</span>created_at text source<span class="br0">&#93;</span>.<span class="me1">each</span> <span class="kw1">do</span> |a|</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;h<span class="br0">&#91;</span>a.<span class="me1">intern</span><span class="br0">&#93;</span> = s.<span class="me1">elements</span><span class="br0">&#91;</span>a<span class="br0">&#93;</span>.<span class="me1">text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;h<span class="br0">&#91;</span><span class="re3">:screen_name</span><span class="br0">&#93;</span> = s.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;user&#8217;</span><span class="br0">&#93;</span>.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;screen_name&#8217;</span><span class="br0">&#93;</span>.<span class="me1">text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;h<span class="br0">&#91;</span><span class="re3">:profile_image_url</span><span class="br0">&#93;</span> = s.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;user&#8217;</span><span class="br0">&#93;</span>.<span class="me1">elements</span><span class="br0">&#91;</span><span class="st0">&#8216;profile_image_url&#8217;</span><span class="br0">&#93;</span>.<span class="me1">text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;twitts &lt;&lt; h</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">return</span> twitts</div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<p>Ahora ya podríamos usar esta función en nuestro controller, enviandole el usuario como parámetro.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> show_mytwitts</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re1">@twitts</span> = get_twitts<span class="br0">&#40;</span><span class="st0">&quot;corp&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<p>Para mostrar los twitts que almacenamos en el controller, la vista sería algo así:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&lt;%<span class="kw1">for</span> twitt <span class="kw1">in</span> <span class="re1">@twitts</span> do%&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;img src=<span class="st0">&quot;&lt;%=twitt[:profile_image_url]%&gt;&quot;</span> width=<span class="st0">&quot;25&quot;</span> /&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;strong&gt;&lt;%=twitt<span class="br0">&#91;</span><span class="re3">:screen_name</span><span class="br0">&#93;</span>%&gt;:&lt;/strong&gt; &lt;%=twitt<span class="br0">&#91;</span><span class="re3">:text</span><span class="br0">&#93;</span>%&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; Enviado desde &lt;%=twitt<span class="br0">&#91;</span><span class="re3">:source</span><span class="br0">&#93;</span>%&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;hr /&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;%end%&gt;</div>
</li>
</ol>
</div>
<p><strong>Conclusión</strong></p>
<p>Hay muchas formas de leer XML desde Rails, de hecho las mejores y más elegantes facilitan mucho más el acceso a los datos por medio de integración con los modelos.</p>
<p>Lo que pude implementar con REXML es una solución rápida y simple que sirve para la etapa en que estas en desarrollo y para que tu cliente (socio o contraparte) pueda ver los resultados de la integración al API deseado.</p>
<p>Para producción conviene utilizar soluciones más eficientes. Mientras investigaba encontré esta presentación que describe muchas formas elegantes y más eficientes de leer XML con Rails:</p>
<div id="__ss_955192" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Ruby Xml Mapping" href="http://www.slideshare.net/marc.seeger/ruby-xml-mapping-presentation">Ruby Xml Mapping</a><object style="margin:0px" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ruby-xml-mapping-1233006534538089-1&amp;stripped_title=ruby-xml-mapping-presentation" /><param name="allowfullscreen" value="true" /><embed style="margin:0px" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ruby-xml-mapping-1233006534538089-1&amp;stripped_title=ruby-xml-mapping-presentation" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">documents</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/marc.seeger">Marc Seeger</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://alejandro.corpeno.com/2009/11/12/leyendo-apis-desde-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
