<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Daniel Calderón</title>
	
	<link>http://danielcalderon.net</link>
	<description>desarrollo web · diseño de interacción · metodologías ágiles</description>
	<lastBuildDate>Mon, 28 Nov 2011 20:01:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/danielcalderon" /><feedburner:info uri="danielcalderon" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><item>
		<title>‘border-radius’ mixins de andar por casa</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/KNN9yycgh1c/</link>
		<comments>http://danielcalderon.net/desarrollo-web/css/border-radius-mixins-de-andar-por-casa/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 19:45:44 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[border-radius]]></category>
		<category><![CDATA[compass]]></category>
		<category><![CDATA[mixins]]></category>
		<category><![CDATA[scss]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=234</guid>
		<description><![CDATA[Últimamente estoy dándole algo de caña a Compass y usándolo en algún que otro proyecto. Es un framework CSS increíble, con muchas herramientas para hacernos la vida más fácil a los fronteneros (o al menos a intentarlo). Entre muchas de estas herramientas está el módulo CSS3, que proporciona mixins para propiedades CSS3 como por ejemplo [...]]]></description>
			<content:encoded><![CDATA[<p>Últimamente estoy dándole algo de caña a <a href="http://compass-style.org/reference/compass/" onclick="pageTracker._trackPageview('/outgoing/compass-style.org/reference/compass/?referer=');">Compass</a> y usándolo en algún que otro proyecto. Es un framework CSS increíble, con muchas herramientas para hacernos la vida más fácil a los fronteneros (o al menos a intentarlo). Entre muchas de estas herramientas está el módulo CSS3, que proporciona mixins para propiedades CSS3 como por ejemplo border-radius. Os animo a darle una oportunidad a este fantástico framework, nos os decepcionará.</p>
<p>En cualquier caso, si no os da por probar Compass, pero usáis <a href="http://sass-lang.com" onclick="pageTracker._trackPageview('/outgoing/sass-lang.com?referer=');">SCSS</a> y estáis hartos de repetiros como loros en vuestro código (<a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Don_t_repeat_yourself?referer=');">DRY!</a>) estáis tardando en utilizar mixins y variables para solucionarlo. Aquí os dejo un &#8216;mixin casero&#8217; para la propiedad border-radius, que no es (pero casi) como los de Compass, pero dan el apaño. Enjoy it!</p>
<p><script src="https://gist.github.com/1401658.js"></script></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=KNN9yycgh1c:aJO_8jDFgp4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=KNN9yycgh1c:aJO_8jDFgp4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=KNN9yycgh1c:aJO_8jDFgp4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=KNN9yycgh1c:aJO_8jDFgp4:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/KNN9yycgh1c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/css/border-radius-mixins-de-andar-por-casa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/css/border-radius-mixins-de-andar-por-casa/</feedburner:origLink></item>
		<item>
		<title>Desactivar Spotlight</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/ap7ZI_F2zzI/</link>
		<comments>http://danielcalderon.net/general/desactivar-spotlight/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 06:59:09 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[lion]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[spotlight]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=231</guid>
		<description><![CDATA[Fácil y rápido. Para desactivar la indexación, en consola haremos: Si por cualquier motivo queremos volver a reactivarlo y además limpiar la indexación anterior:]]></description>
			<content:encoded><![CDATA[<p>Fácil y rápido. Para desactivar la indexación, en consola haremos:</p>
<pre class="brush: bash; title: ; notranslate">
sudo mdutil -i off
</pre>
<p>Si por cualquier motivo queremos volver a reactivarlo y además limpiar la indexación anterior:</p>
<pre class="brush: bash; title: ; notranslate">
sudo mdutil -i on / &amp;&amp; sudo mdutil -E /
</pre>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=ap7ZI_F2zzI:tl36jWhC22Q:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=ap7ZI_F2zzI:tl36jWhC22Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=ap7ZI_F2zzI:tl36jWhC22Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=ap7ZI_F2zzI:tl36jWhC22Q:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/ap7ZI_F2zzI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/general/desactivar-spotlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/general/desactivar-spotlight/</feedburner:origLink></item>
		<item>
		<title>validates uniqueness y Shoulda</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/HQ6VZp6ug1E/</link>
		<comments>http://danielcalderon.net/desarrollo-web/ruby-on-rails/validates-uniqueness-y-shoulda/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 09:17:20 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[factory girl]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[shoulda]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[uniqueness]]></category>
		<category><![CDATA[validates_uniqueness_of]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=225</guid>
		<description><![CDATA[Generalmente utilizo Factory Girl y Shoulda para testear aplicaciones rails. El primero os lo recomiendo y sobre Shoulda, aunque siempre me da algún que otro dolor de cabeza, también me da muchas satisfacciones. Hoy me encontraba en la tesitura de testear que un atributo tuviera un valor único. Si incluimos el test correspondiente con shoulda [...]]]></description>
			<content:encoded><![CDATA[<p>Generalmente utilizo <a href="http://github.com/thoughtbot/factory_girl/" onclick="pageTracker._trackPageview('/outgoing/github.com/thoughtbot/factory_girl/?referer=');">Factory Girl</a> y <a href="http://github.com/thoughtbot/shoulda" onclick="pageTracker._trackPageview('/outgoing/github.com/thoughtbot/shoulda?referer=');">Shoulda</a> para testear aplicaciones rails. El primero os lo recomiendo y sobre Shoulda, aunque siempre me da algún que otro dolor de cabeza, también me da muchas satisfacciones.</p>
<p>Hoy me encontraba en la tesitura de testear que un atributo tuviera un valor único.</p>
<pre class="brush: ruby; title: ; notranslate">
class Example &lt; ActiveRecord::Base
  validates :name, :uniqueness =&gt; true
end
</pre>
<p>Si incluimos el test correspondiente con shoulda nos da un error del tipo <strong>should require case sensitive unique value for</strong> &#8230; Para solucionarlo basta con incluir la primera línea que podéis leer en el test:</p>
<pre class="brush: ruby; title: ; notranslate">
class ExampleTest &lt; ActiveSupport::TestCase
  subject { Factory(:example) }
  should validate_uniqueness_of(:name)
end
</pre>
<p><code>should validate_uniqueness_of</code> necesita tener un registro creado y con <code>subject</code> conseguimos tal objetivo. Podéis obtener más información sobre subject, que es bastante interesante, en la <a href="http://rubydoc.info/gems/shoulda/2.10.3/Shoulda/InstanceMethods" onclick="pageTracker._trackPageview('/outgoing/rubydoc.info/gems/shoulda/2.10.3/Shoulda/InstanceMethods?referer=');">documentación de Shoulda</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=HQ6VZp6ug1E:6T46FBz3lCA:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=HQ6VZp6ug1E:6T46FBz3lCA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=HQ6VZp6ug1E:6T46FBz3lCA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=HQ6VZp6ug1E:6T46FBz3lCA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/HQ6VZp6ug1E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/ruby-on-rails/validates-uniqueness-y-shoulda/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/ruby-on-rails/validates-uniqueness-y-shoulda/</feedburner:origLink></item>
		<item>
		<title>Comenzar un proyecto desde 0 con Ruby 1.9.2, Rails 3.1 y Mongodb</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/C-9B60dFLVo/</link>
		<comments>http://danielcalderon.net/desarrollo-web/ruby-on-rails/comenzar-proyecto-ruby-1-9-2-rails-3-1-mongodb-mongoid/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 10:26:02 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mongoid]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails 3.1]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=219</guid>
		<description><![CDATA[En lo último que ando metido en mis ratos libres es en aprender un poco sobre otros tipos de base de datos. Usualmente suelo trabajar con MySQL pero tenía ganas de probar una base de datos documental, en este caso, MondoDB. Para trastear MongoDB he empezado un proyectillo simple donde aplicar todo lo que vaya [...]]]></description>
			<content:encoded><![CDATA[<p>En lo último que ando metido en mis ratos libres es en aprender un poco sobre otros tipos de base de datos. Usualmente suelo trabajar con <strong>MySQL</strong> pero tenía ganas de probar una base de datos documental, en este caso, <a title="MongoDB" href="http://www.mongodb.org/" onclick="pageTracker._trackPageview('/outgoing/www.mongodb.org/?referer=');">MondoDB</a>.</p>
<p>Para trastear MongoDB he empezado un proyectillo simple donde aplicar todo lo que vaya aprendiendo. El proyecto será en <strong>Rails 3.1</strong> y utilizaré <a href="http://mongoid.org/" onclick="pageTracker._trackPageview('/outgoing/mongoid.org/?referer=');">Mongoid</a>, un ODM (Object-Document-Mapper) muy amigable para los que ya estamos acostumbrados a <strong>ActiveRecord</strong>. En este primer post os voy a contar los pasos que he seguido para poner en pie el entorno de trabajo:</p>
<p>Antes que nada, tendremos en cuenta que vamos a utilizar Ruby 1.9.2. Para trabajar con diferentes entornos de desarrollo Ruby utilizo <a href="http://beginrescueend.com/" onclick="pageTracker._trackPageview('/outgoing/beginrescueend.com/?referer=');">RVM</a>. Una vez tengas instalado Ruby 1.9.2, cambia a ese entorno de desarrollo con <code>rvm use 1.9.2</code>.</p>
<p>Ahora a instalar MongoDB:</p>
<pre class="brush: bash; title: ; notranslate">
brew update
brew install mongodb
</pre>
<p>Con la primera línea actualizamos las formulas de <a href="http://mxcl.github.com/homebrew/" onclick="pageTracker._trackPageview('/outgoing/mxcl.github.com/homebrew/?referer=');">homebrew</a>, el instalador de paquetes con el que trabajo. Si no lo conoces, dale una oportunidad, merece la pena. Una vez instalado mongodb, sigue los pasos que te vayan indicando y, para comprobar que todo ha ido correctamente, prueba a ejecutar <code>mongod</code> y acceder a <em>http://localhost:28017</em>.</p>
<p>Lo siguiente es empezar el proyecto de rails. Lo importante es evitar que utilice ActiveRecord:</p>
<pre class="brush: bash; title: ; notranslate">
rails new myproject -O
</pre>
<p>Esto basicamente crea tu proyecto Rails con todo lo necesario para trabajar con MongoDB. Puedes ver qué hace realmente viendo la documentación de MongoDB, donde explican <a href="http://www.mongodb.org/display/DOCS/Rails+3+-+Getting+Started" onclick="pageTracker._trackPageview('/outgoing/www.mongodb.org/display/DOCS/Rails+3+-+Getting+Started?referer=');">cómo trabajar con Rails</a>.</p>
<p>Ahora vamos a hacer un alto en el camino. Es una buena práctica con rvm definir un gemset por proyecto, para evitar posibles conflictos. Lo explica muy bien <a href="http://railsatope.blogspot.com/2011/06/cambio-automatico-de-gemsets-con-rvm.html" onclick="pageTracker._trackPageview('/outgoing/railsatope.blogspot.com/2011/06/cambio-automatico-de-gemsets-con-rvm.html?referer=');">Javi Baena en su blog</a>. Accedemos al directorio de nuestro proyecto <code>/myproject</code> y creamos un fichero .rvmrc que incluya lo siguiente:</p>
<pre class="brush: bash; title: ; notranslate">
rvm --create use 1.9.2@myproject
</pre>
<p>Sal del directorio del proyecto y vuelve a entrar. Si no había ningún gemset con el nombre myproject lo creará y cambiará a él de manera automática. Como ves, esto es de mucha ayuda cuando tienes varios proyectos en diferentes entornos de desarrollo, no tienes que estar pensando qué entorno utiliza cada uno y demás. Muy útil.</p>
<p>Bien, ahora vamos con el último paso, <a href="http://mongoid.org" onclick="pageTracker._trackPageview('/outgoing/mongoid.org?referer=');">Mongoid</a>. Simplemente incluye en tu <code>Gemfile</code>:</p>
<pre class="brush: ruby; title: ; notranslate">
gem &quot;mongoid&quot;, &quot;~&gt; 2.1&quot;
gem &quot;bson_ext&quot;, &quot;~&gt; 1.3&quot;
</pre>
<p>Y para terminar, en consola:</p>
<pre class="brush: bash; title: ; notranslate">
bundle install
rails g mongoid:config
</pre>
<p>Con la última línea creamos el fichero de configuración que necesita Mongoid (config/mongoid.yml). En su página oficial puedes las diferentes opciones que se pueden incluir en este fichero.</p>
<p>Como primera toma de contacto no está nada mal, ahora toca pelearse con MongoDB. Te recomendaría ver el <a href="http://railscasts.com/episodes/238-mongoid" onclick="pageTracker._trackPageview('/outgoing/railscasts.com/episodes/238-mongoid?referer=');">railscast de Ryan Bates sobre Mongoid</a>, donde te cuenta lo mismo que yo y mucho más.</p>
<p><strong>Actualización</strong>: Si os encontráis en el momento de plantear cómo va a ser el esquema de la base de datos, os aconsejo echarle un vistazo a esta <a href="https://www.10gen.com/presentation/mongosf2011/schemabasics" onclick="pageTracker._trackPageview('/outgoing/www.10gen.com/presentation/mongosf2011/schemabasics?referer=');">presentación de Kyle Banker</a>. Intentaré plasmar en un post lo que saque en claro después de verla.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=C-9B60dFLVo:7HbudmyB2UQ:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=C-9B60dFLVo:7HbudmyB2UQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=C-9B60dFLVo:7HbudmyB2UQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=C-9B60dFLVo:7HbudmyB2UQ:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/C-9B60dFLVo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/ruby-on-rails/comenzar-proyecto-ruby-1-9-2-rails-3-1-mongodb-mongoid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/ruby-on-rails/comenzar-proyecto-ruby-1-9-2-rails-3-1-mongodb-mongoid/</feedburner:origLink></item>
		<item>
		<title>Metaprogramación: métodos y delegates</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/qH_xeUr4OOs/</link>
		<comments>http://danielcalderon.net/desarrollo-web/ruby-on-rails/metaprogramacion-metodos-delegates/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 14:18:54 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[metaprogramación]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=211</guid>
		<description><![CDATA[En el proyecto que estoy trabajando ahora mismo necesitamos diferenciar en vista ciertos elementos en función del tipo al que pertenecen. Sin embargo, el tipo no está asociado directamente a ellos. Para entendernos: Un tipo consta de nombre y label. Para saber si un Item es de un tipo concreto podemos solucionarlo facilmente con un [...]]]></description>
			<content:encoded><![CDATA[<p>En el proyecto que estoy trabajando ahora mismo necesitamos diferenciar en vista ciertos elementos en función del tipo al que pertenecen. Sin embargo, el tipo no está asociado directamente a ellos. Para entendernos:</p>
<pre class="brush: ruby; title: ; notranslate">
class Kind &lt; ActiveRecord::Base
  has_many :items
end

class Item &lt; ActiveRecord::Base
  belongs_to :kind
end

class ItemData &lt; ActiveRecord::Base
  belongs_to :item
end
</pre>
<p>Un tipo consta de nombre y label. Para saber si un Item es de un tipo concreto podemos solucionarlo facilmente con un poco de metaprogramación básica:</p>
<pre class="brush: ruby; title: ; notranslate">
if ActiveRecord::Base.connection.tables.include?('kinds')
  Kind.all.map(&amp;:label).each do |label|
    define_method &quot;#{label}?&quot; do
      self.kind.label == label
    end
  end
end
</pre>
<p>Ahora tenemos métodos como por ejemplo item.a?, item.b?, etc&#8230; Sin embargo, por manos del diablo, en vista no trabajamos directamente con un objeto de tipo Item sino con objetos de tipo ItemData. Si todo estuviera cerradito podríamos hacer cosas como:</p>
<pre class="brush: ruby; title: ; notranslate">
class ItemData &lt; ActiveRecord::Base
  belongs_to :item

  delegate :a?, :to =&gt; :item
end
</pre>
<p>Pero no es nuestro caso, no está cerrado. ¿Cómo lo hacemos? Le echamos un ojo a cómo está hecho el método <a href="http://apidock.com/rails/Module/delegate" onclick="pageTracker._trackPageview('/outgoing/apidock.com/rails/Module/delegate?referer=');">delegate</a> y tras poner aquí y quitar allá, nos queda algo como esto:</p>
<pre class="brush: ruby; title: ; notranslate">
class ItemData &lt; ActiveRecord::Base
  belongs_to :item
  if ActiveRecord::Base.connection.tables.include?('kinds')
    Kind.all.map(&amp;:label).each do |label|
      method = label + '?'
      module_eval(&lt;&lt;-EOS, &quot;(__DELEGATION__)&quot;, 1)
         def #{method}
           notice.__send__(#{method.inspect})
         end
       EOS
    end
  end
end
</pre>
<p>Y ya está. Ahora podemos hacer cosas como @item_data.a? y si el día de mañana se añaden tipos, tendremos su método delegate correspondiente.</p>
<p><strong>Actualización</strong>: incluyo un condicional para saber si está disponible o no la tabla Kind, ya que de otro modo, rake ni siquiera nos deja correr migraciones para que exista.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=qH_xeUr4OOs:o4N9IErxyyg:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=qH_xeUr4OOs:o4N9IErxyyg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=qH_xeUr4OOs:o4N9IErxyyg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=qH_xeUr4OOs:o4N9IErxyyg:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/qH_xeUr4OOs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/ruby-on-rails/metaprogramacion-metodos-delegates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/ruby-on-rails/metaprogramacion-metodos-delegates/</feedburner:origLink></item>
		<item>
		<title>Dragonfly y procesado de imágenes: problema con el uid</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/zQbCRqWqZ5g/</link>
		<comments>http://danielcalderon.net/desarrollo-web/ruby-on-rails/dragonfly-y-procesado-de-imagenes-problema-con-el-uid/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 17:45:48 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[dragonfly]]></category>
		<category><![CDATA[procesado de imágenes]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=204</guid>
		<description><![CDATA[Desde hace algún tiempo venimos trabajando en Flowers in Space en un nuevo producto propio que queremos lanzar a Internet. En él, para el tratamiento de imágenes, por diversos motivos que no vienen a cuento, nos decidimos por utilizar Dragonfly, un framework Rack para el tratamiento de imágenes. Dragonfly es una maravilla. Nos abstraemos del [...]]]></description>
			<content:encoded><![CDATA[<p>Desde hace algún tiempo venimos trabajando en Flowers in Space en un nuevo producto propio que queremos lanzar a Internet. En él, para el tratamiento de imágenes, por diversos motivos que no vienen a cuento, nos decidimos por utilizar <a href="https://github.com/markevans/dragonfly" onclick="pageTracker._trackPageview('/outgoing/github.com/markevans/dragonfly?referer=');">Dragonfly</a>, un framework Rack para el tratamiento de imágenes.</p>
<p><strong>Dragonfly</strong> es una maravilla. Nos abstraemos del post procesado de imágenes y cuando necesitamos que cierta imagen esté en un determinado tamaño basta hacer en vista algo tan simple como por ejemplo @album.cover_image.thumb(&#8217;400&#215;200#&#8217;) y él nos sirve la imagen, la guarda donde le hayamos indicado, y nos olvidamos.</p>
<p>Sin embargo, en algunos casos concretos sabemos que no vamos a necesitar más de un tamaño de imagen. Para esos determinados podemos seguir utilizando Dragonfly y post procesar la imagen antes de guardarla. Mi problema era que estaba intentando hacerlo mediante un before_save de toda la vida y el uid de mi imagen no se generaba. Consecuencia: que en realidad no tenía imagen.</p>
<p>He aquí la solución. Imaginemos el caso anterior, un album que tiene una portada (el ejemplo de la documentación de Dragonfly, vaya). Pero sabemos de antemano que cuando mostremos nuestra portada en la web tendrá un tamaño de 50&#215;50 (<em>un poné</em>). Pues al definir el <code>image_accessor</code> en nuestro modelo podemos hacer lo siguiente:</p>
<pre class="brush: ruby; title: ; notranslate">
image_accessor :cover_image do
    after_assign{ |img| img.process!(:thumb, '50x50') }
end
</pre>
<p>Podéis encontrar más ejemplos y otros callbacks en la <a href="http://markevans.github.com/dragonfly/file.Models.html#Callbacks" onclick="pageTracker._trackPageview('/outgoing/markevans.github.com/dragonfly/file.Models.html_Callbacks?referer=');">documentación de Dragonfly</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=zQbCRqWqZ5g:YoHQVZagxVw:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=zQbCRqWqZ5g:YoHQVZagxVw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=zQbCRqWqZ5g:YoHQVZagxVw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=zQbCRqWqZ5g:YoHQVZagxVw:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/zQbCRqWqZ5g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/ruby-on-rails/dragonfly-y-procesado-de-imagenes-problema-con-el-uid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/ruby-on-rails/dragonfly-y-procesado-de-imagenes-problema-con-el-uid/</feedburner:origLink></item>
		<item>
		<title>Error ActiveRecord::ReadOnlyRecord al actualizar atributos</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/vRXNIOybILo/</link>
		<comments>http://danielcalderon.net/desarrollo-web/ruby-on-rails/error-activerecordreadonlyrecord-al-actualizar-atributos/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 22:21:36 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[ActiveRecord::ReadOnlyRecord]]></category>
		<category><![CDATA[controlador]]></category>
		<category><![CDATA[errores]]></category>
		<category><![CDATA[has_many :through]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=195</guid>
		<description><![CDATA[Sigo con mi proyecto final de carrera y poco a poco vamos aprendiendo cosillas nuevas de Rails. Al mismo tiempo que voy picando código en el controlador, modelo y vistas voy testeando, dos frentes de aprendizaje pero que recomiendo a todos los que comiencen en Rails. Aunque al principio avanzas de forma más lenta y [...]]]></description>
			<content:encoded><![CDATA[<p>Sigo con mi proyecto final de carrera y poco a poco vamos aprendiendo cosillas nuevas de Rails. Al mismo tiempo que voy picando código en el controlador, modelo y vistas voy testeando, dos frentes de aprendizaje pero que <strong>recomiendo</strong> a todos los que comiencen en Rails. Aunque al principio avanzas de forma más lenta y te das (como estoy haciendo yo) de bruces contra un muro una y otra vez, a la larga aprendes mucho tanto de tus múltiples errores como de tus aciertos.</p>
<p>Una vez tenía hecho el test de un <em>update</em> supuestamente correcto obtuve un error al actualizar los atributos de un objeto. En primera instancia pensé que había olvidado en el modelo alguna cosa, pero también estaba correcto. Tras una búsqueda en Google <a href="http://stackoverflow.com/questions/639171/what-is-causing-this-activerecordreadonlyrecord-error#answer-639844" onclick="pageTracker._trackPageview('/outgoing/stackoverflow.com/questions/639171/what-is-causing-this-activerecordreadonlyrecord-error_answer-639844?referer=');">encontré la solución</a>.</p>
<p>Extrayendo la explicación del artículo</p>
<blockquote><p>Introduce read-only records. If you call object.readonly! then it will mark the object as read-only and raise ReadOnlyRecord if you call object.save. object.readonly? reports whether the object is read-only. Passing :readonly => true to any finder method will mark returned records as read-only. <strong>The :joins option now implies :readonly, so if you use this option, saving the same record will now fail</strong>. Use find_by_sql to work around.</p></blockquote>
<p>O lo que es lo mismo, si tu objeto lo obtienes tirando de relaciones, por ejemplo, un <em>has_many :through</em>, por debajo está haciendo un INNER JOIN con el modelo intermedio, y ahi está el problema, que el objeto pasa a ser de solo lectura. Las soluciones podrían ser dos:</p>
<ol>
<li>Obligar al objeto a que no sea solo lectura indicando como parámetro del find :readonly => false</li>
<li>Utilizar include en lugar de join, si es posible</li>
</ol>
<p>Hasta aquí lo que venías buscando. Pero si quieres ver un ejercicio práctico sobre relaciones y cómo evitar el <strong>ActiveRecord::ReadOnlyRecord</strong> en él sigue leyendo.</p>
<h4>Ejemplo práctico</h4>
<p>Imaginemos que estamos en el WoW (oh dios, no puedo creer que esté escribiendo esto). Tenemos hermandades (guild) y jugadores (users). Las hermandades pueden tener varios jugadores, de los cuales varios pueden ser Maestre, algo así como los &#8220;admin&#8221; de la hermandad, y puede haber más de un Maestre por hermandad. Además los jugadores pueden estar en varias hermandades.</p>
<p>Seguro que se puede hacer de varias formas, pero nosotros vamos a hacerlo mediante un <em>has_many :through</em>, utilizando como modelo intermedio <em>membership</em>, donde tenemos un campo <em>owner</em> que nos indica si es o no maestre de la hermandad.</p>
<p>Empezamos con los modelos:</p>
<p><strong>guild.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
  has_many :memberships
  has_many :users, :through =&gt; :memberships, :uniq =&gt; true
  has_many :owners, :through =&gt; :memberships, :source =&gt; :user, :conditions =&gt; { &quot;memberships.owner&quot; =&gt; true }

  validates_presence_of :name
</pre>
<p>De esta manera si tenemos una hermandad en @guild podemos saber quienes son todos sus miembros haciendo @guild.users y sus maestres @guild.owners.</p>
<p><strong>IMPORTANTE</strong>: Este ejemplo no está completo. Es decir, si hacemos @guild.owners << User.find(5) (por ejemplo) no crea adecuadamente el membership, ya que faltaría marcar el campo owner del membership creado a <em>true</em>. Eso lo dejo para otro post y no seguir complicando las cosas.</p>
<p><strong>user.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
  has_many :memberships
  has_many :guilds, :through =&gt; :memberships
  has_many :owned_guilds, :through =&gt; :memberships, :source =&gt; :owner, :conditions =&gt; { &quot;memberships.owner&quot; =&gt; true }
</pre>
<p>De esta manera podemos saber qué hermandades lidera un jugador haciendo @user.owned_guilds y a cuales pertenece (sea maestre o no) haciendo @user.guilds.</p>
<p>De nuevo, <strong>importante</strong>: Este ejemplo no está completo. Es decir, si hacemos @user.owned_guilds << Guild.find(7) (por ejemplo) no crea adecuadamente el membership, ya que faltaría marcar el campo owner del membership creado a <em>true</em>.</p>
<p><strong>ownership.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
belongs_to :user
belongs_to :owner, :class_name =&gt; &quot;User&quot;
belongs_to :guild
</pre>
<p>Hasta aquí el ejercicio práctico de relaciones, ahora vamos al lío. Imaginemos que queremos actualizar el nombre de nuestra hermandad. Para hacer esto debes ser maestre de la hermandad. Si tenemos en cuenta que no hemos metido aquí un sistema de permisos (rollo CanCan o similares) podemos solucionar esto de dos formas:</p>
<h5>Buscar y modificar si es posible</h5>
<p><strong>guilds_controller.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
def edit
  @guild = Guild.find(params[:id])
end

def update
  @guild = Guild.find(params[:id])
  if @guild.update_attributes(params[:guild])
    redirect_to guild_path(@guild), :success =&gt; &quot;Guild actualizada&quot;
  else
    render :edit
  end
end
</pre>
<p>Algo de refactoring básico:</p>
<p><strong>guilds_controller.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">

before_filter :get_guild

def edit
end

def update
  if @guild.update_attributes(params[:guild])
    redirect_to guild_path(@guild), :success =&gt; &quot;Guild actualizada&quot;
  else
    render :edit
  end
end

protected

def get_guild
  @guild = Guild.find(params[:id])
end
</pre>
<p>Además vamos a tener aquello de que <strong>actualizar el nombre de la hermandad solo puede hacerlo el maestre</strong>.</p>
<p><strong>guilds_controller.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">

before_filter :get_guild
before_filter :check_ownerhip

def edit
end

def update
  if @guild.update_attributes(params[:guild])
    redirect_to guild_path(@guild), :success =&gt; &quot;Guild actualizada&quot;
  else
    flash[:error] = &quot;No ha sido posible actualizar los datos de la guild&quot;
    render :edit
  end
end

protected

def get_guild
  @guild = Guild.find(params[:id])
end

def check_ownership
   redirect_to user_path(current_user), :error =&gt; &quot;No tienes permisos&quot; unless current_user.owned_guilds.include?(@guild)
end
</pre>
<p>En este primer ejemplo, no obtenemos un ActiveRecord::ReadOnlyRecord ya que obtenemos la @guild directamente (sin el uso del join de la has_many :through) y el objeto @guild no es de solo lectura. La consulta que se hace a base de datos sería:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT `guilds`.* FROM `guilds` WHERE `guilds`.`id` = 1 LIMIT 1
</pre>
<h5>Tirar de relaciones y 404</h5>
<p>Esta es la segunda forma, donde no vamos a utilizar un before_filter para comprobar si el jugador es maestre de la hermandad. En su lugar vamos a aprovecharnos de que al buscar entre las owned_guilds de un jugador una de la que no sea maestre en Rails obtenemos un ActiveRecord::RecordNotFound, o lo que es lo mismo, un 404.</p>
<p><strong>guilds_controller.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
before_filter :get_guild

protected

def get_guild
  @guild = current_user.owned_guilds.find(params[:id])
end
</pre>
<p>El resto de acciones del controlador permanece intacto (exceptuando como dije, el before_filter :check_ownership que no estaría en este segundo ejemplo).</p>
<p>Y ahora&#8230; por fin, ¿y el ActiveRecord::ReadOnlyRecord donde anda en este segundo ejemplo? Pues al hacer @guild = current_user.owned_guilds.find(params[:id]), @guild es de solo lectura, al haber tirado de relaciones.</p>
<p>Suponiendo que el User con id igual a 1 quiere actualizar la Guild con id igual a 1. Lo primera lanzaría la siguiente consulta:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT `guilds`.* FROM `guilds` INNER JOIN `ownerships` ON `guilds`.id = `ownerships`.guild_id WHERE `guilds`.`id` = 1 AND ((`ownerships`.user_id = 1)) LIMIT 1
</pre>
<p>Ahí podéis ver el JOIN al que antes hacía mención. Habiendo un JOIN de por medio, el objeto es de solo lectura. Y no podremos actualizarlo.</p>
<h5>Tío, termina ya, so pesao</h5>
<p>Pues la solución para mantener el segundo ejemplo tal cual y poder actualizar es tan simple como indicar que no es de solo lectura. ¿Cómo?</p>
<pre class="brush: ruby; title: ; notranslate">
before_filter :get_guild

protected

def get_guild
  @guild = current_user.owned_guilds.find(params[:id], :readonly =&gt; false)
end
</pre>
<p>Vaya artículo largo. No tengo remedio. Al menos espero que le sirva a alguien. Y como siempre, si alguien tiene algo que aportar o corregir, dispone de los comentarios para ello, yo lo agradezco un montón.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=vRXNIOybILo:7JlOvkfL7QE:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=vRXNIOybILo:7JlOvkfL7QE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=vRXNIOybILo:7JlOvkfL7QE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=vRXNIOybILo:7JlOvkfL7QE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/vRXNIOybILo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/ruby-on-rails/error-activerecordreadonlyrecord-al-actualizar-atributos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/ruby-on-rails/error-activerecordreadonlyrecord-al-actualizar-atributos/</feedburner:origLink></item>
		<item>
		<title>has_many con múltiples foreign_keys</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/nX3Tbf1OQuM/</link>
		<comments>http://danielcalderon.net/desarrollo-web/ruby-on-rails/has_many-con-multiples-foreign_keys/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 11:43:28 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[has_many]]></category>
		<category><![CDATA[relaciones]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=185</guid>
		<description><![CDATA[Estos días estoy desconectado del mundo. No tengo tiempo para nada entre el proyecto final de carrera y el WoW al que José Galisteo aka Ceritium me enganchó muy gentilmente. Pero como estoy aprendiendo cositas de Rails, donde estoy todavía muy verde, y son sencillas, pues quería compartirlas. Tenemos un modelo, por ejemplo, Person. Y [...]]]></description>
			<content:encoded><![CDATA[<p>Estos días estoy desconectado del mundo. No tengo tiempo para nada entre el proyecto final de carrera y el WoW al que <a href="http://jose.gr/" title="Blog de José Galisteo" onclick="pageTracker._trackPageview('/outgoing/jose.gr/?referer=');">José Galisteo</a> aka Ceritium me enganchó muy gentilmente. Pero como estoy aprendiendo cositas de Rails, donde estoy todavía muy verde, y son sencillas, pues quería compartirlas.</p>
<p>Tenemos un modelo, por ejemplo, <strong>Person</strong>. Y tenemos otro <strong>Dish</strong>. Los platos (dishes) están relacionados de diferentes formas con las personas: alguien los cocina, alguien se los come, alguien los limpia (un poné, como se dice en mi tierra). Un plato tiene un cocinero, un comensal, un limpiador, pero todos son Personas (nen). Y una persona puede tener varios platos cocinados, varios platos degustados y haber limpiado varios platos. Veamos como solucionarlo ahora que está más claro:</p>
<p><strong>User.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
has_many :cooked_dishes, :class_name =&gt; &quot;Dish&quot;, :foreign_key =&gt; &quot;cooker_id&quot;
has_many :tasted_dishes, :class_name =&gt; &quot;Dish&quot;, :foreign_key =&gt; &quot;taster_id&quot;
has_many :cleaned_dishes, :class_name =&gt; &quot;Dish&quot;, :foreign_key =&gt; &quot;cleaner_id&quot;
</pre>
<p><strong>Dish.rb</strong></p>
<pre class="brush: ruby; title: ; notranslate">
belongs_to :cooker, :class_name =&gt; &quot;User&quot;
belongs_to :taster, :class_name =&gt; &quot;User&quot;
belongs_to :cleaner, :class_name =&gt; &quot;User&quot;
</pre>
<p>De esta manera, si en @user tenemos a un usuario, podemos hacer @user.cooked_dishes, @user.tasted_dishes o @user.cleaned_dishes. Y del mismo modo si tenemos un plato podríamos saber quién lo cocinó, quién lo degustó y quien lo limpió: @dish.cooker, @dish.taster, @dish.cleaner.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=nX3Tbf1OQuM:DgxdEKiwauk:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=nX3Tbf1OQuM:DgxdEKiwauk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=nX3Tbf1OQuM:DgxdEKiwauk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=nX3Tbf1OQuM:DgxdEKiwauk:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/nX3Tbf1OQuM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/ruby-on-rails/has_many-con-multiples-foreign_keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/ruby-on-rails/has_many-con-multiples-foreign_keys/</feedburner:origLink></item>
		<item>
		<title>Crear un blog en Heroku con Toto: alternativa a WordPress</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/PcM5uN-SfVc/</link>
		<comments>http://danielcalderon.net/desarrollo-web/crear-blog-en-heroku-toto-alternativa-wordpress/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 09:00:33 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[toto]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=163</guid>
		<description><![CDATA[Creo que este es uno de los pasos que me falta por dar pero no me decido a hacerlo, al menos de golpe y porrazo. Jose, el evangelizador, me puso sobre la pista de Toto, una plataforma para la creación de blogs. Y diréis que tengo más cara que espalda, hacer un post recomendando que [...]]]></description>
			<content:encoded><![CDATA[<p>Creo que este es uno de los pasos que me falta por dar pero no me decido a hacerlo, al menos de golpe y porrazo. Jose, el evangelizador, me puso <a href="http://jose.gr/2010/09/30/toto-un-blog-en-10-segundos/" onclick="pageTracker._trackPageview('/outgoing/jose.gr/2010/09/30/toto-un-blog-en-10-segundos/?referer=');">sobre la pista de Toto</a>, una plataforma para la creación de blogs.</p>
<p>Y diréis que tengo más cara que espalda, hacer un post recomendando que os paséis a <a href="cloudhead.io/toto">Toto</a> y estar usando yo un WordPress, que debo predicar con el ejemplo y todo eso. Os doy la razón, podéis fustigarme, soy un ser vil. Pero a mi favor diré que estamos trabajando en ello :P</p>
<p>Total, al grano que siempre me enrollo. <strong>¿Qué porras es Toto?</strong> Alexis Sellier, el creador de <a href="http://lesscss.org/" onclick="pageTracker._trackPageview('/outgoing/lesscss.org/?referer=');">Less</a> y de Toto os lo cuenta:</p>
<blockquote><p>toto is a git-powered, minimalist blog engine for the hackers of Oz. The engine weighs around 300 sloc at its worse. There is no toto client, at least for now; everything goes through git.
</p></blockquote>
<p>Dejando de un lado posibles modificaciones de Toto, gracias a él podemos crear un blog en 15 segundos, listo para usar. No almacena los post en una base de datos, sino en archivos .txt que creamos en local y que luego, mediante git, subimos a un repositorio. Y al poder almacenarlo facilmente en <a href="heroku.com">Heroku</a>, os invito al menos a probar, que no se pierde nada.</p>
<p><strong>Prerequisitos para cambiarte a Toto</strong>: que estés cansado de las actualizaciones de WordPress, que uses git, que abraces el cambio :)</p>
<p>¿Os mola? Pues al lío:</p>
<h3>Crear una cuenta en Heroku</h3>
<p>Antes que nada, para poder alojar nuestro blog  en <strong>Heroku</strong> tenemos que <a href="http://heroku.com/signup" onclick="pageTracker._trackPageview('/outgoing/heroku.com/signup?referer=');">darnos de alta</a>. Nos enviarán un email de confirmación al correo con el que nos registremos.</p>
<h3>Instalar la gema Heroku y añadir nuestra clave pública</h3>
<p>Instalación:</p>
<pre class="brush: bash; title: ; notranslate">$ sudo gem install heroku</pre>
<p>Añadir clave pública:</p>
<pre class="brush: bash; title: ; notranslate">$ heroku keys:add</pre>
<p>Y para terminar escribimos nuestro email y contraseña.</p>
<h3>Creamos nuestro blog</h3>
<pre class="brush: bash; title: ; notranslate">
$ git clone git://github.com/cloudhead/dorothy.git myblog
$ cd myblog
$ heroku create myblog
$ git push heroku master
</pre>
<p>¿Ya? Sí, ya. Antes del siguiente paso te recomiendo que edites (o crees) un fichero .Gemfile y añadas la versión 0.4.6 de la gema de toto, la última versión, la 0.4.7 peta, no sé muy bien todavía por qué.</p>
<p>Añadiremos el servidor heroku.com a nuestra lista de servidores seguros y de una tacada subirá nuestro blog al repo e instalará las gemas que necesite. ¡Yasta! Blog ready to go!</p>
<p>Viendo la parrafada que me he marcado, debo replantearme escribir post más cortos, in <a href="http://jose.gr/2010/09/30/toto-un-blog-en-10-segundos/" onclick="pageTracker._trackPageview('/outgoing/jose.gr/2010/09/30/toto-un-blog-en-10-segundos/?referer=');">Gali Mode</a>.</p>
<p>PD: Desde la web de Toto podéis obtener <a href="cloudhead.io/toto">más información</a> sobre él</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=PcM5uN-SfVc:eAqH51ZkamE:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=PcM5uN-SfVc:eAqH51ZkamE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=PcM5uN-SfVc:eAqH51ZkamE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=PcM5uN-SfVc:eAqH51ZkamE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/PcM5uN-SfVc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/desarrollo-web/crear-blog-en-heroku-toto-alternativa-wordpress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/desarrollo-web/crear-blog-en-heroku-toto-alternativa-wordpress/</feedburner:origLink></item>
		<item>
		<title>Optimiza imágenes para web con ImageOptim (Mac)</title>
		<link>http://feedproxy.google.com/~r/danielcalderon/~3/15UMzZnbqKY/</link>
		<comments>http://danielcalderon.net/aplicaciones/optimiza-imagenes-para-web-con-imageoptim-mac/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 22:30:52 +0000</pubDate>
		<dc:creator>Daniel Calderón</dc:creator>
				<category><![CDATA[aplicaciones]]></category>
		<category><![CDATA[aplicación mac]]></category>
		<category><![CDATA[imágenes]]></category>
		<category><![CDATA[optimización de imágenes]]></category>
		<category><![CDATA[optimizar imágenes]]></category>

		<guid isPermaLink="false">http://danielcalderon.net/?p=167</guid>
		<description><![CDATA[ImageOptim es una aplicación para Mac que nos ayuda a optimizar imágenes JPG y PNG para su uso en Internet]]></description>
			<content:encoded><![CDATA[<p>Aquellos que utilicéis Photoshop o cualquier otra aplicación para diseñar (por cierto, estoy inmerso en el cambio a <a href="http://www.pixelmator.com" onclick="pageTracker._trackPageview('/outgoing/www.pixelmator.com?referer=');">Pixelmator</a>, ya os contaré qué tal) seguramente os molará <a href="http://imageoptim.pornel.net/" onclick="pageTracker._trackPageview('/outgoing/imageoptim.pornel.net/?referer=');">ImageOptim</a>, una pequeña pero gran aplicación para Mac para la optimización de imágenes para Internet.</p>
<p>La aplicación no hace más que facilitarnos la vida y proporcionarnos una interfaz gráfica para el uso de diferentes herramientas de optimización que ya trae de serie.</p>
<blockquote><p>AdvPNG from AdvanceCOMP, OptiPNG, PngCrush, JpegOptim, jpegtran from libjpeg, Gifsicle and optionally PNGOUT.</p></blockquote>
<p>Como bien indica la web de la aplicación, por el tipo de licencia de PNGOUT no puede venir incluido &#8220;de serie&#8221;, así que tenemos que instalarlo aparte. Es fácil:</p>
<ol>
<li>Lo descargáis desde su web: <a href="http://www.jonof.id.au/index.php?p=pngout" onclick="pageTracker._trackPageview('/outgoing/www.jonof.id.au/index.php?p=pngout&amp;referer=');">http://www.jonof.id.au/index.php?p=pngout</a></li>
<li>Descomprimimos y (si lo habéis descargado en la carpeta Downloads), abrimos el terminal y hacemos:
<pre class="brush: bash; title: ; notranslate">sudo mv /Downloads/pngout-darwin /usr/bin/pngout</pre>
</li>
</ol>
<p>Acto seguido abrimos ImageOptim y añadimos el path correspondiente (/usr/bin/pngout), nada más. A disfrutar de una herramienta muy útil para el día a día de un maquetador maquero.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/danielcalderon?a=15UMzZnbqKY:Sq9FbGfwTnM:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=15UMzZnbqKY:Sq9FbGfwTnM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/danielcalderon?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/danielcalderon?a=15UMzZnbqKY:Sq9FbGfwTnM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/danielcalderon?i=15UMzZnbqKY:Sq9FbGfwTnM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/danielcalderon/~4/15UMzZnbqKY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://danielcalderon.net/aplicaciones/optimiza-imagenes-para-web-con-imageoptim-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://danielcalderon.net/aplicaciones/optimiza-imagenes-para-web-con-imageoptim-mac/</feedburner:origLink></item>
	</channel>
</rss>

