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

<channel>
	<title>metaduck &#187; Rails</title>
	<atom:link href="http://www.metaduck.com/category/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.metaduck.com</link>
	<description></description>
	<lastBuildDate>Wed, 05 May 2010 12:04:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Will_paginate and AJAX</title>
		<link>http://www.metaduck.com/2010/04/will_paginate-and-ajax/</link>
		<comments>http://www.metaduck.com/2010/04/will_paginate-and-ajax/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 15:07:59 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.metaduck.com/?p=247</guid>
		<description><![CDATA[I have been using will_paginate ever since I started on Rails.
It's a great plugin for classic page rendering, but what if you want to use it with AJAX, so it updates a document element (a floating window layer, for instance) with the results instead of reloading the page?
Well, inspired on Redline's blog post (which almost [...]]]></description>
			<content:encoded><![CDATA[<p>I have been using will_paginate ever since I started on Rails.</p>
<p>It's a great plugin for classic page rendering, but what if you want to use it with AJAX, so it updates a document element (a floating window layer, for instance) with the results instead of reloading the page?</p>
<p>Well, inspired on <a href="http://weblog.redlinesoftware.com/2008/1/30/willpaginate-and-remote-links">Redline's blog post</a> (which almost worked for the latest version of the will_paginate plugin), I have the solution.</p>
<p>Create a link renderer. I put in under lib/remote_link_renderer.rb so Rails always loads it on startup.</p>
<pre style="font-size: 1.1em; background-color: #dddddd; overflow-x: auto; overflow-y: auto; padding: 0.4em; border: 1px solid #aaaaaa;"><code style="font-size: 1.1em; font-family: Monaco, 'Courier New', monospace; color: #000000;"><span style="font-family: monospace; color: #8b0000;">class</span> <span>RemoteLinkRenderer</span> &lt; <span>WillPaginate</span>:<span style="font-family: monospace; color: #884400;">:LinkRenderer</span>

  <span style="font-family: monospace; color: #8b0000;">def</span> page_link_or_span<span>(</span>page, span_class = <span style="font-family: monospace; color: #00008b;">'current'</span>, text = nil<span>)</span>
    text ||= page<span style="font-family: monospace; color: #006400;">.to_s</span>
    <span style="font-family: monospace; color: #8b0000;">if</span> page and page != current_page
      <span>@template</span><span style="font-family: monospace; color: #006400;">.link_to_remote</span><span>(</span>text, <span>{</span><span style="font-family: monospace; color: #884400;">:url</span> =&gt; url_for<span>(</span>page<span>)</span>, <span style="font-family: monospace; color: #884400;">:method</span> =&gt; <span style="font-family: monospace; color: #884400;">:get</span><span>}</span><span style="font-family: monospace; color: #006400;">.merge</span><span>(</span><span>@remote</span><span>)</span><span>)</span>
    <span style="font-family: monospace; color: #8b0000;">else</span>
      <span>@template</span><span style="font-family: monospace; color: #006400;">.content_tag</span> <span style="font-family: monospace; color: #884400;">:span</span>, text, <span style="font-family: monospace; color: #884400;">:class</span> =&gt; span_class
    <span style="font-family: monospace; color: #8b0000;">end</span>
  <span style="font-family: monospace; color: #8b0000;">end</span>
<span style="font-family: monospace; color: #8b0000;">end</span></code></pre>
<p>On the view, when you are rendering the pager, do it like this:</p>
<pre style="font-size: 1.1em; background-color: #dddddd; overflow-x: auto; overflow-y: auto; padding: 0.4em; border: 1px solid #aaaaaa;"><code style="font-size: 1.1em; font-family: Monaco, 'Courier New', monospace; color: #000000;">&lt;%= will_paginate <span>@collection</span>, <span style="font-family: monospace; color: #884400;">:renderer</span> =&gt; <span style="font-family: monospace; color: #00008b;">'RemoteLinkRenderer'</span> , <span style="font-family: monospace; color: #884400;">:remote</span> =&gt; <span>{</span><span style="font-family: monospace; color: #884400;">:with</span> =&gt; ’value’, <span style="font-family: monospace; color: #884400;">:update</span> =&gt; ‘some_div’<span>}</span> %&gt;</code></pre>
<p>That's it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2010/04/will_paginate-and-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to paginate outside of the database with will_paginate</title>
		<link>http://www.metaduck.com/2010/03/how-to-paginate-outside-of-the-database-with-will_paginate/</link>
		<comments>http://www.metaduck.com/2010/03/how-to-paginate-outside-of-the-database-with-will_paginate/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 11:09:33 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.metaduck.com/?p=240</guid>
		<description><![CDATA[will_paginate is a great plugin. I have been using it since I started on Rails.
If you want to paginate records that are inside your database it works great.
But what if you want to paginate records that come from, say an external webservice?
Well, you can use the WillPaginate::Collection class.
This class will let you mimic the collection [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://wiki.github.com/mislav/will_paginate/">will_paginate</a> is a great plugin. I have been using it since I started on Rails.</p>
<p>If you want to paginate records that are inside your database it works great.</p>
<p>But what if you want to paginate records that come from, say an external webservice?</p>
<p>Well, you can use the WillPaginate::Collection class.</p>
<p>This class will let you mimic the collection that will work on a pager, so you can use the view helper pager seamlessly throughout your app.</p>
<p>Just use it like this:</p>
<pre style="font: normal normal normal 14px/normal Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace; color: black; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f8f8f8; padding-top: 0.5em; padding-right: 0.8em; padding-bottom: 0.5em; padding-left: 0.8em; overflow-x: auto; overflow-y: auto; background-position: initial initial; background-repeat: initial initial; border: 1px solid silver;">@entries = WillPaginate::Collection.create(1, 10) do |pager|
  result = Webservice.get(...) # get your results
  # inject the result array into the paginated collection:
  pager.replace(result)

  unless pager.total_entries
    # the pager didn't manage to guess the total count, do it manually
    pager.total_entries = result.count
  end
end</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2010/03/how-to-paginate-outside-of-the-database-with-will_paginate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tools for the job</title>
		<link>http://www.metaduck.com/2009/11/tools-for-the-job/</link>
		<comments>http://www.metaduck.com/2009/11/tools-for-the-job/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 15:28:24 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.metaduck.com/?p=208</guid>
		<description><![CDATA[See the tools / gems / plugins I can't live without.]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-226 alignleft" title="tools" src="http://www.metaduck.com/wp-content/uploads/2009/11/tools.jpeg" alt="tools" width="123" height="123" />Here are some tools / gems / plugins I can't live without:</p>
<h2>IDEs:</h2>
<ul>
<li><a href="http://www.radrails.org/">Aptana Rad Rails</a> - very good at Rails and Ruby. It's based on Eclipse - Java - so it tends to bloat</li>
<li><a href="http://projects.gnome.org/gedit/">gedit</a>- Tiny footprint, simple. Great for web and PHP with the right plugins and conf tweaks</li>
</ul>
<h2>Ruby / Rails plugins:</h2>
<p><span id="more-208"></span></p>
<ul>
<li><a href="http://wiki.github.com/mislav/will_paginate">will_paginate</a> - ActiveRecord pagination made easy</li>
<li><a href="http://github.com/Squeegy/fleximage">fleximage</a> - online image processing Rails plug-in based on rmagick. Very easy to manipulate</li>
<li><a href="http://github.com/whymirror/hpricot">hpricot gem</a> - for parsing HTML and XML. Very resilient to formatting errors. Use it to parse XML feeds with wrong encoding and screen scraping.</li>
<li><a href="http://github.com/binarylogic/authlogic">authlogic</a> - for easy and extensible authentication. With care you can make it easily authenticate with anything.</li>
<li><a href="http://deveiate.org/projects/BlueCloth">BlueCloth</a> gem - for markdown markup</li>
<li><a href="http://rubyeventmachine.com/">eventmachine</a> - scalable asynchronous Ruby servers made easy.</li>
<li><a href="http://wiki.github.com/pgte/styled_objects">styled_objects</a> - simplify stylesheet development and maintenance. By yours truly.</li>
<li><a href="http://github.com/collectiveidea/delayed_job">delayed_job</a> - job queuing for Rails made easy.</li>
<li><a href="http://github.com/cjbottaro/app_config">app_config</a> gem - easy application configuration. Easily differentiate for each environment.</li>
<li><a href="http://wiki.github.com/frabcus/acts_as_xapian">acts_as_xapian</a> - easy ruby and Rails bindings for Xapian - full text search engine. Xapian uses offline index update and does not use a daemon.</li>
<li><a href="http://stonean.com/page/lockdown">lockdown</a> -  authorization system for Rails</li>
<li><a href="http://wiki.github.com/pgte/acts_as_pingable">acts_as_pingable</a> - to expose you Rails stack to external pings. Use it for pingdom.com integration.</li>
<li><a href="http://github.com/giraffesoft/resource_controller">resource_controller</a> - simplifies code for resource controllers (almost no code at all for most cases !)</li>
<li><a href="http://github.com/rubyist/aasm">aasm (acts as state machine)</a> - easily turn your objects into state machines.</li>
</ul>
<h2>Testing</h2>
<ul>
<li><a href="http://cukes.info/">cucumber</a> - BDD at it's best</li>
<li><a href="http://mocha.rubyforge.org/">mocha</a> - intuitive mocking and stubbing</li>
<li><a href="http://rspec.info/">rspec and rspec-rails</a> - Rails testing</li>
<li><a href="http://github.com/thoughtbot/factory_girl">factory_girl</a> - Get rid of fixtures</li>
</ul>
<h2>Database</h2>
<ul>
<li><a href="http://www.mysql.com/">MySQL</a> - I love it, I hate it, I have to live with it...</li>
<li><a href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a> - fast single table database for key-value store (it already has multiple columns format) with a simple Ruby API. Useful for a lot of things. You can also use <a href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a> for service.</li>
</ul>
<h2>Deployment</h2>
<ul>
<li><a href="http://www.capify.org">Capistrano</a> - although there are some simpler alternatives around, I simply love Capistrano and use it for almost everything deployment-related.</li>
<li><a href="http://github.com/jamis/capistrano-ext">capistrano-ext</a> - with multistaging deployment, among other goodies.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2009/11/tools-for-the-job/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutorial: building and styling a Rails app with styled_objects</title>
		<link>http://www.metaduck.com/2009/10/tutorial-building-and-styling-a-rails-app-with-styled-objects/</link>
		<comments>http://www.metaduck.com/2009/10/tutorial-building-and-styling-a-rails-app-with-styled-objects/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 22:53:23 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.metaduck.com/?p=88</guid>
		<description><![CDATA[How to keep your stylesheets clean and organized using Rails
This tutorial covers building a web application from scratch using Rails with the styled_objects plugin.
As an example we will be building a very static front-end website, mainly to focus on stylesheets.
Everything you get from can be applied to more complex applications.
Because this is such a simple [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>How to keep your stylesheets clean and organized using Rails</em></strong></p>
<p>This tutorial covers building a web application from scratch using Rails with the styled_objects plugin.</p>
<p><span id="more-88"></span>As an example we will be building a very static front-end website, mainly to focus on stylesheets.</p>
<p>Everything you get from can be applied to more complex applications.</p>
<p>Because this is such a simple application, we won't be using scaffolding generators.</p>
<h2>About styled_obejcts</h2>
<p><a href="http://wiki.github.com/pgte/styled_objects">styled_objects</a> <strong> </strong>is a Rails plugin for simplifying stylesheet management on your application.</p>
<p>Instead of having one or more large stylesheets on your public folder, have many. Keep your <span>CSS</span> close to their respective templates. <strong>styled_objects</strong> will compile them into one file per page.</p>
<h2>Getting started</h2>
<p>1. Bootstrap your Rails app</p>
<pre>$ rails testapp</pre>
<p>2. Install the LESS gem:</p>
<p>Edit your config/environment.rb and place, anywhere before the "end":</p>
<pre class="brush: ruby;">config.gem 'less'</pre>
<p>Run on the shell:</p>
<pre>$ sudo rake gems:install</pre>
<p>2. install the styled_objects plugin</p>
<pre>script/plugin install git://github.com/pgte/styled_objects.git</pre>
<h2>The application</h2>
<p>Here we will be building a simple example application for an e-commerce website.<br />
First we will be focusing on building the controllers and the views, and finally we will learn how to style them with styled_objects.</p>
<p>To start we will be having products and product categories. One product can be in many categories and one category can contain many products. So, it is a many-to-many relationship.</p>
<p>For the sake of simplicity, let's say a product has a name and a description.</p>
<p>Each category have a name.</p>
<p>(I won't go through the building of the models, it's beyond the scope of this tutorial).</p>
<h3>Product page</h3>
<p>After you have your migrations and models setup, we need to configure the routes for our products controller.</p>
<p>Edit your config/routes.rb and add:</p>
<pre class="brush: ruby;">map.resources :products</pre>
<p>Now build the controller under app/controllers/products_controller.rb. For now we will only have a "show" action:</p>
<pre class="brush: ruby;">
class ProductsController &lt; ApplicationController

  def show
    @product = Product.find(params[:id])
  end

end
</pre>
<p>Do the show template  under app/views/products/show.html.erb:</p>
<pre class="brush: ruby;">
&lt;h1&gt;&lt;%= h @product.name %&gt;&lt;/h1&gt;
&lt;p&gt;&lt;%= h @product.description %&gt;&lt;/p&gt;
</pre>
<h3>Category page</h3>
<p>On this page we will be presenting all products on the current category.</p>
<p>Build the product category routes ou config/routes.rb:</p>
<pre class="brush: ruby;">
config.resources :categories
</pre>
<p>Next, build the controller under app/controllers/categories_controller.rb:</p>
<pre class="brush: ruby;">
class CategoriesController &lt; ApplicationController

  def show
    @category = Product.find(params[:id], :include =&gt; :products)
  end

end
</pre>
<p>And the view under app/views/categories/show.html.erb:</p>
<pre class="brush: ruby;">
&lt;h1&gt;&lt;%= h @category.name%&gt;&lt;/h1&gt;

&lt;p&gt;products in this category:&lt;/p&gt;

&lt;%= render :partial =&gt; 'products/product', :collection =&gt; @category.products %&gt;
</pre>
<p>This template is a bit more complex than the product show one because it presents all the products inside the current category by calling the <em>products/_product.html.erb</em> partial for each product.</p>
<p>Let's do this partial (under app/views/products/_product.html.erb):</p>
<pre class="brush: ruby;">
&lt;h2&gt;&lt;%= link_to h(product.name), product_path(product) %&gt;&lt;/h2&gt;
&lt;p&gt;&lt;%= h truncate(product.description) %&gt;&lt;/p&gt;
</pre>
<p>Here, instead of presenting the full product description, we truncate it using the ActionView truncate helper, presenting only the first 30 characters of the product description.</p>
<h2>Styling up</h2>
<p>So, now that we have the category and product pages in place, we need to style them.</p>
<p>But first we need to style the whole website.</p>
<h3>Global styling</h3>
<p>Personally, I feel comfortable with using this folloing setup when starting a website, but it is not a requirement for styled_objects. (We haven't got there yet).</p>
<h4>Reset stylesheet</h4>
<p>There are numerous reset stylesheets out there. I particulary like the one bundled inside blueprint CSS.</p>
<p>So, <a href="http://www.blueprintcss.org/">grab a copy of blueprint</a> and extract the <em>blueprint/src/reset.css</em> file and copy it into <em>public/stylesheets/</em> directory.</p>
<p>Next, edit your <em>app/views/layouts/application.html.erb</em> and add the following line before the &lt;/head&gt; tag:</p>
<pre class="brush: xml;">

&lt;%= stylesheet_link_tag 'reset' %&gt;
</pre>
<h4>Typography sytlesheet</h4>
<p>This is where we add a special stylesheet only for defining your typography. This is where you will be styling your p, a, ul, li, table, etc. tags.</p>
<p>This is your job, but I like to start from the blueprint/src/typography.css bundled on blueprint.</p>
<p>Save this file into public/stylesheets and add the respective the stylesheet link tag right after the reset one:</p>
<pre class="brush: xml;">
&lt;%= stylesheet_link_tag 'reset' %&gt;
&lt;%= stylesheet_link_tag 'typography' %&gt;
</pre>
<p>This stylesheet you will be formatting according to the desired look of your website.</p>
<h4>Layout stylesheet</h4>
<p>Before building a layout stylesheet, you need to build your layout markup. This will be done inside <em>app/layouts/application.html.erb</em> :</p>
<pre class="brush: php;">
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot; /&gt;
		&lt;title&gt;Untitled Document&lt;/title&gt;
		&lt;%= javascript_include_tag 'jquery-1.3.2.min' %&gt;
		&lt;%= stylesheet_link_tag 'reset' %&gt;

	&lt;/head&gt;
	&lt;body&gt;
      &lt;div class=&quot;container&quot;&gt;
        &lt;div id=&quot;header&quot;&gt;&lt;h1&gt;Welcome to ACME&lt;/h1&gt;&lt;/div&gt;
        &lt;div id=&quot;main&quot;&gt;
          &lt;%= yield %&gt;
        &lt;/div&gt;
      &lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>So, on inside our HTML body tag we have a div tag with a "container" class. This "container" class will be used to center and fix the width of our content.</p>
<p>This is what goes inside the layout stylesheet, under public/stylesheets/layout.css:</p>
<pre class="brush: css;">
.container {
  width: 950px;
  margin: 0 auto;
}
</pre>
<p>So, we are setting the width of content area of our website and centering it.</p>
<p>A lot more could be done here, like styling the <em>header</em> div. This also should be done on the layout stylesheet.</p>
<p>The main idea here is: <strong>use the layout stylesheet to only style markup on the layout template. Don't style more than that here</strong>.</p>
<h3>Local styling</h3>
<p>Now we want to style our templates and partials individually. That's where styled_objects comes in.</p>
<p>This plugin allows you to define the styles per template or partial wiathout adding any code.</p>
<p>First we need to call this helper on the <em>app/views/layouts/application.html.erb</em> file:</p>
<pre class="brush: ruby;">&lt;%= so_stylesheet_link_tag %&gt;</pre>
<p>Place it right before the &lt;/head&gt; tag. This helper creates the link tag to the URL for the "glued" stylesheet of each page.</p>
<p>We now begin with the product show page.</p>
<p>Create app/views/products/show.css and edit it.</p>
<p>We want to style the title and the description:</p>
<pre class="brush: css;">background-color: #e0e0e0;
h1 {color: #f576d8; border-bottom: 1px solid #822321};
p {padding: 1em 0; background-color: #fff;, border-top: 1px solid #d6d6d6}
</pre>
<p>On the first line we see something that isn't pure CSS: the background color style declared on the root of the CSS document. That's there because we are styling the <em>show.html.erb</em> template, not any sub node.</p>
<p>Now we want to style the product category page.</p>
<p>Create <em>app/views/categories/show.css</em>:</p>
<pre class="brush: css;">
border-top: 5px solid black;
background-color: #f7f7f7;
h1 {letter-spacing: -2px; color: #3e3e3e}
</pre>
<p>Here we're giving the category show template a top border (line 1), a background-color (line 2) and we're also styling the title on line 3.</p>
<p>This category show template also shows the products and for that it uses the <em>products/_product.html.erb</em> partial.</p>
<p>We also wish to style this partial. Create the file <em>app/views/products/_product.css</em>:</p>
<pre class="brush: css;">background-color: #999;
border: 1px solid #333;
float: left;
h2 {text-transform: uppercase}
</pre>
<h3>AJAX loading</h3>
<p>So, styled_objects collects the needed CSS fragments on each page and constructs one URL that references all the "glued" CSSes.</p>
<p>What if I want to have a shopping basket partial that is called by AJAX instead of normal partial rendering inside a template?</p>
<p>Simple: just add &lt;%= so_include_partial(partial_path) %&gt; (or &lt;%= so_include_template(template_path) %&gt; if it's a template) to anywhere on the calling template. The partial CSS will be included.</p>
<p>Next: <a href="http://www.metaduck.com/2009/10/tutorial-advanced-styled-objects-on-rails/">See the Advanced styled_objects on Rails Tutorial</a></p>
<h2>More</h2>
<p>Read more about object-oriented CSS here:</p>
<ul>
<li><a href="http://wiki.github.com/stubbornella/oocss">Object-oriented CSS by stubbornella</a></li>
</ul>
<p>See the presentation video:</p>
<ul>
<li><a href="http://www.stubbornella.org/content/2009/03/23/object-oriented-css-video-on-ydn/">Object-oriented CSS by stubbornella</a></li>
</ul>
<h2>Other resources</h2>
<ul>
<li><a href="http://lesscss.org/docs.html">LESS syntax</a></li>
<li><a href="http://wiki.github.com/pgte/styled_objects">styled_objects Rails plugin</a></li>
<li><a href="http://www.blueprintcss.org/">blueprint CSS framework</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2009/10/tutorial-building-and-styling-a-rails-app-with-styled-objects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>styled_objects Rails plugin</title>
		<link>http://www.metaduck.com/2009/10/styled_objects-rails-plugin/</link>
		<comments>http://www.metaduck.com/2009/10/styled_objects-rails-plugin/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 13:38:13 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.metaduck.com/?p=84</guid>
		<description><![CDATA[Yesterday I released the styled_objects Rails plugin.
styled_objects is a Rails plugin for simplifying stylesheet management on your application.
Instead of having one or more large stylesheets on your public folder, have many. Keep your CSS close to their respective templates. styled_objects will compile them into one file per page.
Why do I need styled_objects?
Because It’s hard to [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I released the styled_objects Rails plugin.</p>
<p><strong>styled_objects</strong> is a Rails plugin for simplifying stylesheet management on your application.</p>
<p><span id="more-84"></span>Instead of having one or more large stylesheets on your public folder, have many. Keep your <span>CSS</span> close to their respective templates. <strong>styled_objects</strong> will compile them into one file per page.</p>
<h2>Why do I need <strong>styled_objects</strong>?</h2>
<p>Because It’s hard to keep order on your application. Having one or many big stylesheet files is not easy. It’s hard do build, maintain and debug.</p>
<p>Do object-oriented stylesheets. Each presentation object has its own style definitions. With styled_objects everything is where expected.</p>
<p>You also make your stylesheets independent from each other, making it easier to find problems extend your app.</p>
<p><a href="http://www.slideshare.net/stubbornella/object-oriented-css">» Check out this presentation for a full pitch on <span>OOCSS</span> (Object-Oriented <span>CSS</span>).</a></p>
<p><a href="Check out http://wiki.github.com/pgte/styled_objects">Check out http://wiki.github.com/pgte/styled_objects</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2009/10/styled_objects-rails-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails cache in distributed environment</title>
		<link>http://www.metaduck.com/2009/10/rails-cache-in-distributed-environment/</link>
		<comments>http://www.metaduck.com/2009/10/rails-cache-in-distributed-environment/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 10:01:55 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://localhost/metaduck/?p=22</guid>
		<description><![CDATA[Page and fragment caching are life-savers for Rails application scalability. Specially for page cache, they can make your app fast, specially if you use a webserver like Nginx, serving static files directly without touching the Rails stack.
But maintaining cache consistency across a distributed Rails application can be challenging.

When page caching, Rails writes page result in [...]]]></description>
			<content:encoded><![CDATA[<p>Page and fragment caching are life-savers for Rails application scalability. Specially for page cache, they can make your app fast, specially if you use a webserver like <a href="http://nginx.net/">Nginx</a>, serving static files directly without touching the Rails stack.</p>
<p>But maintaining cache consistency across a distributed Rails application can be challenging.</p>
<p><span id="more-22"></span></p>
<p>When page caching, Rails writes page result in a static file on the public folder (when using the default options), allowing the web server to serve it directly.</p>
<h2>Expiring cache</h2>
<p>Cache expiration must be done explicitly by your app using the <a href="http://guides.rubyonrails.org/caching_with_rails.html">expire_page command</a>. This should be done when changes are made to your model (creations, deletions and updates), and should affect one or more pages, depending on your app. The cache expiration should be placed on model sweepers, as <a href="http://guides.rubyonrails.org/caching_with_rails.html#sweepers">explained here</a>.</p>
<h2>Distributed environment</h2>
<p>What about whenu  you are using more than one box for serving your Rails app? When one box calls ethe expire page command, it only cleans the local cache, rendering the other boxes cache remain inconsistent.</p>
<h2>Solutions</h2>
<p>There are several solutions to this. Let's look at them:</p>
<h3>1. dRb cache store</h3>
<p>dRb (or distributed Ruby) cache store uses a singleton process to communicate your cache decisions. This is not a good solution because:</p>
<ul>
<li>there is a single point of failure: the dRb process</li>
<li>web servers generally can't talk to dRb. even if they could, serving static files locally is much faster</li>
</ul>
<h3>2. Memcache Store</h3>
<p>Using a <a href="http://www.danga.com/memcached/">memcached</a> service is one good solution. Memcached can be use clustering and load balancing, and it is pretty fast. But, if you are using a distributed Rails environment mainly for the sake of redundancy, or don't want to complicate the environment setup, don't use memcache store.</p>
<h3>3. Cron-based expiration</h3>
<p>You can expire cache on a scheduled basis. This can be enough for some applications. But for some, specially when you have to keep a tight  cache consistency, this is not enough</p>
<h2>4. Build your own distributed cache cleaning</h2>
<p>In this solution, your model cache sweepers are responsible for cleaning the cache (deleting page cache files) on the other machines.</p>
<p>But how does one machine contact the other machines?</p>
<p>One solution I came up with envolves every machine having a Mongrel server listening on a public TCP port. (When I say public,. mean accessible to the other machines on the cluster. This is not a service that you  want to be public on the internet) .</p>
<p>This HTTP service is there just to listen to cache expiration events. It accepts, as arguments, the paths of the page cache</p>
<h3>Security concerns</h3>
<p>This service can be implemented on your Rails app, but it should not be accessible to</p>
<h2>Drawbacks</h2>
<p>There are several problems with this aproach:</p>
<h3>1. Every machine must know each other</h3>
<p>In order for one machine to contact each other when expiration must occur, every machine must know the other machines. This can be challenging using Rails config, but can be done in Capistrano tasks.</p>
<h3>2. It does not scale well</h3>
<p>Every time you add a machine you are increasing the cache expiration cost.</p>
<h3>3. Fault tolerance</h3>
<p>When you expire a cache page, you must contact EVERY other box. If the cache expiration service of one box is down, the cache expiration will fail. Error handling must be done carefully, having a fall-back mechanism like putting the cache expiration command on a queue.</p>
<h2>A better solution</h2>
<p>One better solution is to make cache expiration events ASYNCHRONOUS. When expiring a page, an event is triggered, and every other box is listening on this channel.</p>
<p>This can be achieved using UDP broadcasts, and having every box listening on this UDP port.</p>
<h3>Drawbacks (again)</h3>
<p>A fall-back mechanism must be in place, though, in case one box is down during the cache expiration event, rendering the cache inconsistent.</p>
<p>This can be done using some kind of persistent message queue instead of UDP broadcasts, but I think this can be an overkill for most applications.</p>
<p>Expect to hear from me soon regarding the implementation of this solution!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2009/10/rails-cache-in-distributed-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capistrano deploying full text search on Rails using acts_as_xapian</title>
		<link>http://www.metaduck.com/2009/09/capistrano-deploying-full-text-search-on-rails-using-acts_as_xapian/</link>
		<comments>http://www.metaduck.com/2009/09/capistrano-deploying-full-text-search-on-rails-using-acts_as_xapian/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 10:35:22 +0000</pubDate>
		<dc:creator>Pedro Teixeira</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[xapian]]></category>

		<guid isPermaLink="false">http://www.metaduck.com/?p=52</guid>
		<description><![CDATA[acts_as_xapian is a rails plugin for Xapian, a full text search engine.
acts_as_xapian installs the search engine database inside the plugin directory, under xapiandbs. If you use Capistrano as a deployment tool and since the entire codebase is rewritten (including the plugin directory),  you will have to rebuild the entire index every time you do a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/frabcus/acts_as_xapian">acts_as_xapian</a> is a rails plugin for <a href="http://xapian.org/">Xapian</a>, a full text search engine.</p>
<p>acts_as_xapian installs the search engine database inside the plugin directory, under xapiandbs. If you use <a href="http://www.capify.org/">Capistrano</a> as a deployment tool and since the entire codebase is rewritten (including the plugin directory),  you will have to rebuild the entire index every time you do a deployment.</p>
<p><span id="more-52"></span>What you need to do is to locate Xapian somewhere capistrano deployments will not overwrite.</p>
<p>Fortunately you can point the Xapian DB to somewhere else more convenient. Simply create a file under config/xapian.yml. Mine looks like this:</p>
<pre><code>
development:
  base_db_path: xapian/database
staging:
  base_db_path: xapian/database
production:
  base_db_path: xapian/database
</code></pre>
<p>This is telling xapian on the development, staging and production environments to look for the database under the &lt;RAILS_ROOT&gt;/xapian/database.</p>
<p>You will have to create a folder under the deployment shared folder named "xapian/database".</p>
<p>Next you will have to tell Capistrano to relink &lt;RAILS_ROOT&gt;/xapian/database to this shared directory using a Capistrano hook:</p>
<pre><code>
after "deploy:symlink", "deploy:symlink_xapian_db"

...

namespace :deploy do

...

  task :symlink_xapian_db do
    xapian_database_path = 'xapian/database'
    run "mkdir -p #{shared_path}/#{xapian_database_path}"
    run "ln -sf  #{shared_path}/xapian #{release_path}/xapian"
  end

end
</code></pre>
<p>You will only have to build the index once using</p>
<pre><code>'rake xapian:rebuild_index models="ModelName1 ModelName2"'</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.metaduck.com/2009/09/capistrano-deploying-full-text-search-on-rails-using-acts_as_xapian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
