<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Jordi Romero</title>
	
	<link>http://jrom.net</link>
	<description>Blog de Jordi Romero con articulos sobre programación, aplicaciones web, informática y tecnología en general.</description>
	<lastBuildDate>Mon, 21 Sep 2009 16:56:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JROM" /><feedburner:info uri="jrom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FJROM" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>Tabulador en Mac OS X</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/bYFrvwYHH54/tabulador-en-mac-os-x</link>
		<comments>http://jrom.net/tabulador-en-mac-os-x#comments</comments>
		<pubDate>Mon, 21 Sep 2009 16:54:34 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=272</guid>
		<description><![CDATA[Parece una chorrada, pero todos los switchers tienen el mismo problema: no siempre pueden saltar de un botón a otro con la tecla ⇥ (TAB o tabulador). La (senzilla) solución es la que sigue:
Abrir Preferencias del Sistema (en el directorio Aplicaciones / Utilidades, o ⇧ + ⌘ + U), luego abrir Teclado Y Ratón y ahí modificar [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-274" title="Teclado y Ratón" src="http://jrom.net/wp-content/uploads/2009/09/teclado-y-raton.png" alt="Teclado y Ratón" width="80" height="78" />Parece una chorrada, pero todos los <em>switchers</em> tienen el mismo problema: no siempre pueden saltar de un botón a otro con la tecla ⇥ (TAB o tabulador). La (senzilla) solución es la que sigue:</p>
<p>Abrir <strong>Preferencias del Sistema</strong> (en el directorio Aplicaciones / Utilidades, o ⇧ + ⌘ + U), luego abrir <strong>Teclado Y Ratón</strong> y ahí modificar la opción <strong>Acceso total al teclado</strong> dejándola como: <strong>Todos los controles</strong>. (Probado en Leopard).</p>
<p><img class="alignnone size-medium wp-image-279" title="Teclado y Ratón / Todos los campos" src="http://jrom.net/wp-content/uploads/2009/09/tab-todos-los-campos-500x447.png" alt="Teclado y Ratón / Todos los campos" width="500" height="447" /></p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/bYFrvwYHH54" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/tabulador-en-mac-os-x/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://jrom.net/tabulador-en-mac-os-x</feedburner:origLink></item>
		<item>
		<title>Seed Data en Rails 2.3.4</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/310izBX6MyE/179-seed-data</link>
		<comments>http://jrom.net/seed-data-en-rails-2-3-4#comments</comments>
		<pubDate>Mon, 14 Sep 2009 19:17:16 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Enlaces]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=233</guid>
		<description><![CDATA[Útil y breve screencast de Ryan Bates sobre una nueva característica introducida en la versión 2.3.4 de Ruby on Rails: Seed Data.
Nos explica como rellenar la base de datos con &#8220;valores iniciales&#8221;, muy útil para: crear un usuario administrador si no existe, poblar una tabla de [países, ciudades, categorías, ...].
 ⚙ ]]></description>
			<content:encoded><![CDATA[<p>Útil y breve screencast de Ryan Bates sobre una nueva característica introducida en la versión 2.3.4 de Ruby on Rails: Seed Data.</p>
<p>Nos explica como rellenar la base de datos con &#8220;valores iniciales&#8221;, muy útil para: crear un usuario administrador si no existe, poblar una tabla de [países, ciudades, categorías, ...].</p>
<div><a title="Leer ‘Seed Data en Rails 2.3.4’ en jrom.net" href="http://jrom.net/seed-data-en-rails-2-3-4"> <big><big><big>⚙</big></big></big> </a></div><img src="http://feeds.feedburner.com/~r/JROM/~4/310izBX6MyE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/seed-data-en-rails-2-3-4/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://railscasts.com/episodes/179-seed-data</feedburner:origLink></item>
		<item>
		<title>Git: descentralizado y rápido</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/HLq8m_vDKzw/git-descentralizado-y-rapido</link>
		<comments>http://jrom.net/git-descentralizado-y-rapido#comments</comments>
		<pubDate>Sun, 13 Sep 2009 20:17:56 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=202</guid>
		<description><![CDATA[Cuando hace un año me puse a hacer una pequeña revisión (guiño involuntario..) de los sistemas de control de versiones existentes y populares, tardé muy poco en darme cuenta de cuál era el verdadero VCS que lo estaba petando.
Git es el nuevo dueño. Subversion llegó para comerse CVS. Git simplemente estando ahí, los ha devorado a [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando hace <a href="http://jrom.net/introduccion-control-de-versiones">un año</a> me puse a hacer una pequeña revisión (guiño involuntario..) de los sistemas de control de versiones existentes y populares, tardé muy poco en darme cuenta de cuál era el verdadero <a title="Version Control System" href="http://es.wikipedia.org/wiki/Control_de_versiones">VCS</a> que <em>lo estaba petando</em>.</p>
<p><a title="Git - Fast Version Control System" href="http://git-scm.com/">Git</a> es el nuevo dueño. Subversion llegó para comerse CVS. Git simplemente estando ahí, los ha devorado a todos. Por qué?</p>
<p>Resumiendo, porque es un sistema <strong>descentralizado</strong>. O puede serlo. O puede ser centralizado. Git es lo que tu quieras que sea. Un repositorio Git no está en un servidor donde tu haces <em>commits</em> y <em>checkouts</em>, aunque podría. Para aclarar un poco este lío, voy a intentar explicar el funcionamiento básico de Git, y porque se diferencia esencialmente de Subversion <em>et al</em>.</p>
<p>Un repositorio Git es un directorio situado en la raíz del directorio de trabajo (me estoy planteando dejar de traducir aleatoriamente y empezar a hablar de las cosas por su nombre: working directory). Éste contiene toda la información sobre los ficheros del repositorio, tanto en su versión actual como todo su historial. Cada revisión de un documento se almacena tal cual, como un objeto más, identificado por un nombre de 40 caracteres que se obtiene por una función de hash SHA1. Con lo de &#8220;tal cual&#8221; me refiero a que no se basa en diferenciales entre versiones (como hace Subversion), sino que cada versión de un fichero se almacena íntegramente. Sorprendentemente esto es eficiente en espacio y tiempo!</p>
<p>En resumen: cada proyecto en el que usemos Git tendrá un directorio en su raíz (por defecto llamado .git), que contendrá todo lo que haya pasado por el proyecto. Esto es la descentralización: no tenemos ninguna dependencia con un servidor. Podemos estar trabajando un mes <em>offline</em>, y luego sincronizar con el servidor.</p>
<p>Ah, pero hay servidor?</p>
<p>Puede haberlo. Aunque Git sea brutalmente útil en trabajos en solitario, <em>&#8220;com més serem, més riurem&#8221;</em>. Como he dicho, cada copia local de un repositorio Git es válida por si misma, y no necesita de ningún servidor, aunque Git nos ofrece la posibilidad de mandar mensajes entre copias del mismo repositorio y &#8220;sincronizarse&#8221; por decirlo de alguna forma. Así que si queremos, podemos sustituir fielmente la estructura de un servidor SVN con sus usuarios haciendo <em>commits</em> / <em>checkouts</em> a él, por un repositorio Git almacenado en un servidor y varias copias de éste que hagan <em>push</em> / <em>pull</em> cuando tengan cambios.</p>
<p>Prometedor, y aún no he nombrado la <em>killer feature</em> de Git: branch &amp; merge. Cuántas veces has creado una rama (odio traducir! quiero decir <em>branch</em>, se llama <em>branch</em>, pero si no traduzco, parece que estemos en Puerto Rico (no offense!)) en un repositorio Subversion/CVS? Yo sólo un par de veces. Usando Git en una docena de proyectos, ya he creado (y luego fusionado casi todas ellas) unas 50 ramas (<em>branches</em>, sí). Precisamente debido a la descentralización de Git, puedes estar trabajando en un proyecto dónde hay un servidor, dónde mas gente participa, y querer implementar una nueva característica que va a afectar muchos ficheros a la vez (no siempre aislamos suficientemente el código..). Intentar hacerlo &#8220;de un sólo <em>commit</em>&#8221; (<a title="Siete de un sólo golpe!" href="http://www.youtube.com/watch?v=a_kNsONdeBw" target="_blank">como diría el Sastrecillo Valiente</a>), no es muy sensato. Así que hacemos un <em>branch</em> (me he hartado) en nuestro ordenador, empezamos a meter mano al código, y si al cabo de 40 <em>commits</em> no funciona nada, nos cargamos el <em>branch</em>. Si llegamos a buen puerto, en cambio, podemos hacer fusionar  el nuestro con el repositorio del servidor, y nuestros cambios ya estarán disponibles para el resto del equipo! Y lo mejor de todo, es muy fácil hacer un <em>merge</em> aún cuando otros han ido modificando el código mientras nosotros trabajábamos, haciendo un <em><a href="http://book.git-scm.com/4_rebasing.html">rebase</a></em> y obteniendo nosotros los cambios del resto del equipo para mezclarlos con nuestro <em>branch</em>, para ver si son compatibles (si no lo son, solucionar los conflictos) y entonces fusionarnos sin colisiones. Easy as pie.</p>
<p>Aunque los detalles de branching &amp; merging parezcan confusos (no es trivial explicar su funcionamiento en cuatro líneas), es muy sencillo y potente. Recomiendo las siguientes lecturas para profundizar en el tema, y los que no estéis usando Git hagáis el paso cuando no podáis aguantar más:</p>
<ul>
<li><a title="Git Internals, por Scott Chacon" href="https://peepcode.com/products/git-internals-pdf">Git Internals</a> &#8211; Scott Chacon, PDF, $9 bien invertidos</li>
<li><a title="The Git Community Book" href="http://book.git-scm.com/">The Git Community Book</a> &#8211; Página oficial de Git</li>
<li><a title="Starting with Git" href="http://blog.sirupsen.dk/guides/starting-with-git/">Starting with Git</a> &#8211; Sirupsen&#8217;s Blog</li>
</ul>
<img src="http://feeds.feedburner.com/~r/JROM/~4/HLq8m_vDKzw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/git-descentralizado-y-rapido/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://jrom.net/git-descentralizado-y-rapido</feedburner:origLink></item>
		<item>
		<title>Creando una aplicación web con Ruby on Rails: Capítulo 2</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/-jguM_LQxKM/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-2</link>
		<comments>http://jrom.net/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-2#comments</comments>
		<pubDate>Tue, 24 Mar 2009 21:52:22 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=168</guid>
		<description><![CDATA[Seguimos donde lo dejamos, rápidamente nos dedicaremos a preparar el layout general de la página y empezaremos a poner Ajax por todas partes.
Se suele comentar que Rails y Ajax se llevan bien. Vamos a demostrarlo creando una pequeña aplicación pseudo GTD para mantener una lista de TODO’s.
En Rails un layout es una vista especial: es [...]]]></description>
			<content:encoded><![CDATA[<p>Seguimos <a href="/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-1" title="Creando una aplicación web con Ruby on Rails: Capítulo 1">donde lo dejamos</a>, rápidamente nos dedicaremos a preparar el <em>layout</em> general de la página y empezaremos a poner Ajax por todas partes.</p>
<blockquote><p>Se suele comentar que Rails y Ajax se llevan bien. Vamos a demostrarlo creando una pequeña aplicación pseudo GTD para mantener una lista de TODO’s.</p></blockquote>
<p>En Rails un <em>layout</em> es una vista especial: es la parte común en un grupo de controladores/acciones. En muchas aplicaciones, con uno o dos layouts nos bastará, por ejemplo: uno para usuarios sin identificar y otro para los miembros, etc. En nuestra aplicación <strong>microtodo</strong> sólo necesitaremos uno. El generador <em>scaffold</em> nos generó el único fichero que podemos encontrar en <code>app/views/layouts</code>: <code>todo_items.html.erb</code>.</p>
<p>Muy típico de Rails: <a href="http://wiki.rubyonrails.org/getting-started/overview/tenets#convention_over_configuration" title="Convention over Configuration en Ruby on Rails">Convention over Configuration</a>. Si no decimos nada, el controlador <code>TodoItemsController</code> buscará si existe un layout llamado <code>todo_items</code>, y si no lo encuentra después buscará uno llamado <code>application</code>. Podemos sobreescribir estas convenciones poniendo <code>layout :nuevo_layout</code> en el controlador, pero ahora no nos interesa.</p>
<p>Lo primero que haremos con este layout es cambiarle el nombre precisamente a <code>application.html.erb</code>, para que sirva para posibles nuevos controladores. Después le haremos un pequeño lavado de cara dejándolo así:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
       &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&nbsp;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;charset=UTF-8&quot; /&gt;
  &lt;title&gt;Micro Todo&lt;/title&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">stylesheet_link_tag</span> <span style="color:#996600;">'scaffold'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">javascript_include_tag</span> <span style="color:#ff3333; font-weight:bold;">:defaults</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/head&gt;
&lt;body&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#5A0A0A; font-weight:bold;">flash</span>.<span style="color:#5A0A0A; font-weight:bold;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>key, msg<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">content_tag</span> <span style="color:#ff3333; font-weight:bold;">:div</span>, msg, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> key <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&nbsp;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>Es bastante sencillo: <code>stylesheet_link_tag 'scaffold'</code> usa un helper que nos ofrece Rails para insertar la etiqueta &lt;link&gt; y el fichero CSS en cuestión (scaffold.css). Usar este helper tiene algunas ventajas que ahora no estudiaremos, como por ejemplo <em>cachear</em> los ficheros de estilo. Lo mismo sirve para <code>javascript_include_tag</code>, aunque este usa la palabra <em>defaults</em> que se traduce en los ficheros necesarios para usar <a href="http://www.prototypejs.org/" title="Javascript Framework">Prototype</a> y <a href="http://script.aculo.us/" title="Javascript library para Efectos chulos">Scriptaculous</a> (Los usaremos para el Ajax).</p>
<p>Finalmente hay este bloque Ruby tan chulo y que puede parecer difícil de entender, aunque hace una cosa bien sencilla: Para cada <code>flash[:algo]</code> que exista, ponemos un <code>&lt;div id=&quot;algo&quot;&gt;Con su contenido.&lt;/div&gt;</code>. Esto nos servirá tanto para <code>flash[:error]</code> como para <code>flash[:notice]</code>, o cualquier otro que nos inventemos.</p>
<p>La última palabra Ruby del layout es la palabra mágica <code>yield</code>. Se sustituirá por el contenido de la vista de la acción que se esté ejecutando (<em>index</em>, <em>edit</em>, <em>add</em>, &#8230;). Espero no ir demasiado lento profundizando en los detalles, pero al ser un tutorial para principiantes&#8230; Pido paciencia a los iniciados que lo estén siguiendo.</p>
<p>Queremos tener el formulario para añadir tareas en la página principal, y que al pulsar el botón Add o la tecla Enter se añada a la lista la tarea mediante Ajax. Volvemos a modificar <code>app/views/todo_items/index.html.erb</code> para usar <em>partials</em> y añadir el formulario:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- index.html.erb --&gt;
&lt;h1&gt;Things To Do&lt;/h1&gt;
&nbsp;
&lt;div id=&quot;todos&quot;&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#0066ff; font-weight:bold;">@todo_items</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/div&gt;
&lt;br /&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#5A0A0A; font-weight:bold;">form_remote_for</span> TodoItem.<span style="color:#5A0A0A; font-weight:bold;">new</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">text_field</span> <span style="color:#ff3333; font-weight:bold;">:task</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">submit</span> <span style="color:#996600;">&quot;Add&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></td></tr></table></div>

<p>Como podéis observar, hemos simplificado mucho el código que lista las tareas usando <code>render @todo_items</code>. Rails es muy listo, y observa que <code>@todo_items</code> es un array de <code>todo_item</code>, y piensa: Si me piden hacer un render de un <code>todo_item</code>, a lo mejor es que hay un <em>partial</em> para este&#8230; Y (oh! qué casualidad) justo acabo de crear un fichero llamado <code>_todo_item.html.erb</code> en <code>app/views/todo_items/</code>. Para que os funcione teneis que crearlo y dejarlo así:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- _todo_item.html.erb --&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> div_for todo_item <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= h todo_item.<span style="color:#9900CC;">task</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  (<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Edit'</span>, edit_todo_item_path<span style="color:#006600; font-weight:bold;">&#40;</span>todo_item<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>)
  &lt;small&gt;(<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Destroy'</span>, todo_item, <span style="color:#ff3333; font-weight:bold;">:confirm</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Are you sure?'</span>, <span style="color:#ff3333; font-weight:bold;">:method</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:delete</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>)&lt;/small&gt;
  &lt;span&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= todo_item.<span style="color:#9900CC;">completed_at</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/span&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

<p>Seguramente habréis observado que he puesto <code>form_remote_for</code> en lugar de <code>form_for</code>, y aquí empieza el Ajax: Esto mandará el contenido del formulario en una llamada Ajax, y en lugar de refrescar el navegador ejecutará lo que el controlador le diga. Así que vamos al controlador y cambiamos un poco el método <code>create</code>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> create
  <span style="color:#0066ff; font-weight:bold;">@todo_item</span> = TodoItem.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:todo_item</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>.<span style="color:#9900CC;">save</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'Todo Item added!.'</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>todo_items_url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>, <span style="color:#ff3333; font-weight:bold;">:location</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">js</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;new&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>.<span style="color:#9900CC;">errors</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:unprocessable_entity</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Hemos añadido la línia <code>format.js</code> en el bloque <code>respond_to do |format|</code>. Esto lo que hará es responder tamién al método <em>create</em> si se pide con <code>Content-Type: text/javascript</code>, que es lo que hará la llamada Ajax, pero responderá usando el view <code>create.js.rjs</code>. Hasta ahora todos los views tenian la doble extensión .html.erb, que significa que se trata de ficheros <strong>HTML</strong> procesados con <strong>ERB</strong> (Embedded Ruby). Ahora ofrecemos un fichero <strong>JavaScript</strong> usando <strong>RJS</strong>, un lenguaje muy simple para generar código JavaScript escribiendo Ruby. Este fichero estará obviamente en <code>app/views/todo_items/</code> y será así:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># create.js.rjs</span>
page.<span style="color:#9900CC;">insert_html</span> <span style="color:#ff3333; font-weight:bold;">:bottom</span>, <span style="color:#ff3333; font-weight:bold;">:todos</span>, <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'todo_item'</span>, <span style="color:#ff3333; font-weight:bold;">:object</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>
page.<span style="color:#9900CC;">visual_effect</span> <span style="color:#ff3333; font-weight:bold;">:highlight</span>, <span style="color:#996600;">&quot;todo_item_#{@todo_item.id}&quot;</span>
page<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:new_todo_item</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">reset</span>
flash.<span style="color:#9900CC;">discard</span></pre></td></tr></table></div>

<p>Resumiendo: La primera línea generará el <em>partial</em> con el objeto recién creado en el controlador y lo añadirá al final de <code>&lt;div id=&quot;todos&quot;&gt;</code>. La segunda hará un efecto de sobresalto en la tarea recién añadida, la tercera vaciará el formulario y con la última descartaremos el mensaje flash que se añade en el controlador. La magia de Ajax y Rails es que este código Ruby se convertirá en JavaScript, y gracias a <code>form_remote_for</code> se mandará de vuelta al cliente, donde se ejecutará dejándonos asombrados a nosotros mismos de lo que sómos capaces de hacer.</p>
<p>Ahora (sólo porque me conviene que se vean las cosas un poco mejor) añadiremos un poco de CSS al final de <code>public/stylesheets/scaffold.css</code></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
</pre></td><td class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.todo_item</span>
<span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">5px</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#DADADA</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.todo_item</span> span
<span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">0.7em</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#747474</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
body
<span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #993333;">auto</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;"><span style="color: #cc66cc;">60</span>%</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>Lo último que haremos en este capítulo es completar y descompletar las tareas mediante un checkbox que usando Ajax actualizará el estado de la tarea. Dado que estamos usando un controlador REST, tenemos que modificar el fichero <code>config/routes.rb</code> para permitir una nueva acción: <em>toggle</em>, que cambiará de completado a pendiente una tarea. Modificamos el fichero:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">ActionController::Routing::Routes</span>.<span style="color:#9900CC;">draw</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>map<span style="color:#006600; font-weight:bold;">|</span>
&nbsp;
  map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:todo_items</span>, <span style="color:#ff3333; font-weight:bold;">:member</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:toggle</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:put</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:todo_items</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Ahora añadimos el método <em>toggle</em> en <code>TodoItemsController</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>87
88
89
90
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> toggle
  <span style="color:#0066ff; font-weight:bold;">@todo_item</span> = TodoItem.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0066ff; font-weight:bold;">@todo_item</span>.<span style="color:#9900CC;">update_attribute</span> <span style="color:#ff3333; font-weight:bold;">:completed_at</span>, <span style="color:#006600; font-weight:bold;">&#40;</span>@todo_item.<span style="color:#9900CC;">completed_at</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>? ? <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span> : <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Añadimos el checkbox al parcial <code>_todo_item.html.erb</code></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- _todo_item.html.erb --&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> div_for todo_item <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span>= check_box_tag <span style="color:#ff3333; font-weight:bold;">:completed_at</span>, <span style="color:#996600;">&quot;1&quot;</span>, !todo_item.<span style="color:#9900CC;">completed_at</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?,
                  <span style="color:#ff3333; font-weight:bold;">:onclick</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#5A0A0A; font-weight:bold;">remote_function</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> toggle_todo_item_path<span style="color:#006600; font-weight:bold;">&#40;</span>todo_item<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#ff3333; font-weight:bold;">:method</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:put</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= h todo_item.<span style="color:#9900CC;">task</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  (<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Edit'</span>, edit_todo_item_path<span style="color:#006600; font-weight:bold;">&#40;</span>todo_item<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>)
  &lt;small&gt;(<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Destroy'</span>, todo_item, <span style="color:#ff3333; font-weight:bold;">:confirm</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Are you sure?'</span>, <span style="color:#ff3333; font-weight:bold;">:method</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:delete</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>)&lt;/small&gt;
  &lt;span&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= todo_item.<span style="color:#9900CC;">completed_at</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/span&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

<p>Y sólo nos falta crear otro fichero RJS: <code>toggle.js.rjs</code> junto a las otras vistas de <code>views/todo_items</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># toggle.js.rjs</span>
page.<span style="color:#9900CC;">replace</span> <span style="color:#996600;">&quot;todo_item_#{@todo_item.id}&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'todo_item'</span>, <span style="color:#ff3333; font-weight:bold;">:object</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>
page.<span style="color:#9900CC;">visual_effect</span> <span style="color:#ff3333; font-weight:bold;">:highlight</span>, <span style="color:#996600;">&quot;todo_item_#{@todo_item.id}&quot;</span></pre></td></tr></table></div>

<p>Esto es todo por hoy. Os podéis bajar el código de <a href="http://github.com/jrom/microtodo/tree/chapter-2" title="Código de Microtodo para el Capítulo 2 en Github">Github</a> usando Git o directamente <a href="http://github.com/jrom/microtodo/zipball/chapter-2" title="ZIP con el código de Microtodo para el Capítulo 2">un fichero comprimido</a>. Y para los más perezosos que tienen ganas de ver cómo funciona esto del Ajax pero no quieren probar el código o instalar Ruby on Rails, podéis ver este pequeño screencast de 30 segundos (sin audio):<br />
<a href="http://jrom.net/wp-content/uploads/2009/03/demo-microtodo.mov" title="Screencast Microtodo"><img src="http://jrom.net/wp-content/uploads/2009/03/demo-microtodo-poster.jpg" alt="Imagen del Screencast de Microtodo" title="Imagen del Screencast de Microtodo" width="500" height="350" class="alignnone size-full wp-image-196" /></a></p>
<p>Dejo para el próximo capítulo separar las tareas pendientes de las completadas, eliminarlas usando ajax, cambiarles el texto in-situ y reordenarlas! (Recordáis el campo <code>position:integer</code> de nuestra migración?).</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/-jguM_LQxKM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-2/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
<enclosure url="http://jrom.net/wp-content/uploads/2009/03/demo-microtodo.mov" length="320886" type="video/quicktime" />
		<feedburner:origLink>http://jrom.net/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-2</feedburner:origLink></item>
		<item>
		<title>Creando una aplicación web con Ruby on Rails: Capítulo 1</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/GbIxD4zMKR8/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-1</link>
		<comments>http://jrom.net/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-1#comments</comments>
		<pubDate>Sun, 22 Mar 2009 22:58:53 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=120</guid>
		<description><![CDATA[Se suele comentar que Rails y Ajax se llevan bien. Vamos a demostrarlo creando una pequeña aplicación pseudo GTD para mantener una lista de TODO&#8217;s. Aunque en el primer capítulo aún no se verá Ajax, aparecerá muy pronto. Fácilmente se puede extender para gestionar varias listas, pero interesa mantener el código simple.
Comprovamos las versiones de Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>Se suele comentar que Rails y Ajax se llevan bien. Vamos a demostrarlo creando una pequeña aplicación pseudo <a title="Buscar Getting Things Done en Google" href="http://www.google.com/search?q=getting+things+done">GTD</a> para mantener una lista de TODO&#8217;s. Aunque en el primer capítulo aún no se verá Ajax, aparecerá muy pronto. Fácilmente se puede extender para gestionar varias listas, pero interesa mantener el código simple.</p>
<p>Comprovamos las versiones de Ruby y Rails, y creamos la aplicación con el comando <code>rails</code>. El comando <code>mate .</code> abre el editor <a title="Editor de texto TextMate" href="http://macromates.com/">TextMate</a> (sólo para Mac OS X). Aquí usad el equivalente para vuestro editor o simplemente abrid el directorio con vuestro navegador de ficheros.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~<span style="color: #000000; font-weight: bold;">%</span> ruby <span style="color: #660033;">-v</span>
ruby 1.8.6 <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2008</span>-03-03 patchlevel <span style="color: #000000;">114</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>universal-darwin9.0<span style="color: #7a0874; font-weight: bold;">&#93;</span>
~<span style="color: #000000; font-weight: bold;">%</span> rails <span style="color: #660033;">-v</span>
Rails 2.3.2
~<span style="color: #000000; font-weight: bold;">%</span> rails microtodo
      create
      create  app<span style="color: #000000; font-weight: bold;">/</span>controllers
      <span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
      create  log<span style="color: #000000; font-weight: bold;">/</span>test.log
~<span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">cd</span> microtodo
~<span style="color: #000000; font-weight: bold;">/</span>microtodo<span style="color: #000000; font-weight: bold;">%</span> mate .</pre></div></div>

<p>Ahora toca respirar un poco y curiosear por el directorio que acabamos de crear y llenar. Podríamos ejecutar <code>script/server</code> y abrir con nuestro navegador <a href="http://0.0.0.0:3000/">http://0.0.0.0:3000/</a> para ver la página inicial de Rails, pero si habéis seguido la entrada anterior, esto no es necesario.</p>
<p>A continuación nos cargaremos esta página inicial (el objetivo es ver la lista de tareas por hacer cuando vayamos a la página principal) y usaremos el generador <em>scaffold</em> para las tareas. Crearemos el modelo <code>TodoItem</code> y la migración a la base de datos con tres campos: <code>task: string</code> (descripción de la tarea), <code>position: integer</code> (para poder reorganizar las tareas como nos parezca) y <code>completed_at: timestamp</code> (para saber si una tarea se ha completado y en qué instante se ha hecho). Una migración es un pequeño código ruby que se convertirá en sentencias <accron title="Structured Query Language">SQL</accron > al ejecutar el comando <code>rake db:migrate</code>. Recomiendo echar un vistazo a la <a title="Migraciones en Ruby on Rails" href="http://guides.rubyonrails.org/migrations.html">guía sobre migrations</a>. El generador <em>scaffold</em> además crea el controlador <code>TodoItemsController</code>, las vistas para las acciones <a href="http://es.wikipedia.org/wiki/CRUD" title="Create, Read, Update, Delete">CRUD</a>, un <em>layout</em> para el controlador y un fichero css básico.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~<span style="color: #000000; font-weight: bold;">/</span>microtodo<span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> public<span style="color: #000000; font-weight: bold;">/</span>index.html
~<span style="color: #000000; font-weight: bold;">/</span>microtodo<span style="color: #000000; font-weight: bold;">%</span> script<span style="color: #000000; font-weight: bold;">/</span>generate scaffold TodoItem task:string position:integer completed_at:timestamp
      <span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
~<span style="color: #000000; font-weight: bold;">/</span>microtodo<span style="color: #000000; font-weight: bold;">%</span> rake db:migrate
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jordi<span style="color: #000000; font-weight: bold;">/</span>microtodo<span style="color: #7a0874; font-weight: bold;">&#41;</span>
==  CreateTodoItems: migrating ================================================
<span style="color: #660033;">--</span> create_table<span style="color: #7a0874; font-weight: bold;">&#40;</span>:todo_items<span style="color: #7a0874; font-weight: bold;">&#41;</span>
   -<span style="color: #000000; font-weight: bold;">&gt;</span> 0.0037s
==  CreateTodoItems: migrated <span style="color: #7a0874; font-weight: bold;">&#40;</span>0.0041s<span style="color: #7a0874; font-weight: bold;">&#41;</span> =======================================
&nbsp;
~<span style="color: #000000; font-weight: bold;">/</span>microtodo<span style="color: #000000; font-weight: bold;">%</span></pre></div></div>

<p>Ahora es un buen momento para ejecutar <code>script/server</code> y jugar un poco con las tareas generadas por el <em>scaffold</em>. A continuación vamos a hacer que el controlador <code>TodoItemsController</code> responda a la página inicial modificando el fichero <code>config/routes.rb</code> y dejándolo así:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">ActionController::Routing::Routes</span>.<span style="color:#9900CC;">draw</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>map<span style="color:#006600; font-weight:bold;">|</span>
&nbsp;
  map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:todo_items</span>
  map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:todo_items</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Hoy acabaremos el capítulo uno limpiando un poco los views modificando los ficheros de <code>app/views/todo_items</code>. Primero borraremos el fichero <code>show.html.erb</code> puesto que no nos interesa una página para cada To Do Item, luego editaremos <code>index.html.erb</code>, <code>edit.html.erb</code> y <code>new.html.erb</code> y crearemos <code>_form.html.erb</code> con este contenido:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- index.html.erb --&gt;
&lt;h1&gt;Things To Do&lt;/h1&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#0066ff; font-weight:bold;">@todo_items</span>.<span style="color:#5A0A0A; font-weight:bold;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>todo_item<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span> div_for todo_item <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= h todo_item.<span style="color:#9900CC;">task</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    (<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Edit'</span>, edit_todo_item_path<span style="color:#006600; font-weight:bold;">&#40;</span>todo_item<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>)
    &lt;small&gt;(<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Destroy'</span>, todo_item, <span style="color:#ff3333; font-weight:bold;">:confirm</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Are you sure?'</span>, <span style="color:#ff3333; font-weight:bold;">:method</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:delete</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>)&lt;/small&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&nbsp;
&lt;br /&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Add To Do Item'</span>, new_todo_item_path <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

<p>Aquí observamos el uso del iterador <code>each</code> sobre la variable <code>@todo_items</code> que se crea en el controlador. Se usa el clásico bloque de Ruby, y para cada <code>todo_item</code> usamos los helpers que Rails nos ofrece para definir un <code>&lt;div&gt;</code> que contiene la descripción de la tarea y enlaces para editarla y eliminarla. Sustituiremos estos enlaces por edición y eliminación in-situ usando Ajax, pero será en otro capítulo.</p>
<p>Vamos las vistas de las acciones <em>edit</em> y <em>new</em>, que son muy parecidas:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- edit.html.erb --&gt;
&lt;h1&gt;Editing To Do Item&lt;/h1&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;form&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:locals</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:todo_item</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>, <span style="color:#ff3333; font-weight:bold;">:button_label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Update Item&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Back'</span>, todo_items_path <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- new.html.erb --&gt;
&lt;h1&gt;New To Do Item&lt;/h1&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;form&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:locals</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:todo_item</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@todo_item</span>, <span style="color:#ff3333; font-weight:bold;">:button_label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Add Item&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">'Back'</span>, todo_items_path <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

<p>Aquí, además de usar el helper <code>link_to</code> que ya hemos visto en la anterior vista, utilizamos <code>render :partial</code>, que es una herramienta muy potente que permite mantener el código mas limpio siguiendo fielmente el principio <a href="http://wiki.rubyonrails.org/getting-started/overview/tenets#don_t_repeat_yourself_dry" title="Don't Repeat Yourself">DRY</a>. Más información en la guía <a href="http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials" title="Guía: Render partial en Rails">Layout and Rendering</a>.</p>
<p>Finalmente, la nueva vista que se usará en las acciones <em>edit</em> y <em>new</em> para mostrar el formulario. Tener este formulario duplicado era muy poco <accron title="Don't Repeat Yourself">DRY</accron>, y puesto que usamos los <em>helpers</em> de Rails para crear los campos del formulario, si el objeto <code>todo_item</code> contiene información se mostrará en el campo creado por el <em>helper</em>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">&lt;!-- _form.html.erb --&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#5A0A0A; font-weight:bold;">form_for</span><span style="color:#006600; font-weight:bold;">&#40;</span>todo_item<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">error_messages</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;p&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:task</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;br /&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">text_field</span> <span style="color:#ff3333; font-weight:bold;">:task</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;/p&gt;
  &lt;p&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">submit</span> button_label <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;/p&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

<p>Casi estamos por hoy, pero si nos cargamos la vista para la acción <em>show</em>, tenemos que modificar el controlador para que nunca intente llevarnos a ver un To Do Item. Concretamente, el controlador creado por el scaffolding hace un redirect a la página <code>/todo_items/ID</code> después de crear o editar una tarea. Cambiaremos este comportamiento modificando las acciones <code>create</code > y <code>update</code>.</p>
<p>Modificamos las líneas 48 y 65 del fichero <code>app/controllers/todo_items_controller.rb</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>48
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@todo_item<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>65
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@todo_item<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<p>por</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>48
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>todo_items_url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>65
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>todo_items_url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></td></tr></table></div>

<p>Hasta aquí en este primer capítulo. En el próximo haremos que toda la acción suceda en una página, insertando tareas desde la página principal y haciendo que una tarea se pueda completar con un checkbox, ambas acciones usando Ajax.</p>
<p>He colgado el proyecto en <a href="http://github.com/jrom/microtodo/tree" title="Aplicación web Micro Todo en Github">Github</a>, por si en lugar de seguir los pasos queréis consultar directamente el resultado. Si no usáis Git, os podéis bajar un tarball también desde <a href="http://github.com/jrom/microtodo/downloads" title="Bajar un tarball de Github">Github</a>.</p>
<p>Responderé encantado cualquier duda que aparezca siguiendo este tutorial.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/GbIxD4zMKR8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-1/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://jrom.net/creando-una-aplicacion-web-con-ruby-on-rails-capitulo-1</feedburner:origLink></item>
		<item>
		<title>La verdadera definición de Ruby on Rails</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/hXWxtNrXZLw/la-verdadera-definicion-de-ruby-on-rails</link>
		<comments>http://jrom.net/la-verdadera-definicion-de-ruby-on-rails#comments</comments>
		<pubDate>Thu, 19 Mar 2009 22:14:57 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=93</guid>
		<description><![CDATA[La definición de Ruby on Rails dice:
&#8220;Ruby on Rails es un Framework para desarrollar aplicaciones web escrito en Ruby.&#8221;
Bueno, esto es casi tan inútil como cierto. Qué es un framework? Nunca he visto dos veces la misma definición para esta palabra: herramienta, conjunto de herramientas, entorno de trabajo, estructura de soporte, &#8230; Y &#8220;uno de esos&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p><strong>La definición</strong> de Ruby on Rails dice:</p>
<blockquote><p>&#8220;Ruby on Rails es un Framework para desarrollar aplicaciones web escrito en Ruby.&#8221;</p></blockquote>
<p>Bueno, esto es casi tan inútil como cierto. Qué es un <em>framework</em>? Nunca he visto dos veces la misma definición para esta palabra: herramienta, conjunto de herramientas, entorno de trabajo, estructura de soporte, &#8230; Y &#8220;uno de esos&#8221; escrito en ruby? Más confuso aún.</p>
<p>Creo que se entiende mejor así:</p>
<blockquote><p>&#8220;Ruby on Rails es una aplicación web vacía, esperando a ser completada con código Ruby.&#8221;</p>
<p>&#8220;Ruby on Rails es una aplicación que usa el patrón MVC.&#8221;</p>
<p>&#8220;Ruby on Rails es Active Record [<strong>M</strong>]: La persistencia de datos como problema se desvanece.&#8221;</p>
<p>&#8220;Ruby on Rails es Action View [<strong>V</strong>]: Crear documentos HTML (y otros formatos) dinámicos con cuatro palabras en Ruby.&#8221;</p>
<p>&#8220;Ruby on Rails es Action Controller [<strong>C</strong>]: Ejecutar acciones dependiendo de la URL, gestionar las redirecciones, sesiones, mandar trabajo a Action View o Active Record en muy poco código.&#8221;</p>
<p>&#8220;Ruby on Rails es una aplicación web que se puede testear, que se debe testear, que te hará querer testear!&#8221;</p>
<p>&#8220;Ruby on Rails es una comunidad que no para de escribir <a title="Rails en Github" href="http://github.com/search?type=Repositories&amp;q=rails">plugins</a>, <a title="Gems en Github" href="http://github.com/search?type=Repositories&amp;q=gem">gems</a>, <a title="Guias de Ruby on Rails oficiales" href="http://guides.rubyonrails.org/">tutoriales</a>, <a title="RailsTips por John Nunemaker" href="http://railstips.org/">trucos</a>, <a title="Railscasts por Ryan Bates" href="http://railscasts.com/">screencasts</a>, &#8230;&#8221;</p></blockquote>
<p>Por supuesto es muchas cosas más, pero lo fundamental está dicho. Recomiendo leer las guias oficiales de Ruby on Rails, empezando por <a title="Getting Started with Ruby on Rails Guide" href="http://guides.rubyonrails.org/getting_started.html">Getting Started with Rails</a> para más detalles sobre qué es Ruby on Rails.</p>
<p>Y para acabar, una <em>demo</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rails blog
<span style="color: #7a0874; font-weight: bold;">cd</span> blog
script<span style="color: #000000; font-weight: bold;">/</span>generate scaffold Post titulo:string contenido:text
rake db:migrate
script<span style="color: #000000; font-weight: bold;">/</span>server</pre></div></div>

<p>Si habías <a title="Instalando Ruby on Rails" href="http://jrom.net/instalando-ruby-on-rails">instalado correctamente</a> Ruby y Rails, ahora simplemente abre un navegador y ve a <a href="http://0.0.0.0:3000/posts">http://0.0.0.0:3000/posts</a>. Una aplicación web (muy sencilla) sin escribir ni una línea de código. A partir de aquí se puede ir haciendo retoques a los ficheros generados por el comando <code>rails</code> hasta tener un Wordpress-killer en Rails. Cuando lo tengas, avísame.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/hXWxtNrXZLw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/la-verdadera-definicion-de-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://jrom.net/la-verdadera-definicion-de-ruby-on-rails</feedburner:origLink></item>
		<item>
		<title>Miedo al FTP</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/Bqe7RxPck9w/miedo-al-ftp</link>
		<comments>http://jrom.net/miedo-al-ftp#comments</comments>
		<pubDate>Sun, 15 Mar 2009 23:44:56 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=50</guid>
		<description><![CDATA[Inexplicablemente el FTP no desapareció junto a TELNET en calidad de protocolo absolutamente inseguro.
Sin entrar a explicar cómo funcionan este tipo de protocolos, FTP lo que hace es establecer una conexión TCP con el servidor y mandarle mensajes del tipo:

USER pepito
331 Please identify yourself in a password.
&#160;
PASS juanito
230 Thanks.
&#160;
...
&#160;
RETR /pub/report
150 I see that file.

Lo que [...]]]></description>
			<content:encoded><![CDATA[<p>Inexplicablemente el <a title="FTP" href="http://es.wikipedia.org/wiki/File_Transfer_Protocol">FTP</a> no desapareció junto a <a title="Telnet" href="http://es.wikipedia.org/wiki/Telnet">TELNET</a> en calidad de protocolo absolutamente inseguro.</p>
<p>Sin entrar a explicar cómo funcionan este tipo de protocolos, FTP lo que hace es establecer una conexión TCP con el servidor y mandarle mensajes del tipo:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">USER pepito
331 Please identify yourself in a password.
&nbsp;
PASS juanito
230 Thanks.
&nbsp;
...
&nbsp;
RETR /pub/report
150 I see that file.</pre></div></div>

<p>Lo que la mayoría de usuarios de FTP no saben es que estos mensajes viajan <em>tal cual</em> por la red! Cualquier persona que esté monitoreando la red en la que está conectado el usuario, o cualquier router administrado por alguien con mala baba puede implicar que estés gritando a los cuatro vientos: <code>PASS juanito</code></p>
<p>Supongo que es muy evidente que es una limitación absolutamente inaceptable teniendo en cuenta que muchas veces necesitamos acceder para subir/bajar ficheros privados en servidores remotos.</p>
<p>La solución al problema, desgraciadamente, depende de lo simpático (o bueno) que sea el proveedor que administra el servidor al que queremos acceder y los protocolos que nos proporcione. Podemos usar <a title="FTP sobre SSL" href="http://es.wikipedia.org/wiki/FTPS">FTPS</a>, o FTP sobre SSL. Su nombre lo dice todo, funciona normalmente igual que FTP pero cifrando los datos de la comunicación. Alternativamente podemos enviar y recibir ficheros a un servidor mediante <a title="SFTP" href="http://es.wikipedia.org/wiki/Sftp">SFTP</a>, siglas de Secure File Transfer Protocol, y que en definitiva significa: Transferencia de ficheros vía <a href="http://es.wikipedia.org/wiki/Ssh">SSH</a>. Éste es mi método favorito, ya que se usa únicamente el puerto SSH para acceder a la máquina y para subir y bajar ficheros, y evidentemente toda la comunicación viaja encriptada con pares de claves pública/privada.</p>
<p>Mi consejo: evitad el uso de FTP siempre que sea posible, y absolutamente dejad de usarlo cuando se trate de acceder a sistemas donde la seguridad sea mínimamente importante. La mayoría de clientes FTP decentes también soportan FTPS y SFTP. Para el que tenga curiosidad en las tecnologías comentadas, recomiendo visitar los enlaces del texto (todos van a la Wikipedia) y en el caso de FTP, añado <a title="FTP" href="http://cr.yp.to/ftp.html">esta página</a>.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/Bqe7RxPck9w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/miedo-al-ftp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jrom.net/miedo-al-ftp</feedburner:origLink></item>
		<item>
		<title>No más bash scripts</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/wrs0e3vKkrU/no-mas-bash-scripts</link>
		<comments>http://jrom.net/no-mas-bash-scripts#comments</comments>
		<pubDate>Sun, 15 Mar 2009 17:23:10 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=61</guid>
		<description><![CDATA[El otro día estuve perdiendo casi una hora con un bash script para hacer copias de seguridad. De repente, vi que podía hacer un script Ruby en la mitad del líneas. Así lo hice, de hecho pasé de 60 a 13 líneas de código. Y nunca abuso de la notación de Ruby para compactar el código, en aras [...]]]></description>
			<content:encoded><![CDATA[<p>El otro día estuve perdiendo casi una hora con un bash script para hacer copias de seguridad. De repente, vi que podía hacer un script Ruby en la mitad del líneas. Así lo hice, de hecho pasé de 60 a 13 líneas de código. Y nunca abuso de la notación de Ruby para compactar el código, en aras de la legibilidad. A pesar del pequeño coste en rendimiento, el desgaste se divide casi por infinito al escribir un pequeño programa en ruby.</p>
<p>Sólo voy a usar bash script para algún alias o para ejecutar 3 o 4 instrucciones en un comando. Se ha acabado <em>programar</em> en bash script.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/wrs0e3vKkrU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/no-mas-bash-scripts/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jrom.net/no-mas-bash-scripts</feedburner:origLink></item>
		<item>
		<title>El mejor teclado del mundo</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/mtm7Xlw0c9c/el-mejor-teclado-del-mundo</link>
		<comments>http://jrom.net/el-mejor-teclado-del-mundo#comments</comments>
		<pubDate>Sun, 16 Nov 2008 18:48:38 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=12</guid>
		<description><![CDATA[Curiosamente, la parte de mi ordenador/ entorno de trabajo que más me costó encontrar fue el teclado. Ahora mismo estoy usando un Power Mac G5 con un monitor Dell de 20&#8243; (mejorable), un ratón Logitech Cordless Click! óptico, el teclado del que ahora hablaré y algunos periféricos más. Todos estos elementos han sido elegidos simplemente observando los [...]]]></description>
			<content:encoded><![CDATA[<p>Curiosamente, la parte de mi ordenador/ entorno de trabajo que más me costó encontrar fue el teclado. Ahora mismo estoy usando un <a title="Power Mac G5" href="http://en.wikipedia.org/wiki/Power_Macintosh_G5">Power Mac G5</a> con un <a title="Monitor Dell 2005FPW" href="http://support.euro.dell.com/support/edocs/monitors/2005FPW/Sp/about.htm">monitor Dell</a> de 20&#8243; (mejorable), un ratón <a href="http://www.amazon.com/gp/product/B0002H0CA4?ie=UTF8&amp;tag=jordrome-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B0002H0CA4">Logitech Cordless Click!</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=jordrome-20&amp;l=as2&amp;o=1&amp;a=B0002H0CA4" border="0" alt="" width="1" height="1" /> óptico, el teclado del que ahora hablaré y algunos periféricos más. Todos estos elementos han sido elegidos simplemente observando los productos que ofrece el mercado, y escogiendo el mejor (o el que mejor se adaptaba a mis necesidades) al precio que pudiera soportar. Respecto al ordenador, entran muchos factores en la decisión, y nos saldríamos del tema. En el caso del monitor, simplemente necesitaba el máximo espacio que me pudiera pagar, y la opción de Dell era de lejos la mejor. El ratón se ha acabado consolidando a base de descartes. Después de descartar el mighty mouse de Apple (frágil, no se adapta perfectamente a la mano, y hay que levantar el dedo izquierdo para hacer click derecho), un ratón fantástico de microsoft (demasiado ancho y el tacto con la alfombrilla era simplemente desagradable), y algún otro ratón que he ido probando, ha acabado sobreviviendo el ratón que me regalaron con un portátil hace 5 años.</p>
<p>Todo resuelto, excepto el teclado. Con mi antiguo PC Dell, usaba un teclado Acer (aunque luego también vi el mismo teclado marca BenQ) mecánico. Funcionaba bastante bien, aunque quizá las teclas hacían demasiado ruido, y era PS/2. Además, el tacto no era perfecto.</p>
<p><img class="size-full wp-image-19 alignnone" title="teclado-benq" src="http://jrom.net/wp-content/uploads/2008/11/teclado-benq.jpg" alt="Teclado BenQ" width="500" height="119" /></p>
<p>Después probé el teclado blanco de Apple, que tampoco cumplió su requisito: ser cómodo y agradable al tacto. Las teclas se atascan si no se presionan perfectamente perpendiculares, y eso frena la velocidad de escritura forzando errores de vez en cuando. A los detalles prácticos, se le suma que se ensucia y pierde glamour con el tiempo. Ni siquiera es mecánico.</p>
<p><img class="alignnone size-full wp-image-22" title="teclado-apple" src="http://jrom.net/wp-content/uploads/2008/11/teclado-apple.jpg" alt="" width="500" height="133" /></p>
<p>Pero, que alternativas hay? Pues la respuesta la encontré de viaje por Japón. Curioseando en la mejor tienda de aparatos electrónicos que he visto jamás: <a title="Yodobashi Camera, tienda de aparatos electrónicos de Japón" href="http://www.yodobashi.com/">Yodobashi Camera</a>. Allí, en un pasillo sin fin lleno de teclados, fui probando, buscando a ver si en uno de los centros neurálgicos de la tecnología: el barrio de <a title="Akihabara en Kirainet" href="http://www.kirainet.com/akihabara/">Akihabara</a>, se encontraba un teclado mejor. Pues sin esperarlo, toqué el que hasta el momento ha sido el teclado más cómodo. Se trata del <strong>Happy Hacking Keyboard Professional 2</strong>. Es un teclado completamente mecánico, muy compacto, y alámbrico. Cuesta explicar con palabras porqué este teclado es infinitamente mejor que cualquier Logitech Dinovo para altos directivos pretenciosos. Simplemente, cada tecla tiene el muelle perfecto, el peso y el rebote ideal, y un tacto inmejorable. En la página oficial, te lo explican en japonés: <a title="Happy Hacking Keyboard Professional 2" href="http://www.pfu.fujitsu.com/hhkeyboard/hhkbpro2/feature.html">HHK Professional 2</a>.</p>
<p><img class="alignnone size-full wp-image-34" title="Teclado Happy Hacking Keyboard Professional 2" src="http://jrom.net/wp-content/uploads/2008/11/teclado-hhkp2.jpg" alt="" width="500" height="287" /></p>
<p>La cuestión es que se trata del mejor teclado que pueda existir, excepto por los siguientes puntos:</p>
<ul>
<li>Por cuestiones misteriosas, <strong>no dispone de flechas</strong>, ni algunas otras teclas &#8220;extra&#8221; cómo si se tratara de un teclado de portátil (de aquí que lo describiera cómo teclado compacto).</li>
<li>No dispone de teclado numérico. No entiendo porqué un teclado compacto es mejor que uno completo.</li>
<li>No está disponible con un layout que no sea el inglés, por lo que preferí la opción sin imprimir, puesto que bastantes símbolos no se corresponderían con su representación en el ordenador.</li>
<li>Es demasiado caro. Me costó unos 120€ al cambio en yenes en verano de 2007. Lo he visto por 330€ en tiendas españolas.</li>
</ul>
<p>Tengo que advertir a los aventureros que lo busquen para comprárselo: usar un teclado sin imprimir resulta bastante fácil cuándo uno lleva muchos años usando ordenadores, pero usar un teclado sin imprimir y sin teclado numérico puede resultar una pesadilla si hay que trabajar mucho rato con números. Por este motivo llevo meses buscando un buen teclado numérico inalámbrico y que funcione con Mac. Si alguien lo encuentra, por favor, que me diga dónde!</p>
<p>Yo me lo compré en <a title="Happy Hacking Keyboard en Yodobashi Camera" href="http://www.yodobashi.com/ec/product/100000001000724459/index.html">Yodobashi Camera</a>, aunque también parece que lo venden en <a title="Happy Hacking Keyboard en Amazon Japan" href="http://www.amazon.co.jp/Happy-Hacking-Keyboard-Professional2-PD-KB400B/dp/B000EXZ0VC?tag=jordrome-20">Amazon Japan</a> y en <a title="Happy Hacking Keyboard en Geek Stuff 4 U" href="http://www.geekstuff4u.com/happy-hacking-keyboard-pro-2.html">Geek Stuff 4 U</a>.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/mtm7Xlw0c9c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/el-mejor-teclado-del-mundo/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://jrom.net/el-mejor-teclado-del-mundo</feedburner:origLink></item>
		<item>
		<title>Qué es REST</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/FkJii6x1lq0/que-es-rest</link>
		<comments>http://jrom.net/que-es-rest#comments</comments>
		<pubDate>Fri, 09 May 2008 17:58:13 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=13</guid>
		<description><![CDATA[REST (REpresentational State Transfer) es una arquitectura para aplicaciones que se comunican a través del protocolo HTTP.
Verbos HTTP
Típicamente, se conocen del protocolo HTTP dos verbos: GET y POST. GET es el que se utiliza para pedir un contenido a un servidor web. Por ejemplo: GET http://jrom.net/ nos mandará el contenido de la URL pedida. También [...]]]></description>
			<content:encoded><![CDATA[<p><strong>REST</strong> (REpresentational State Transfer) es una arquitectura para aplicaciones que se comunican a través del protocolo HTTP.</p>
<h2>Verbos HTTP</h2>
<p>Típicamente, se conocen del protocolo HTTP dos verbos: GET y POST. GET es el que se utiliza para pedir un contenido a un servidor web. Por ejemplo: <code>GET http://jrom.net/</code> nos mandará el contenido de la URL pedida. También podemos añadir parámetros usando el verbo GET: <code>GET http://jrom.net/?s=rails</code>, en este caso, el servidor recibe que queremos la URL http://jrom.net/ pero con la variable s=rails.</p>
<p>El otro verbo conocido es POST. Normalmente se utiliza en los formularios mandan datos al servidor.</p>
<p>Sin embargo, hay más verbos HTTP que normalmente no se usan. Para poder usar una arquitectura REST, necesitaremos usar (además de GET y POST) los verbos PUT y DELETE. Estos ni siquiera son soportados por los navegadores corrientes, por lo que hay que simular que usamos esos verbos al hacer un enlace para un navegador, aunque sí que puede usar cuándo se nos use como webservice.</p>
<h2>REST &#8211; CRUD</h2>
<p>REST se puede ver cómo un sistema CRUD (Crear, leer, actualizar y eliminar) proyectado al protocolo HTTP. Podemos usar un verbo HTTP por cada acción CRUD:</p>
<ul>
<li><strong>GET</strong>: Read, mostrar un objeto</li>
<li><strong>DELETE</strong>: Delete, eliminar un objeto</li>
<li><strong>PUT</strong>: Update, actualizar un objeto</li>
<li><strong>POST</strong>: Create, crear un objeto</li>
</ul>
<div>De esta forma, si queremos hacer una de las acciones CRUD sobre el objeto &#8220;proyecto&#8221; que lo identificamos por un ID=428, podríamos entender las siguientes ordenes HTTP:</div>
<div>
<ul>
<li><code>GET http://localhost/proyectos/428</code> → Obtiene el proyecto 428</li>
<li><code>DELETE http://localhost/proyectos/428</code> → Elimina el proyecto 428</li>
<li><code>PUT http://localhost/proyectos/428</code> → Modifica el proyecto 428</li>
<li><code>POST http://localhost/proyectos</code> → Crea un proyecto con ID 428 (no podemos pasar el ID porque esto nos lo devolverá el servidor después de crear el proyecto)</li>
</ul>
<h2>El dilema</h2>
<div>Hasta aquí, parece que REST es una solución muy limpia para manejar recursos en aplicaciones web: obtenemos unas URL limpias y orientadas a CRUD, nos van muy bien para programar nuestra aplicación web como webservice y es muy sencillo de comprender y intuir cómo funciona una aplicación web.</div>
<div>El problema que tiene REST es que los navegadores corrientes no soportan los verbos DELETE y PUT. Por este motivo, mucha gente descarta plantearse usar diseños REST para aplicaciones web, ya que sólo sirven al ofrecerse como webservice, y no como aplicación de cara al usuario a través de un navegador web.</div>
<h2>La conclusión</h2>
<div>Se puede usar un diseño REST sólo para webservices, dónde puedes manejar sin problemas los cuatro verbos HTTP. Otra opción, la que por ejemplo eligieron los diseñadores de Ruby on Rails al implementar REST en el manejo de recursos, es simular la funcionalidad REST a través de sólo GET y POST, pudiendo aceptar llamadas PUT y DELETE cuándo el cliente lo soporte. En el caso de RAILS, añaden una variable POST llamada <code>_method</code>, a la que le dan valor put o delete para simular llamadas PUT y DELETE del cliente.</div>
</div>
<img src="http://feeds.feedburner.com/~r/JROM/~4/FkJii6x1lq0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/que-es-rest/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://jrom.net/que-es-rest</feedburner:origLink></item>
		<item>
		<title>Instalando Ruby on Rails</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/9FEis8ZLbts/instalando-ruby-on-rails</link>
		<comments>http://jrom.net/instalando-ruby-on-rails#comments</comments>
		<pubDate>Fri, 02 May 2008 00:04:17 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=12</guid>
		<description><![CDATA[Antes que nada, necesitas tener Ruby en el sistema: En Linux y Windows, sigue los pasos que cuentan en la página oficial de Ruby. En Mac OS X Tiger, sigue las instrucciones que da Dan Benjamin en Hivelogic. En Mac OS X Leopard, no hace falta hacer nada, viene con una instalación de serie de [...]]]></description>
			<content:encoded><![CDATA[<p>Antes que nada, necesitas tener Ruby en el sistema: En Linux y Windows, sigue los pasos que cuentan en la <a title="Instalando Ruby" href="http://www.ruby-lang.org/es/downloads/" target="_blank">página oficial de Ruby</a>. En Mac OS X Tiger, sigue las instrucciones que da Dan Benjamin en <a title="Instalar Ruby en Tiger" href="http://hivelogic.com/articles/2007/02/ruby-rails-mongrel-mysql-osx" target="_blank">Hivelogic</a>. En Mac OS X Leopard, no hace falta hacer nada, viene con una instalación de serie de Ruby y Ruby on Rails.  También necesitarás las RubyGems, que puedes encontrar <a title="Instalando RubyGems" href="http://rubyforge.org/frs/?group_id=126" target="_blank">aquí</a>.  Para comprobar que realmente tienes Ruby y RubyGems funcionando, escribe esto en la línea de comandos:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ ruby -v     
&nbsp;
ruby 1.8.6 <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2007</span>-09-<span style="color: #000000;">24</span> patchlevel <span style="color: #000000;">111</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>universal-darwin9.0<span style="color: #7a0874; font-weight: bold;">&#93;</span>
&nbsp;
$ gem <span style="color: #660033;">-v</span>
&nbsp;
1.1.1
&nbsp;
$</pre></div></div>

<p>Ahora, sólo hace falta escribir</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ gem <span style="color: #c20cb9; font-weight: bold;">install</span> rails <span style="color: #660033;">--include-dependencies</span></pre></div></div>

<p>Y tendremos Rails instalado. Vamos a crear nuestra primera aplicación Rails:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ rails hello_world_rails
      create
      create  app<span style="color: #000000; font-weight: bold;">/</span>controllers
      create  app<span style="color: #000000; font-weight: bold;">/</span>helpers
      create  app<span style="color: #000000; font-weight: bold;">/</span>models
      create  app<span style="color: #000000; font-weight: bold;">/</span>views<span style="color: #000000; font-weight: bold;">/</span>layouts
      create  config<span style="color: #000000; font-weight: bold;">/</span>environments
      <span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
      create  log<span style="color: #000000; font-weight: bold;">/</span>server.log
      create  log<span style="color: #000000; font-weight: bold;">/</span>production.log
      create  log<span style="color: #000000; font-weight: bold;">/</span>development.log
      create  log<span style="color: #000000; font-weight: bold;">/</span>test.log
$ <span style="color: #7a0874; font-weight: bold;">cd</span> hello_world_rails<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>El comando <code>rails &lt;nombreaplicacion&gt;</code> en realidad lo único que hace es crear un directorio de nombre &#8220;nombreaplicacion&#8221; y llenarlo con el esqueleto de una aplicación Rails:</p>
<ul>
<li><strong>app</strong>: El directorio donde mas lineas escribiremos, ahí es dónde va el código de nuestra aplicación.</li>
<li><strong>config</strong>: Se configura la base de datos, las rutas y parámetros para cada entorno de ejecución (development, test y production)</li>
<li><strong>db</strong>: Es donde tendremos los ficheros de migraciones de la base de datos, y si usas sqlite, también tendrás la base de datos ahí.</li>
<li><strong>doc</strong>: Por defecto está vacío, pero puedes generar ahí la API de Rails, o la API de tu propia aplicación con el comando rake.</li>
<li><strong>lib</strong>: Código Ruby que queramos tener accesible desde cualquier código de nuestra aplicación</li>
<li><strong>log</strong>: &#8230;</li>
<li><strong>public</strong>: Directorio que el servidor web servirá, es dónde se encuentra el dispatcher, y el contenido estático (css, imágenes, js, &#8230;)</li>
<li><strong>script</strong>: Código de Rails con los scripts que usaremos constantemente para generar más código</li>
<li><strong>test</strong>: Directorio dónde colocaremos el código de nuestros tests para probar la aplicación</li>
<li><strong>tmp</strong>: &#8230;</li>
<li><strong>vendor</strong>: Inicialmente vacío, pero ahí es dónde irán a parar los plugins que instalemos, y si queremos, podemos incrustar todo el código de rails para no tener que depender de la versión de rails que haya en nuestra máquina, e incluso, hacerle modificaciones</li>
</ul>
<p>Ahora vamos a poner en marcha unos instantes esta nueva aplicación dónde aún no hemos escrito ni una línea de código:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ script<span style="color: #000000; font-weight: bold;">/</span>server
=<span style="color: #000000; font-weight: bold;">&amp;</span>gt; Booting Mongrel <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">'script/server webrick'</span> to force WEBrick<span style="color: #7a0874; font-weight: bold;">&#41;</span>
=<span style="color: #000000; font-weight: bold;">&amp;</span>gt; Rails application starting on http:<span style="color: #000000; font-weight: bold;">//</span>0.0.0.0:<span style="color: #000000;">3000</span>
=<span style="color: #000000; font-weight: bold;">&amp;</span>gt; Call with <span style="color: #660033;">-d</span> to detach
=<span style="color: #000000; font-weight: bold;">&amp;</span>gt; Ctrl-C to shutdown server
<span style="color: #000000; font-weight: bold;">**</span> Starting Mongrel listening at 0.0.0.0:<span style="color: #000000;">3000</span>
<span style="color: #000000; font-weight: bold;">**</span> Starting Rails with development environment...
<span style="color: #000000; font-weight: bold;">**</span> Rails loaded.
<span style="color: #000000; font-weight: bold;">**</span> Loading any Rails specific GemPlugins
<span style="color: #000000; font-weight: bold;">**</span> Signals ready.  TERM =<span style="color: #000000; font-weight: bold;">&amp;</span>gt; stop.  USR2 =<span style="color: #000000; font-weight: bold;">&amp;</span>gt; restart.  INT =<span style="color: #000000; font-weight: bold;">&amp;</span>gt; stop <span style="color: #7a0874; font-weight: bold;">&#40;</span>no restart<span style="color: #7a0874; font-weight: bold;">&#41;</span>.
<span style="color: #000000; font-weight: bold;">**</span> Rails signals registered.  HUP =<span style="color: #000000; font-weight: bold;">&amp;</span>gt; reload <span style="color: #7a0874; font-weight: bold;">&#40;</span>without restart<span style="color: #7a0874; font-weight: bold;">&#41;</span>.  It might not work well.
<span style="color: #000000; font-weight: bold;">**</span> Mongrel 1.1.4 available at 0.0.0.0:<span style="color: #000000;">3000</span>
<span style="color: #000000; font-weight: bold;">**</span> Use CTRL-C to stop.</pre></div></div>

<p>En nuestro navegador favorito, ponemos <a href="http://0.0.0.0:3000" target="_blank">http://0.0.0.0:3000</a> y veremos una página de bienvenida que nos da pistas sobre nuestros siguientes pasos. Ya podemos cerrar el servidor (Control-C), y ponernos manos a la obra.<br />
Por defecto, Rails supone que vamos a usar una base de datos sqlite, si queremos forzarlo a usar otra opción (por ejemplo: mysql), tenemos que ejecutar el comando <code>rails &lt;aplicación&gt; -d mysql</code>.<br />
En este articulo sólo pretendo mostrar cómo se pone en marcha una aplicación rails, pero sólo como aperitivo, podemos probar lo siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ script<span style="color: #000000; font-weight: bold;">/</span>generate scaffold Producto nombre:string descripcion:text precio:integer 
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
&nbsp;
$ rake db:migrate
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jordi<span style="color: #000000; font-weight: bold;">/</span>rails<span style="color: #000000; font-weight: bold;">/</span>hello_world_rails<span style="color: #7a0874; font-weight: bold;">&#41;</span>
== <span style="color: #000000;">1</span> CreateProductos: migrating ===============================================
<span style="color: #660033;">--</span> create_table<span style="color: #7a0874; font-weight: bold;">&#40;</span>:productos<span style="color: #7a0874; font-weight: bold;">&#41;</span>
   -<span style="color: #000000; font-weight: bold;">&amp;</span>gt; 0.0038s
== <span style="color: #000000;">1</span> CreateProductos: migrated <span style="color: #7a0874; font-weight: bold;">&#40;</span>0.0040s<span style="color: #7a0874; font-weight: bold;">&#41;</span> ======================================
&nbsp;
$ script<span style="color: #000000; font-weight: bold;">/</span>server
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>Y vamos a <a href="http://0.0.0.0:3000/productos" target="_blank">http://0.0.0.0:3000/productos</a>. Con sólo escribir un comando, hemos generado un <strong>controlador</strong> (Productos), un <strong>modelo</strong> (Producto) y unas <strong>vistas</strong> (páginas html) para manipular productos. Podemos crear, mostrar, editar, borrar y listar productos sin tener que escribir ni una sola línea de Ruby. Con el segundo comando hemos generado la tabla en la base de datos (sqlite, configurada en config/databse.yml) productos, con los campos nombre, descripción y precio.<br />
Hasta aquí la instalación de Rails, a partir de aquí hace falta saber un poco de Ruby y empezar a programar aplicaciones realmente útiles.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/9FEis8ZLbts" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/instalando-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jrom.net/instalando-ruby-on-rails</feedburner:origLink></item>
		<item>
		<title>Introducción al control de versiones</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/D6Ckfm5FIls/introduccion-control-de-versiones</link>
		<comments>http://jrom.net/introduccion-control-de-versiones#comments</comments>
		<pubDate>Thu, 17 Apr 2008 15:38:35 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=11</guid>
		<description><![CDATA[El problema
Casi cualquier proyecto de software, por pequeño que sea, requiere la intervención de más de un desarrollador. Todos los que hayamos participado en un proyecto dónde más de una persona colabora en un mismo código, nos hemos encontrado con los mismos problemas: ¿Quién tiene la versión buena? ¿Sobre qué código debo aplicar este cambio? [...]]]></description>
			<content:encoded><![CDATA[<h2>El problema</h2>
<p>Casi cualquier proyecto de software, por pequeño que sea, requiere la intervención de más de un desarrollador. Todos los que hayamos participado en un proyecto dónde más de una persona colabora en un mismo código, nos hemos encontrado con los mismos problemas: ¿Quién tiene la versión buena? ¿Sobre qué código debo aplicar este cambio? ¿Has hecho cambios esta semana en el fichero tal?</p>
<h2>La solución: Control de versiones</h2>
<p>Se trata de tener una herramienta que gestione todos los cambios que sufre un determinado archivo por un determinado usuario. A eso lo llamamos <strong>Control de versiones</strong>. Hay una copia en un servidor que es dónde todos los desarrolladores deben acudir para empezar a trabajar (el <strong>repositorio</strong>). Entonces, el desarrollador parte de esa versión, hace los cambios que tiene que hacer, y sube sus cambios al servidor. Ha creado una nueva versión de los documentos que ha modificado (una <strong>revisión</strong>). Si otro desarrollador quiere trabajar en ese mismo fichero, observará que alguien ha efectuado cambios antes que él, y si ya tenia una revisión del código, se bajará los cambios hechos por su compañero para actualizar su versión local (la <strong>copia de trabajo</strong>).</p>
<h2>Ventajas de usar un sistema de control de versiones</h2>
<p>Usar un sistema de control de versiones nos proporciona muchas ventajas:</p>
<ul>
<li>Poder en todo momento ver cuál es la versión más actual del proyecto, quien y cuándo la ha subido.</li>
<li> Comparar cualquier par de versiones, dónde vemos todas las partes añadidas, modificadas o eliminadas de los ficheros entre las dos versiones.</li>
<li>Volver atrás en el tiempo a una versión que funcionaba, si los cambios que hemos hecho no nos han llevado por el buen camino.</li>
<li>Crear distintas ramas del proyecto, para que sigan caminos separados a partir de un punto.</li>
<li>Etiquetar distintas revisiones que representan una versión oficial del proyecto (para indicar que la revisión 4283 coincide con la versión del proyecto 2.4.0, la etiquetaremos por ejemplo: 2_4_0).</li>
</ul>
<h2>Sistemas de control de versiones populares</h2>
<ul>
<li>CVS: Concurrent Versions System es el que ha sido mas popular hasta que ha sido rápidamente sustituido por el siguiente</li>
<li>SVN: Subversion, diseñado para reemplazar el CVS, mejorando casi todas las características de CVS y añadiendo funcionalidades que el antiguo no tenia.</li>
<li>Git: Un proyecto de Linus Torvalds, en auge y del que voy a hablar cuando tega un momentito.</li>
</ul>
<p>En posteriores artículos hablaré de las características de Subversion, cómo se crea un repositorio, cómo se trabaja en un proyecto con Subversion, etc&#8230;</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/D6Ckfm5FIls" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/introduccion-control-de-versiones/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jrom.net/introduccion-control-de-versiones</feedburner:origLink></item>
		<item>
		<title>Introducción a Ruby on Rails</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/RazEiF4ABEk/introduccion-ruby-on-rails</link>
		<comments>http://jrom.net/introduccion-ruby-on-rails#comments</comments>
		<pubDate>Tue, 15 Apr 2008 20:07:25 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=10</guid>
		<description><![CDATA[¿Qué es Ruby on Rails?
Ruby on Rails es un framework para desarrollar aplicaciones web que usan bases de datos. Esa seria la definición estricta que aparece en la web oficial de Ruby on Rails.
Yo definiría RoR cómo la solución a los problemas de casi cualquier desarrollador de aplicaciones web. RoR permite construir tu aplicación web [...]]]></description>
			<content:encoded><![CDATA[<h2>¿Qué es Ruby on Rails?</h2>
<p>Ruby on Rails es un framework para desarrollar aplicaciones web que usan bases de datos. Esa seria la definición estricta que aparece en la <a title="Web oficial de Ruby on Rails" href="http://www.rubyonrails.org/" target="_blank">web oficial</a> de Ruby on Rails.</p>
<p>Yo definiría RoR cómo la solución a los problemas de <em>casi</em> cualquier desarrollador de aplicaciones web. RoR permite construir tu aplicación web consumiendo el 98% de tu esfuerzo en la propia aplicación, dejando que el resto simplemente funcione.</p>
<p>Ruby on rails es una herramienta creada <strong>por</strong> desarrolladores de aplicaciones web <strong>para</strong> desarrolladores de aplicaciones web. Y además es Open Source!</p>
<h2>Rails vs el resto</h2>
<p>Rails ofrece una arquitectura MVC (Modelo-Vista-Controlador), que nos separa el código de la interfície (Vista), la lógica de control (Controlador) y los datos (Modelo).</p>
<p>También destaca una potente herramienta de generación de código &#8220;por defecto&#8221;: el scaffolding. Gracias al scaffolding podemos crear un código básico para un recurso (por ejemplo: posts, personas, facturas, paginas, &#8230;) que nos permite crear, editar, mostrar y borrar instancias de ese recurso sin tener que escribir ni una sola línea de ruby. Partiendo de ese código crearemos el resto de nuestra aplicación.</p>
<p>En definitiva, la gran distinción de Ruby on Rails es que nos permite crear aplicaciones web en muy poco tiempo, con un código muy limpio, modular, reutilizable y con facilidades para escalar.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/RazEiF4ABEk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/introduccion-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jrom.net/introduccion-ruby-on-rails</feedburner:origLink></item>
		<item>
		<title>Hello world!</title>
		<link>http://feedproxy.google.com/~r/JROM/~3/v1eUk0vYi18/hello-world</link>
		<comments>http://jrom.net/hello-world#comments</comments>
		<pubDate>Mon, 14 Apr 2008 21:00:37 +0000</pubDate>
		<dc:creator>Jordi Romero</dc:creator>
				<category><![CDATA[Artículos]]></category>

		<guid isPermaLink="false">http://jrom.net/?p=1</guid>
		<description><![CDATA[Hello world! creado automáticamente por Wordpress. Cuándo esté el blog listo ya pondré un post de bienvenida un poco más serio.
]]></description>
			<content:encoded><![CDATA[<p>Hello world! creado automáticamente por Wordpress. Cuándo esté el blog listo ya pondré un post de bienvenida un poco más serio.</p>
<img src="http://feeds.feedburner.com/~r/JROM/~4/v1eUk0vYi18" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jrom.net/hello-world/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://jrom.net/hello-world</feedburner:origLink></item>
	</channel>
</rss>
