<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text" xml:lang="en">WyeWorks Blog - The Team's Voice</title>
  <link type="application/atom+xml" href="http://blog.wyeworks.com/feed/" rel="self" />
  <link type="text" href="http://blog.wyeworks.com/" rel="alternate" />
  <updated>2013-03-18T18:59:06+00:00</updated>
  <id>http://blog.wyeworks.com/</id>
  
  <entry>
    <title>Rails 4 links compilation</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2012/11/13/rails-4-compilation-links/"/>
    <updated>2012-11-13T00:00:00+00:00</updated>
    <id>http://blog.wyeworks.com/2012/11/13/rails-4-compilation-links/</id>
    <content type="html"><![CDATA[<p>I'm leaving here a curated compilation of interesting links where you will find information that is not very well known. There are pull requests, issues, commits, examples, posts, videos and more about Rails 4.</p>

<p>I'm also giving a shout out asking for improvements to this compilation. If you find something is missing or you have suggestions to make let me know by commenting in this post.</p>

<p>The Rails Guides are not always enough. When you don't find something in the guides or docs, you probably search for information on the internet or a blog post about the specific subject. But wouldn't it be better if you had all the related information together? This could also be a great starting point for a new Rails guide.</p>

<p>So, I encourage everyone to help compiling more material about each new section of Rails 4 and then, by looking at all this compilation, start guides about specific topics. You can do that by directly pushing to <a href="http://github.com/lifo/docrails">docrails</a>, which has public access for everyone to push documentation changes only.</p>

<p><a href="/images/posts/Rails4-4.png"><img src="/images/posts/Rails4-mini-4.png" title="Rails 4
MindNode" alt="Rails 4 MindNode" /></a></p>

<h2>Overview</h2>

<ul>
<li><a href="http://edgeguides.rubyonrails.org/4_0_release_notes.html">Ruby on Rails Guides: Rails 4.0 Release Notes</a></li>
<li><a href="http://blog.wyeworks.com/2012/10/29/rails-4-in-30-minutes/">Rails 4 in 30'</a></li>
<li><a href="http://vimeo.com/51898266">Why should I care about Rails 4</a></li>
<li><a href="http://confreaks.com/videos/1228-aloharuby2012-keynote-rails-4-and-the-future-of-web">Rails 4 and the Future of Web</a></li>
<li><a href="http://vimeo.com/51181496">Rails 4 Whirlwind Tour</a></li>
<li><a href="http://bostonrb.org/presentations/what-to-expect-in-rails-40">BostonRB: what to expect in Rails 4.0</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/11/rails-4-countdown-to-2013">Rails 4 Countdown to 2013</a></li>
</ul>


<h2>Upgrade</h2>

<ul>
<li>Ruby 1.9.3

<ul>
<li><a href="https://github.com/rails/rails/commit/4fa615a8661eb13d4bd8a7de4d839e9883ef26ec">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/rails-4-requires-at-least-ruby-1-9-3-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Rails 4 requires at least Ruby 1.9.3</a></li>
</ul>
</li>
<li>New deprecation policy

<ul>
<li><a href="http://weblog.rubyonrails.org/2012/8/9/ann-rails-3-2-8-has-been-released/">Weblog Post mentions deprecation policy</a></li>
</ul>
</li>
<li>vendor/plugins has gone

<ul>
<li><a href="https://github.com/rails/rails/commit/dad7fdc5734a3813246f238ac5760b2076932216">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/rails-plugin-reaches-end-of-life-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Rails::Plugin reaches end of life</a></li>
</ul>
</li>
<li>Moved to a plugin

<ul>
<li>Hash-based &amp; Dynamic finder methods

<ul>
<li><a href="https://github.com/rails/activerecord-deprecated_finders">Gem</a></li>
</ul>
</li>
<li>Mass assignment in AR models

<ul>
<li><a href="https://github.com/rails/protected_attributes">Gem</a></li>
</ul>
</li>
<li>ActiveRecord::SessionStore

<ul>
<li><a href="https://github.com/rails/activerecord-session_store">Gem</a></li>
<li><a href="https://github.com/rails/rails/commit/0ffe19056c8e8b2f9ae9d487b896cad2ce9387ad">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/activerecord-sessionstore-gem-extraction-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - ActiveRecord::SessionStore Gem Extraction</a></li>
</ul>
</li>
<li>ActiveResource

<ul>
<li><a href="https://github.com/rails/activeresource">Gem</a></li>
<li><a href="http://yetimedia.tumblr.com/post/35233051627/activeresource-is-dead-long-live-activeresource">ActiveResource is dead, long live ActiveResource</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/activeresource-gem-extraction-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - ActiveResource Gem Extraction</a></li>
</ul>
</li>
<li>Action Caching

<ul>
<li><a href="https://github.com/rails/actionpack-action_caching">Gem</a></li>
</ul>
</li>
<li>Page Caching

<ul>
<li><a href="https://github.com/rails/actionpack-page_caching">Gem</a></li>
</ul>
</li>
<li>Page and Action Caching

<ul>
<li><a href="http://blog.remarkablelabs.com/2012/12/page-caching-action-caching-gem-extraction-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Page and Action Caching Gem Extraction</a></li>
</ul>
</li>
<li>New default test locations

<ul>
<li><a href="https://github.com/rails/rails/pull/7878">Pull Request</a></li>
</ul>
</li>
<li>Observers

<ul>
<li><a href="https://github.com/rails/rails-observers">Gem</a></li>
<li><a href="https://github.com/rails/rails/commit/ccecab3ba950a288b61a516bf9b6962e384aae0b">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/observers-gem-extraction-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Observers Gem Extraction</a></li>
</ul>
</li>
</ul>
</li>
</ul>


<h2>Active Support</h2>

<ul>
<li>Queue API (NOTE: This was reverted and will be included in Rails 4.1)

<ul>
<li><a href="https://github.com/rails/rails/commit/adff4a706a5d7ad18ef05303461e1a0d848bd662">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/rails-queue-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Rails.queue</a></li>
</ul>
</li>
<li>Notifiers start &amp; finish

<ul>
<li><a href="https://github.com/rails/rails/compare/60736fe...c7847f1">Commits</a></li>
</ul>
</li>
<li>Dalli replaces memcache-client

<ul>
<li><a href="http://blog.remarkablelabs.com/2012/12/dalli-replaces-memcache-client-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Dalli replaces memcache-client</a></li>
</ul>
</li>
</ul>


<h2>Action Mailer</h2>

<ul>
<li>Asynchronous Mailer (NOTE: This was reverted and will be included in Rails 4.1)

<ul>
<li><a href="https://github.com/rails/rails/pull/6839">Pull Request</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/asynchronous-action-mailer-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Asynchronous Action Mailer</a></li>
</ul>
</li>
</ul>


<h2>Active Model</h2>

<ul>
<li>ActiveModel::Model

<ul>
<li><a href="http://blog.plataformatec.com.br/2012/03/barebone-models-to-use-with-actionpack-in-rails-4-0/">Plataforma: barebone models to use with actionpack in rails 4.0</a></li>
<li><a href="https://github.com/rails/rails/commit/3b822e91d1a6c4eab0064989bbd07aae3a6d0d08">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/activemodel-model-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - ActiveModel::Model</a></li>
</ul>
</li>
<li>ActiveModel Validator

<ul>
<li><a href="http://blog.remarkablelabs.com/2012/12/activemodel-absence-validator-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - ActiveModel Absence Validator</a></li>
</ul>
</li>
</ul>


<h2>Action Pack</h2>

<ul>
<li>ActionController::Live

<ul>
<li><a href="http://tenderlovemaking.com/2012/07/30/is-it-live.html">Aaron Patterson's blog post: Is it Live</a></li>
<li><a href="http://blog.phusion.nl/2012/08/03/why-rails-4-live-streaming-is-a-big-deal/">Why Rails 4 Live Streaming is a big deal</a></li>
<li><a href="https://github.com/rails/rails/commit/af0a9f9eefaee3a8120cfd8d05cbc431af376da3">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/live-streaming-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Live Streaming</a></li>
</ul>
</li>
<li>Strong parameters

<ul>
<li><a href="https://github.com/rails/strong_parameters">Gem</a></li>
<li><a href="http://iconoclastlabs.com/cms/blog/posts/upgrading-to-rails-4-parameters-security-tour">Parameters Security Tour</a></li>
<li><a href="http://weblog.rubyonrails.org/2012/3/21/strong-parameters/">Ruby on Rails Weblog: Strong parameters</a></li>
<li><a href="http://rubysource.com/rails-4-quick-look-strong-parameters/">Rails 4 Quick Look: Strong Parameters</a></li>
<li><a href="https://github.com/rails/rails/pull/7251">Pull Request</a></li>
<li><a href="http://railscasts.com/episodes/371-strong-parameters">Railscast</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/strong-parameters-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Strong Parameters</a></li>
</ul>
</li>
<li>Turbolinks

<ul>
<li><a href="https://github.com/rails/turbolinks">Gem</a></li>
<li><a href="http://geekmonkey.org/articles/28-introducing-turbolinks-for-rails-4-0">Introducing Turbolinks for Rails 4.0 geekmonkey</a></li>
<li><a href="http://blog.steveklabnik.com/posts/2012-09-27-seriously--numbers--use-them-">Turbolinks benchmarks from Steve Klabnik</a></li>
<li><a href="http://railscasts.com/episodes/390-turbolinks">Railscast</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/turbolinks-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Turbolinks</a></li>
</ul>
</li>
<li>Russian Doll Caching

<ul>
<li><a href="http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works">How key-based cache expiration works</a></li>
<li><a href="http://www.youtube.com/watch?v=FkLVl3gpJP4#t=33m30s">Evening on Backbone.js/ Q&amp;A with dhh</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/russian-doll-caching-cache-digests-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Russian Doll Caching &amp; Cache Digests</a></li>
</ul>
</li>
<li>Cache Digests

<ul>
<li><a href="https://github.com/rails/cache_digests">Gem</a></li>
<li><a href="https://github.com/rails/rails/commit/502d5e24e28b3634910495d0fb71cb20b1426aee">Commit</a></li>
<li><a href="http://railscasts.com/episodes/387-cache-digests">Railscast</a></li>
</ul>
</li>
<li>Declarative ETags

<ul>
<li><a href="https://github.com/rails/etagger">Gem</a></li>
<li><a href="https://github.com/rails/rails/commit/ed5c938fa36995f06d4917d9543ba78ed506bb8d">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/generate-controller-wide-etags-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Generate Controller-Wide ETags</a></li>
</ul>
</li>
<li>Decouple Action Pack and Action View

<ul>
<li><a href="https://github.com/rails/rails/pull/7356">Pull Request</a></li>
</ul>
</li>
<li>Asset Pipelining

<ul>
<li><a href="http://yetimedia.tumblr.com/post/33320732456/moving-forward-with-the-rails-asset-pipeline">Moving forward with the Rails asset pipeline</a></li>
<li>sprockets-rails

<ul>
<li><a href="https://github.com/rails/sprockets-rails">Gem</a></li>
<li><a href="https://github.com/rails/rails/pull/5409">Extraction</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/sprockets-rails-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Sprockets Rails</a></li>
</ul>
</li>
</ul>
</li>
<li>Replace memcache-client with dalli

<ul>
<li><a href="https://github.com/rails/rails/pull/6903">Pull Request</a></li>
</ul>
</li>
<li>Routing Concerns

<ul>
<li><a href="https://github.com/rails/routing_concerns">Gem</a></li>
<li><a href="https://github.com/rails/rails/commit/0dd24728a088fcb4ae616bb5d62734aca5276b1b">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/routing-concerns-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Routing Concerns</a></li>
</ul>
</li>
<li>PATCH verb

<ul>
<li><a href="http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/">Weblog post</a></li>
<li><a href="https://github.com/rails/rails/issues/348">Rails issue: use PATCH verb instead of PUT</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/http-patch-verb-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - HTTP PATCH Verb</a></li>
</ul>
</li>
<li>Rename all action callbacks from *_filter to *_action

<ul>
<li><a href="https://github.com/rails/rails/commit/9d62e04838f01f5589fa50b0baa480d60c815e2c">Commit</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/renaming-_filter-to-_action-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Renaming *_filter to *_action</a></li>
</ul>
</li>
<li>Helpers

<ul>
<li><a href="https://github.com/rails/rails/pull/6359">HTML5 tag helpers - Pull Request</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/collection-form-helpers-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Collection Form Helpers</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/new-html5-form-input-helpers-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - New HTML5 Form Input Helpers</a></li>
</ul>
</li>
<li>Render default index page

<ul>
<li><a href="https://github.com/rails/rails/pull/8468">Pull Request</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/dynamic-index-html-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Dynamic index.html</a></li>
</ul>
</li>
<li>Register your flash types

<ul>
<li><a href="http://blog.remarkablelabs.com/2012/12/register-your-own-flash-types-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Register your own flash types</a></li>
<li><a href="https://github.com/rails/rails/commit/238a4253bf229377b686bfcecc63dda2b59cff8f">Commit</a></li>
</ul>
</li>
<li>New exceptions pages for development

<ul>
<li><a href="https://github.com/rails/rails/pull/8668">Pull Request</a></li>
</ul>
</li>
</ul>


<h2>Active Record</h2>

<ul>
<li>What's new

<ul>
<li><a href="http://blog.remarkablelabs.com/2012/12/what-s-new-in-active-record-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - What's new in Active Record</a></li>
</ul>
</li>
<li>MySQL strict mode by default

<ul>
<li><a href="https://github.com/rails/rails/pull/6069">Pull Request</a></li>
</ul>
</li>
<li>PostgreSQL support

<ul>
<li><a href="http://blog.remarkablelabs.com/2012/12/a-love-affair-with-postgresql-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - A love affair with PostgreSQL</a></li>
</ul>
</li>
<li>Support for array datatype in PostgreSQL

<ul>
<li><a href="http://reefpoints.dockyard.com/ruby/2012/09/18/rails-4-sneak-peek-postgresql-array-support.html">Rails 4.0 sneak peek: PostgreSQL array support</a></li>
<li><a href="https://github.com/rails/rails/pull/7547">Pull Request</a></li>
</ul>
</li>
<li>Support for MACADDR, INET, CIDR datatypes in PostgreSQL

<ul>
<li><a href="http://reefpoints.dockyard.com/ruby/2012/05/18/rails-4-sneak-peek-expanded-activerecord-support-for-postgresql-datatype.html">Rails 4.0 sneak peek: PostgreSQL MACADDR, INET, CIDR support</a></li>
</ul>
</li>
<li>Support for specifying transaction isolation level

<ul>
<li><a href="https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253">Commit</a></li>
</ul>
</li>
<li>Schema cache dump

<ul>
<li><a href="https://github.com/rails/rails/pull/5162">Pull Request</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/schema-cache-dump-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Schema Cache Dump</a></li>
</ul>
</li>
<li>ActiveRecord::Relation bang methods

<ul>
<li><a href="https://github.com/rails/rails/commit/8c2c60511beaad05a218e73c4918ab89fb1804f0">Commit</a></li>
</ul>
</li>
<li>ActiveRecord::Base.all returns a Relation

<ul>
<li><a href="https://github.com/rails/rails/commit/6a81ccd69d96f36f4322ef927191ab5a35e68d68">Commit</a></li>
</ul>
</li>
<li>Relation#find_or_create_by and friends

<ul>
<li><a href="https://github.com/rails/rails/commit/eb72e62c3042c0df989d951b1d12291395ebdb8e">Commit</a></li>
</ul>
</li>
<li>CollectionProxy#scope

<ul>
<li><a href="https://github.com/rails/rails/commit/0e1cafcbc4d67854faf35e489571bc30f5e2ac14">Commit</a></li>
</ul>
</li>
<li>Support for partial inserts

<ul>
<li><a href="https://github.com/rails/rails/commit/144e8691cbfb8bba77f18cfe68d5e7fd48887f5e">Commit</a></li>
</ul>
</li>
<li>Relation.where with no args can be chained with not

<ul>
<li><a href="https://github.com/rails/rails/pull/8332">Pull Request</a></li>
<li><a href="https://github.com/rails/rails/commit/8d02afeaee8993bd0fde69687fdd9bf30921e805">Revert of like and not_like</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/not-equal-support-for-active-record-queries-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Not Equal support for Active Record queries</a></li>
</ul>
</li>
<li>Add metadata to schema_migrations table

<ul>
<li><a href="https://github.com/rails/rails/pull/8399">Pull Request</a></li>
</ul>
</li>
<li>Rename update_attributes method to update, keep update_attributes as an alias

<ul>
<li><a href="https://github.com/rails/rails/commit/1f3a1fedf951dbc4b72d178e2a649c4afd2f1566">Commit</a></li>
</ul>
</li>
</ul>


<h2>Railties</h2>

<ul>
<li>Threadsafe on by default

<ul>
<li><a href="http://tenderlovemaking.com/2012/06/18/removing-config-threadsafe.html">Aaron Patterson's blog post</a></li>
<li><a href="https://github.com/rails/rails/pull/6685">Discusion of Tony Arcieri's Pull Request</a></li>
<li><a href="http://github.com/rails/rails/pull/7225">Improve eager load on Rails: Pull Request</a></li>
<li><a href="http://railscasts.com/episodes/365-thread-safety">Railscast</a></li>
<li><a href="http://blog.remarkablelabs.com/2012/12/rails-4-is-thread-safe-by-default-rails-4-countdown-to-2013">Rails 4 Countdown to 2013 - Rails 4 is thread safe by default</a></li>
</ul>
</li>
<li>Binstubs

<ul>
<li><a href="https://github.com/rails/rails/commit/f34c27a452418d8aa17f92bb0fd7ae97b5f7e252">Install binstubs by default</a></li>
<li><a href="https://github.com/rails/rails/commit/1e9d6e7b567c778baa884e7e569e67cdf5040119">Revert "Install binstubs by default"</a></li>
<li><a href="https://github.com/rails/rails/commit/61b91c4c55bcbd5a2ec85d6e1c67755150653dff">Revert "Ignore /bin on new apps" -- given the move to default binstubs, we want you to check those in!</a></li>
<li><a href="https://github.com/carlhuda/bundler/compare/17561867...885ed215">bundle binstubs &lt;gem></a>

<ul>
<li><a href="https://github.com/sstephenson/rbenv/wiki/Understanding-binstubs">Understanding binstubs</a></li>
</ul>
</li>
</ul>
</li>
<li>Add --no-html to scaffold generator

<ul>
<li><a href="https://github.com/rails/rails/commit/cb025f850c45f26355892961d5cf05145d247a4d">Commit</a></li>
</ul>
</li>
<li>Rails commands

<ul>
<li><a href="https://github.com/rails/commands">Commands</a></li>
<li><a href="https://github.com/jonleighton/spring">Spring</a></li>
</ul>
</li>
</ul>


<h2>Security</h2>

<ul>
<li>Default headers

<ul>
<li><a href="http://edgeguides.rubyonrails.org/security.html#default-headers">Security Guide's default headers</a></li>
</ul>
</li>
<li>match doesn't catch all

<ul>
<li><a href="https://github.com/rails/rails/commit/56cdc81c08b1847c5c1f699810a8c3b9ac3715a6">Commit</a></li>
</ul>
</li>
<li>Set escaping HTML in JSON encoding to true by default

<ul>
<li><a href="https://github.com/rails/rails/pull/6287">Pull Request</a></li>
</ul>
</li>
<li>Add ActiveSupport::KeyGenerator as a simple wrapper around PBKDF2

<ul>
<li><a href="https://github.com/rails/rails/pull/6952">Pull Request</a></li>
</ul>
</li>
<li>Encrypted Cookies + Sign using Derived Keys

<ul>
<li><a href="https://github.com/rails/rails/pull/8112">Pull Request</a></li>
</ul>
</li>
</ul>


<p>Please send me more information about Rails 4 if you find that I'm missing something in this post.</p>

<p>P.D.: Thanks to Nikolay Petrachkov who gave me a starting point for building this list and to Guillermo Iguaran who contributed reviewing and sharing some links too.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Rails 4 in 30&#39;</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2012/10/29/rails-4-in-30-minutes/"/>
    <updated>2012-10-29T18:45:00+00:00</updated>
    <id>http://blog.wyeworks.com/2012/10/29/rails-4-in-30-minutes/</id>
    <content type="html"><![CDATA[<p>I gave a presentation in <a href="http://rubyconfargentina.org/en">RubyConf Argentina</a> about what's new in Rails 4 (if you saw it please <a href="http://speakerrate.com/talks/17941-rails-4-en-30">rate it</a>). I've already posted the <a href="http://blog.wyeworks.com/2012/9/20/rails-4-in-a-mindnode/">Rails 4 MindNode</a> which I used to start to think about what I was going to present. The talk was in Spanish but I'm leaving here the English version of the slides.</p>

<p>If you want to use these slides to spread the word about what's new in Rails you don't need to ask me for permission, just feel free to use them and make the changes you want. I would appreciate a mention in your presentation and all the suggestions you may have for improving the slides and/or the mind map.</p>

<p>I still have to post the links I've collected of Rails 4 blog posts and commits to the Rails 4 MindNode post so keep checking it.</p>

<script async class="speakerdeck-embed"
data-id="508ecd4a06b6f70002001fb8" data-ratio="1.299492385786802"
src="//speakerdeck.com/assets/embed.js"></script>

]]></content>
  </entry>
  
  <entry>
    <title>Rails 4 in a MindNode</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2012/9/20/rails-4-in-a-mindnode/"/>
    <updated>2012-09-20T21:00:00+00:00</updated>
    <id>http://blog.wyeworks.com/2012/9/20/rails-4-in-a-mindnode/</id>
    <content type="html"><![CDATA[<p>I'll be talking at <a href="http://rubyconfargentina.org/en">RubyConf Argentina</a>,
and the first thing I usually do when preparing talks is to think in a
high level and then start going down form there. I find MindNode a great
tool for that. So I started checking what was being added, removed and
deprecated in Rails 4 (my memory isn't good enough to have all that in the
top of my head :P). The result is this MindNode I'm sharing with you …</p>

<p><a href="/images/posts/Rails4-4.png"><img src="/images/posts/Rails4-mini-4.png" title="Rails 4
MindNode" alt="Rails 4 MindNode" /></a></p>

<p>I could be missing some stuff or could even be things that won't make it to
Rails 4, but that's the picture as of today. If you find something that I'm
missing or that I should change please let me know. I will keep this
MindNode updated so keep checking it.</p>

<p><strong>UPDATE #1</strong>: <a href="https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253">Support for specifying transaction isolation
level</a></p>

<p><strong>UPDATE #2</strong>: <a href="https://github.com/rails/turbolinks/">Turbolinks</a></p>
]]></content>
  </entry>
  
  <entry>
    <title>Ruby Refinements landed in trunk</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2012/8/3/ruby-refinements-landed-in-trunk/"/>
    <updated>2012-08-03T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2012/8/3/ruby-refinements-landed-in-trunk/</id>
    <content type="html"><![CDATA[<p>Refinements arrived to Ruby trunk <a href="https://bugs.ruby-lang.org/issues/4085.">here</a> The purpose of Refinements is to make monkey patching safer, extending core classes but limiting its effects to a particular area of code.</p>

<p>Shugo Maeda wrote ...</p>

<pre><code>"Refinements are similar to Classboxes.  However, Refinements doesn't
support local rebinding as mentioned later.  In this sense,
Refinements might be more similar to selector namespaces, but I'm not
sure because I have never seen any implementation of selector
namespaces.

In Refinements, a Ruby module is used as a namespace (or classbox) for
class extensions.  Such class extensions are called refinements.  For
example, the following module refines Fixnum."</code></pre>


<p>You can read the long story here <a href="https://bugs.ruby-lang.org/issues/4085">https://bugs.ruby-lang.org/issues/4085</a></p>

<p>So let's see how Refinements work in practice</p>

<p>Basically instead of doing …</p>

<pre><code>class Object
  def blank?
    respond_to?(:empty?) ? empty? : !self
  end
end

puts "".blank?
puts "hi".blank?
puts nil.blank?
puts [].blank?
puts [1].blank?</code></pre>


<p>and polluting all the objects, you can do ...</p>

<pre><code>module Blank
  refine Object do
    def blank?
      respond_to?(:empty?) ? empty? : !self
    end
  end
end

class A
  using Blank

  puts "".blank?   # => true
  puts "hi".blank? # => false
  puts nil.blank?  # => true
  puts [].blank?   # => true
  puts [1].blank?  # => false
end</code></pre>


<p>and monkey patch in a controlled way. You can also check that you won't be polluting all the objects in your system by checking …</p>

<pre><code>class B
  puts "".blank?
  puts "hi".blank?
  puts nil.blank?
  puts [].blank?
  puts [1].blank?
end</code></pre>


<p>This will raise an undefined method `blank?' for <a href="String"></a> (NoMethodError).</p>

<p>Refinements has been committed to ruby by Shugo Maeda, but it may be reverted for Ruby 2.0. The Ruby Core is asking for feedback, so, what are the use cases you see Refinements is good for you?</p>

<p>You can learn more about Refinements reading <a href="http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/">Refinements in practice, a blog post from Yehuda Katz</a></p>
]]></content>
  </entry>
  
  <entry>
    <title>Rails for API applications (rails-api) released</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2012/4/20/rails-for-api-applications-rails-api-released/"/>
    <updated>2012-04-20T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2012/4/20/rails-for-api-applications-rails-api-released/</id>
    <content type="html"><![CDATA[<p><strong><a href="https://github.com/spastorino/rails-api">rails-api</a></strong> is a plugin developed by Yehuda Katz, José Valim, Carlos Antonio da Silva and me (Santiago Pastorino) which modifies Rails applications trimming down usually unneeded Rails functionalities for API applications.
Do you remember we added support for this on core and <a href="https://github.com/rails/rails/commit/6db930cb5bbff9ad824590b5844e04768de240b1">it was reverted</a>?. This plugin enables that again.</p>

<h3>What is an API app?</h3>

<p>Traditionally, when people said that they used Rails as an "API", they meant providing a programmatically accessible API alongside their web application. For example, GitHub provides <a href="http://developer.github.com/">an API</a> that you can use from your own API clients.</p>

<h3>Why using this instead of Rails?</h3>

<p>Because you don't need the entire Rails middleware stack. Specifically you won't need middleware that are meant for browser applications. For example you probably won't need cookies support, but you can add that back if you want. You don't need most of the functionality provided by ActionController::Base like template generation for instance. And you won't need generated views, helpers and assets. The plugin also skips the asset pipelining.</p>

<h3>Configuration</h3>

<h4>For existing Rails applications you need …</h4>

<ol>
<li>To add gem 'rails-api' to your Gemfile</li>
<li>Make <em>ApplicationController</em> inherit from <em>ActionController::API</em> instead of <em>ActionController::Base</em>. As with middleware, this will leave out any <em>ActionController</em> module that provides functionality primarily used by browser applications.</li>
<li>Remove respond_to from your controllers and just use render :json instead.</li>
</ol>


<h4>For new apps</h4>

<p>Install the gem if you haven't already:</p>

<pre><code>gem install rails-api
</code></pre>

<p>Then generate a new <strong>Rails API</strong> application:</p>

<pre><code>rails-api new my_api
</code></pre>

<p>And that's it, when you use the generators by default controllers will respond to json only.</p>

<h3>Middlewares</h3>

<p>An api application comes with the following middlewares by default.</p>

<ul>
<li><em>Rack::Cache</em>: Caches responses with public <em>Cache-Control</em> headers using HTTP caching semantics.</li>
<li><em>Rack::Sendfile</em>: Uses a front-end server's file serving support from your Rails application.</li>
<li><em>Rack::Lock</em>: If your application is not marked as threadsafe (<code>config.threadsafe!</code>), this middleware will add a mutex around your requests.</li>
<li><em>ActionDispatch::RequestId</em></li>
<li><em>Rails::Rack::Logger</em></li>
<li><em>Rack::Runtime</em>: Adds a header to the response listing the total runtime of the request.</li>
<li><em>ActionDispatch::ShowExceptions</em>: Rescue exceptions and re-dispatch them to an exception handling application.</li>
<li><em>ActionDispatch::DebugExceptions</em>: Log exceptions.</li>
<li><em>ActionDispatch::RemoteIp</em>: Protect against IP spoofing attacks.</li>
<li><em>ActionDispatch::Reloader</em>: In development mode, support code reloading.</li>
<li><em>ActionDispatch::ParamsParser</em>: Parse XML, YAML and JSON parameters when the request's <em>Content-Type</em> is one of those.</li>
<li><em>ActionDispatch::Head</em>: Dispatch <em>HEAD</em> requests as <em>GET</em> requests, and return only the status code and headers.</li>
<li><em>Rack::ConditionalGet</em>: Supports the <code>stale?</code> feature in Rails controllers.</li>
<li><em>Rack::ETag</em>: Automatically set an <em>ETag</em> on all string responses. This means that if the same response is returned from a controller for the same URL, the server will return a <em>304 Not Modified</em>, even if no additional caching steps are taken. This is primarily a client-side optimization; it reduces bandwidth costs but not server processing time.</li>
</ul>


<p>Other plugins, including <em>ActiveRecord</em>, may add additional middlewares. In general, these middlewares are agnostic to the type of app you are building, and make sense in an API-only Rails application.</p>

<p>You can get a list of all middlewares in your application via:</p>

<pre><code>rake middleware
</code></pre>

<h4>Other Middlewares</h4>

<p>Rails ships with a number of other middlewares that you might want to use in an API app, especially if one of your API clients is the browser:</p>

<ul>
<li><em>Rack::MethodOverride</em>: Allows the use of the <em>_method</em> hack to route POST requests to other verbs.</li>
<li><em>ActionDispatch::Cookies</em>: Supports the <em>cookie</em> method in <em>ActionController</em>, including support for signed and encrypted cookies.</li>
<li><em>ActionDispatch::Flash</em>: Supports the <em>flash</em> mechanism in <em>ActionController</em>.</li>
<li><em>ActionDispatch::BestStandards</em>: Tells Internet Explorer to use the most standards-compliant available renderer. In production mode, if ChromeFrame is available, use ChromeFrame.</li>
<li>Session Management: If a <em>config.session_store</em> is supplied, this middleware makes the session available as the <em>session</em> method in <em>ActionController</em>.</li>
</ul>


<p>Any of these middlewares can be added via:</p>

<pre><code>config.middleware.use Rack::MethodOverride
</code></pre>

<h4>Removing Middlewares</h4>

<p>If you don't want to use a middleware that is included by default in the api middleware set, you can remove it using <em>config.middleware.delete</em>:</p>

<pre><code>config.middleware.delete ::Rack::Sendfile
</code></pre>

<p>Keep in mind that removing these features may remove support for certain features in <em>ActionController</em>.</p>

<h3>Choosing Controller Modules</h3>

<p>An api application (using <em>ActionController::API</em>) comes with the following controller modules by default:</p>

<ul>
<li><em>ActionController::UrlFor</em>: Makes <em>url_for</em> and friends available</li>
<li><em>ActionController::Redirecting</em>: Support for <em>redirect_to</em></li>
<li><em>ActionController::Rendering</em>: Basic support for rendering</li>
<li><em>ActionController::Renderers::All</em>: Support for <em>render :json</em> and friends</li>
<li><em>ActionController::ConditionalGet</em>: Support for <em>stale?</em></li>
<li><em>ActionController::ForceSSL</em>: Support for <em>force_ssl</em></li>
<li><em>ActionController::RackDelegation</em>: Support for the <em>request</em> and <em>response</em> methods returning <em>ActionDispatch::Request</em> and <em>ActionDispatch::Response</em> objects.</li>
<li><em>ActionController::DataStreaming</em>: Support for <em>send_file</em> and <em>send_data</em></li>
<li><em>AbstractController::Callbacks</em>: Support for <em>before_filter</em> and friends</li>
<li><em>ActionController::Instrumentation</em>: Support for the instrumentation hooks defined by <em>ActionController</em> (see <a href="https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/instrumentation.rb">the source</a> for more).</li>
<li><em>ActionController::Rescue</em>: Support for <em>rescue_from</em>.</li>
</ul>


<p>Other plugins may add additional modules. You can get a list of all modules included into <em>ActionController::API</em> in the rails console:</p>

<pre><code>ActionController::API.ancestors - ActionController::Metal.ancestors
</code></pre>

<h4>Adding Other Modules</h4>

<p>All Action Controller modules know about their dependent modules, so you can feel free to include any modules into your controllers, and all dependencies will be included and set up as well.</p>

<p>Some common modules you might want to add:</p>

<ul>
<li><em>AbstractController::Translation</em>: Support for the <em>l</em> and <em>t</em> localization and translation methods. These delegate to <em>I18n.translate</em> and <em>I18n.localize</em>.</li>
<li><em>ActionController::HTTPAuthentication::Basic</em> (or <em>Digest</em> or <em>Token</em>): Support for basic, digest or token HTTP authentication.</li>
<li><em>AbstractController::Layouts</em>: Support for layouts when rendering.</li>
<li><em>ActionController::MimeResponds</em>: Support for content negotiation (<em>respond_to</em>, <em>respond_with</em>).</li>
<li><em>ActionController::Cookies</em>: Support for <em>cookies</em>, which includes support for signed and encrypted cookies. This requires the cookie middleware.</li>
</ul>


<p>The best place to add a module is in your <em>ApplicationController</em>. You can also add modules to individual controllers.</p>

<h3>How can I help?</h3>

<p>Go to the project url <a href="https://github.com/spastorino/rails-api">https://github.com/spastorino/rails-api</a> and report issues, test it in real apps and provide bug fixes. We have been measuring the plugin against some applications and we will post more about the results later. Meanwhile, if you can test it and share the improvements you found in your apps, would be awesome. To be able to add this functionality to core we need the plugin to show significant performance improvements for real API applications, so it's important to let us know about your results.</p>

<p>&lt;3 &lt;3 &lt;3 Find me at RailsConf. Tenderlove and I are giving out hugs for free!</p>

<p><strong>Update #1</strong>: Wycats who after working with us (South American rubyists) is known as wygatos (figure our why :P), is adhering to the campaign of giving hugs for free.</p>
]]></content>
  </entry>
  
  <entry>
    <title>My OS X Rails installation using Homebrew and rbenv, step by step</title>
    <author>
      <name>sebastian.martinez</name>
    </author>
    <link href="http://blog.wyeworks.com/2012/4/13/my-osx-rails-installation-using-homebrew-and-rbenv-step-by-step/"/>
    <updated>2012-04-13T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2012/4/13/my-osx-rails-installation-using-homebrew-and-rbenv-step-by-step/</id>
    <content type="html"><![CDATA[<p>In this opportunity I'll explain (as the title suggests) how to go from a brand new mac os x to running Rails tests.</p>

<p><b>Step 0</b>, is to make sure that <code>locale</code> returns <pre><code>LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
</code></pre></p>

<p>(you'll get some unexpected errors later on if not). To do so, you can either set the Language to one that Mac OS X sets UTF-8 by default, like United States from the System Preferences panel.
<b>Or</b>, you can run</p>

<pre><code>$ export LC_ALL=en_US.UTF-8
$ export LANG=en_US.UTF-8
</code></pre>


<p>to achieve that.</p>

<p><b>Step 1</b>, install Xcode.</p>

<p><b>Step 2</b>, install osx-gcc-installer from <code>https://github.com/kennethreitz/osx-gcc-installer</code></p>

<p><b>Step 3</b>, So now you're ready to install Homebrew, by doing:</p>

<pre><code>$ /usr/bin/ruby -e "$(/usr/bin/curl -fksSL https://raw.github.com/mxcl/homebrew/go)"
</code></pre>


<p>Now this is how to install some common libraries</p>

<p><b>Step 4</b>, We need to first have git in order run the brew doctor, so</p>

<pre><code>$ brew install git</code></pre>


<p></p>

<p>You can make sure that everything is ok by running <pre><code>$ brew doctor</code></pre> at any time. It should return '<code>Your system is raring to brew</code>' when in optimal conditions.</p>

<p><b>Step 5</b>, now to install the rest of the libraries</p>

<pre><code>$ brew install memcached mysql postgresql</code></pre>


<p><b>Step 6</b>, initializing the mysql and postgres databases must be done by doing</p>

<pre><code>$ initdb /usr/local/var/postgres
$ mysql_install_db --verbose --user=`whoami` --basedir="$(brew
--prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
</code></pre>


<p><b>Step 7</b>, I like having some aliases to load/unload mysql, postgres and memcached. To do so, you should add the following lines to your ~/.zshrc</p>

<pre><code>alias memcached_load="launchctl load -w /usr/local/Cellar/memcached/1.4.13/homebrew.mxcl.memcached.plist"
alias memcached_unload="launchctl unload -w /usr/local/Cellar/memcached/1.4.13/homebrew.mxcl.memcached.plist"
alias mysql_load="launchctl load -w /usr/local/Cellar/mysql/5.5.20/homebrew.mxcl.mysql.plist"
alias mysql_unload="launchctl unload -w /usr/local/Cellar/mysql/5.5.20/homebrew.mxcl.mysql.plist"
alias postgres_load="launchctl load -w /usr/local/Cellar/postgresql/9.1.3/homebrew.mxcl.postgresql.plist"
alias postgres_unload="launchctl unload -w /usr/local/Cellar/postgresql/9.1.3/homebrew.mxcl.postgresql.plist"
</code></pre>


<p><b>Step 8</b>, Now you're good to go. Next we'll install rbenv to easily switch between multiple versions of Ruby. You can also choose to use RVM or roll your own.</p>

<pre><code>$ brew install rbenv ruby-build</code></pre>


<p><b>Step 9</b>, Add</p>

<pre><code>export PATH=$HOME/.rbenv/bin:$PATH
eval "$(rbenv init -)"
</code></pre>


<p>to your <code>~/.zshrc</code>.</p>

<p><b>Step 10</b>, now do the following to install ruby <pre><code>$ rbenv install 1.9.3-p125</code></pre></p>

<p><b>Step 11</b>, you need to <pre><code>$ rbenv global 1.9.3-p125
$ rbenv rehash</code></pre></p>

<p><b>Step 12</b>, Cool, so now we are good to go and setup Rails.</p>

<pre><code>$ git clone https://github.com/rails/rails.git
$ gem install bundler
$ rbenv rehash
$ cd rails
$ bundle
</code></pre>


<p><b>Step 13</b>, now, from the Contributing to Rails Guide, you should</p>

<pre><code>$ mysql_load
$ postgres_load
$ mysql -u root
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.* to 'rails'@'localhost';
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost';
exit
$ cd activerecord
$ rake mysql:build_databases
$ rake postgresql:build_databases
</code></pre>


<p>And that's it!, we have <b>Ruby, MySQL, PostgreSQL, Memcached</b>, and everything needed to do some Rails development.</p>

<p><b>Step 14</b>, we need to load Memcached for its needed for some tests by doing</p>

<pre><code>$ memcached_load </code></pre>


<p><b>Step 15</b>, and lastly, you can run Rails tests by doing</p>

<pre><code>$ rake</code></pre>


<p>at the top of the rails directory.</p>

<p>Everything should work just fine, or at least you should get the same results as the <a href="http://travis-ci.org/#!/rails/rails">Rails CI.</a></p>

<p><b>Congratulations! </b></p>
]]></content>
  </entry>
  
  <entry>
    <title>bundle exec rails … executes Bundler.setup 3 times</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2011/12/27/bundle-exec-rails-executes-bundler-setup-3-times/"/>
    <updated>2011-12-27T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2011/12/27/bundle-exec-rails-executes-bundler-setup-3-times/</id>
    <content type="html"><![CDATA[<p><em>TL;DR</em>: don't run <em>bundle exec</em> before <em>rails</em> command, rails already checks the presence of <em>Bundler</em> through the <em>Gemfile</em> and sets up everything according to it without the overhead of <em>bundle exec<em>. </em>rails</em> command is the only exception to the rule. Additionally I've added a <a href="https://github.com/carlhuda/bundler/commit/2c838255ccadadeab5298b7c2bbc39035e59f248">patch</a> to <em>Bundler</em> that avoids calling Bundler.setup which adds unnecessary overhead.</p>

<p>I was researching on a huge <em>Bundler 1.1</em> performance regression, <a href="http://twitter.com/masterkain">@masterkain</a> was hitting when running <em>bundle exec rails runner ''</em> (you shouldn't run bundle exec before the <em>rails</em> command, but keep reading for now). I started to profile it using <em>ruby-prof</em> and one of the things I realized was that <em>Bundler.setup</em> (which is a considerable slow method because it calls <a href="https://github.com/carlhuda/bundler/blob/2a38a24a295b6e978f0c982d454a3a9f11399abc/lib/bundler/runtime.rb#L7-42">Bundler::Runtime#setup</a>) was ran 3 times. My first reaction was WTF?? 3 times??. I will write about my other findings in another blog post.</p>

<p>After analyzing the code, I found out that the first call to <em>Bundle.setup</em> is in <a href="https://github.com/carlhuda/bundler/blob/2a38a24a295b6e978f0c982d454a3a9f11399abc/lib/bundler/cli.rb#L398">Bundler::CLI#exec</a> right before shelling out to run <em>rails runner ''</em>.
The second call is on <a href="https://github.com/rails/rails/blob/d2abe28ed342443f8c374a6e02977ccb0c3b3f95/railties/lib/rails/generators/rails/app/templates/config/boot.rb#L6">boot.rb</a> as part of the boot process (well actually it's required from <em>bundle exec</em> through <a href="https://github.com/carlhuda/bundler/blob/2a38a24a295b6e978f0c982d454a3a9f11399abc/lib/bundler/runtime.rb#L227">this rubyopt</a> and on boot.rb the require returns false because it's already required).
And the last call starts on <a href="https://github.com/rails/rails/blob/d2abe28ed342443f8c374a6e02977ccb0c3b3f95/railties/lib/rails/generators/rails/app/templates/config/application.rb#L17">config/application.rb</a>
which ends up calling <a href="https://github.com/carlhuda/bundler/blob/2a38a24a295b6e978f0c982d454a3a9f11399abc/lib/bundler.rb#L120-122">Bundler.require</a> to finally call <em>Bundler.setup</em> for the third time.
The second and third calls are run on the same process so <em>Bundler.setup</em> caches the result in <a href="https://github.com/carlhuda/bundler/blob/2a38a24a295b6e978f0c982d454a3a9f11399abc/lib/bundler.rb#L105">@setup</a> so there's no slow down between those 2 calls.
But the command passed to <em>bundle exec</em> runs in a different process (remember I said before that we were shelling out to run <em>rails runner ''<em>) so the resulting execution of the first </em>Bundler.setup</em> won't be available to the <a href="https://github.com/carlhuda/bundler/blob/2a38a24a295b6e978f0c982d454a3a9f11399abc/lib/bundler/runtime.rb#L209-231">rails runner process" and doesn't make any sense. All that <em>bundle exec</em> needs to do is to "setup the rubyopts</a> needed to run the command you are passing to <em>bundle exec<em>. I've <a href="https://github.com/carlhuda/bundler/commit/2c838255ccadadeab5298b7c2bbc39035e59f248">patched</a> </em>Bundler</em> to do the right thing.</p>

<p>So don't run <em>bundle exec</em> before <em>rails</em> command, this command is already aware of <em>Bundler</em> and sets up everything according to what you have on your <em>Gemfile</em>.
If you prepend <em>bundle exec</em> before <em>rails</em> command all you will be adding is overhead of opening another process from <em>Bundler</em> and executing useless code since <em>rails</em> already does the right thing.</p>

<p>You probably already know about that, but I've seen a lot of proficient Rails developers doing it.</p>

<p>Read more about the topic in <a href="http://yehudakatz.com/2011/05/30/gem-versioning-and-bundler-doing-it-right/">Yehuda's blog</a></p>
]]></content>
  </entry>
  
  <entry>
    <title>Ruby 1.9.3 and ruby-debug</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2011/11/1/ruby-1-9-3-and-ruby-debug/"/>
    <updated>2011-11-01T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2011/11/1/ruby-1-9-3-and-ruby-debug/</id>
    <content type="html"><![CDATA[<p>As you probably know Ruby (MRI so brixen doesn't get mad at me :P) <a href="http://www.ruby-lang.org/en/news/2011/10/31/ruby-1-9-3-p0-is-released/.">1.9.3 was released</a> I've been using 1.9.3 for a while now and as part of my RubyConf Uruguay talk I wanted to show ruby-debug. So my first attempt was:</p>

<pre><code>$ gem install ruby-debug19
Fetching: linecache19-0.5.12.gem (100%)
Building native extensions.  This could take a while...
Fetching: ruby-debug-base19-0.11.25.gem (100%)
Building native extensions.  This could take a while...
Fetching: ruby-debug19-0.11.6.gem (100%)
Successfully installed linecache19-0.5.12
Successfully installed ruby-debug-base19-0.11.25
Successfully installed ruby-debug19-0.11.6
3 gems installed</code></pre>


<p>Then require 'ruby-debug' and booom!!</p>

<pre><code>$ irb
irb(main):001:0> require 'ruby-debug'
LoadError: dlopen(/Users/santiago/.rbenv/versions/1.9.3/lib/ruby/gems/1.9.1/gems/ruby-debug-base19-0.11.25/lib/ruby_debug.bundle, 9): Symbol not found: _ruby_current_thread
  Referenced from: /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/gems/1.9.1/gems/ruby-debug-base19-0.11.25/lib/ruby_debug.bundle
  Expected in: flat namespace
 in /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/gems/1.9.1/gems/ruby-debug-base19-0.11.25/lib/ruby_debug.bundle - /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/gems/1.9.1/gems/ruby-debug-base19-0.11.25/lib/ruby_debug.bundle
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/gems/1.9.1/gems/ruby-debug-base19-0.11.25/lib/ruby-debug-base.rb:1:in `<top (required)>'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/gems/1.9.1/gems/ruby-debug19-0.11.6/cli/ruby-debug.rb:5:in `<top (required)>'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:59:in `require'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:59:in `rescue in require'
    from /Users/santiago/.rbenv/versions/1.9.3/lib/ruby/1.9.1/rubygems/custom_require.rb:35:in `require'
    from (irb):1
    from /Users/santiago/.rbenv/versions/1.9.3/bin/irb:12:in `<main>'</code></pre>


<p>So after some research on the internet I found out that the author of ruby-debug had a fix for it which he considered unstable and didn't push it to rubygems.org yet. Since I prefer an unstable ruby-debug than a non working one :P, I gave it a try ...</p>

<p>First download linecache19-0.5.13.gem and ruby-debug-base19-0.11.26.gem from <a href="http://rubyforge.org/frs/?group_id=8883">http://rubyforge.org/frs/?group_id=8883</a>, then …</p>

<pre><code>$ gem install linecache19-0.5.13.gem 
Building native extensions.  This could take a while...
Successfully installed linecache19-0.5.13
1 gem installed
$ gem install ruby-debug-base19-0.11.26.gem -- --with-ruby-include=/Users/santiago/.rbenv/source/ruby-1.9.3-p0  
Building native extensions.  This could take a while...
Successfully installed ruby-debug-base19-0.11.26
1 gem installed
$ irb
irb(main):001:0> require 'ruby-debug'
=> true</code></pre>


<p>and voilá.</p>

<p>So while we wait for an official release, you can enjoy a working ruby-debug.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Client - Developer relationships</title>
    <author>
      <name>sebastian.martinez</name>
    </author>
    <link href="http://blog.wyeworks.com/2011/4/11/client-developer-relationships/"/>
    <updated>2011-04-11T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2011/4/11/client-developer-relationships/</id>
    <content type="html"><![CDATA[<p>There is an old joke that illustrates how the relationship between clients and developers is that I'd like to share with you:</p>

<pre><code>A man is flying in a hot air balloon when realizes he is lost. He reduces height and spots a man down below. He lowers the balloon further and shouts: 
- "Excuse me, can you tell me where I am?"
The man below says: 
- "Yes you're in a hot air balloon, hovering 30 feet above this field."
- "You must be a software developer," says the balloonist.
- "I am," replies the man. "How did you know?"
- "Well," says the balloonist, "everything you have told me is technically correct, but it's of no use to anyone."
The man below says, 
- "You must work in business as a manager."
- "I do," replies the balloonist, "but how did you know?"
- "Well," says the man, "you don't know where you are or where you are going, but you expect me to be able to help. You're in the same position you were before we met but now it's my fault." </code></pre>


<p>Developing successful client relationships are critical to any business. Preserving these relationships is crucial for making the time spent on projects more enjoyable and satisfying, as well as for referrals and future business.</p>

<h2>So how can I improve this relationship?</h2>


<p>It ain't the purpose of this post to be a silver bullet, but to share some practices that have given us some good results in the past.</p>

<ul>
<li><h4>Spend some time getting to know your client</h4>
You will likely spend many hours with the client during the project. It is important in order to strengthen the relationship to get to know your client's interests, try to feel what they feel. After all, we are all human thus have natural highs and lows, and it is important to understand when someone is having a hard day.</li>

<li><h4>Educate your client</h4>
Educating clients about web development is crucial to the success of a project. The pace of change on the web is staggering and it is our responsibility to help clients make good decisions regarding their web presence. You need to tell your client that changes are a good thing and should be welcomed.</li>

<li><h4>Be willing to say NO</h4>
In many cases, clients ask us to do things that our experience says that doing so will, far from contributing to the project, cause users to run away. You need to take the time to understand why your client is asking you to do this, let them know your reasons against it, and try to find another solution together. This is healthy. Don't just say "yes" because <i>the client is always right.</i></li>

<li><h4>Be willing to say YES</h4>
Say yes to the jobs that may require you to work harder. The client will be grateful. Specially in those cases when it is important for the client to have this particular feature deployed, as it will represent and lead to a full stack of opportunities. Doing this will make you more valuable in your clients eyes, and also by sharing the stress of the deadline you'll become closer to the client, so don't be afraid to embrace these opportunities. Now, this concept should not be taken as the regular way to go, meaning no one can expect us to work every single day giving a 150%. Pushing yourself a little bit every once in a while is ok, but when it becomes normal, then something's wrong.</li>

<li><h4>Keep your distance</h4>
We become more valuable the more we work in an organization, but we need to define and maintain our role clearly. Even as we build the relationships that make us successful, we need to be diligent in keeping our distance so we can continue to provide valued advice and expertise. The idea is to have a respectful relationship, always keeping it professional.</li>

<li><h4>Be transparent</h4>
There might be cases when some tasks take longer than you expected. What should you do then? **Be transparent.** Explain your client the complications you ran into, and that these complications will probably make you work a little bit longer on this task, there's nothing wrong with that. Anything can get complicated. Complications are part of our job. Being transparent to your client about this is definitely the way to go.</li>

<li><h4>Gain your client's TRUST</h4>
Best way to gain your client's trust is to stay focused on your deliverables. When we deliver **what** we say and **when** we say we will deliver it, we build our credibility and enhance our relationships. The trust the client gives us increases, and will help us when we state "this task will take two days" for example, when they think it's just a simple tweak and shouldn't take more than a couple of hours. The most important thing is letting them know that we are part of the team, we are both on the same boat, aiming to the same goals. Once your client understands that their failures are also your failures, and their achievements are your achievements as well and the other way around, then you'll be a step further in gaining their trust.</li>

<li><h4>Work at it</h4>
Recognize that the client relationship is part of the job. Working on the relationship will make you more successful on current projects, enhance your chance for future work, and make the project much more enjoyable.</li>
</ul>


<p>Hopefully by following this you'll have a smoother relationship with your clients, and what's more, make you feel comfortable working with them on the daily basis.</p>
]]></content>
  </entry>
  
  <entry>
    <title>RailsConf 2010: Interview with Caike Souza</title>
    <author>
      <name>jose.costa</name>
    </author>
    <link href="http://blog.wyeworks.com/2011/3/25/railsconf-2010-interview-with-caike-souza/"/>
    <updated>2011-03-25T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2011/3/25/railsconf-2010-interview-with-caike-souza/</id>
    <content type="html"><![CDATA[<p>We're opening the box of RailsConf 2010 memories! Yep ... we suck at journalism, so it turns out we have this almost one year old interview with Caike Souza we never shared before. So sorry Caike!</p>

<p>Caike (<a href="http://twitter.com/caike">@caike</a>) is a passionate agile software craftsman and founder of the <a href="http://orlandodojo.org/">Orlando Code Dojo</a> group, where programmers get together to practice coding to improve their skills once a month. He is currently working at <a href="http://envylabs.com/.">Envy Labs</a></p>

<p>Thanks for your time and great vibe!</p>

<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/YtyXKeNzO1g" frameborder="0" allowfullscreen></iframe>

]]></content>
  </entry>
  
  <entry>
    <title>Metaprogramming in Ruby slides from my talk at RubyConf Uruguay</title>
    <author>
      <name>santiago.pastorino</name>
    </author>
    <link href="http://blog.wyeworks.com/2010/11/4/metaprogramming-in-ruby-slides-from-my-talk-at-rubyconf-uruguay/"/>
    <updated>2010-11-04T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2010/11/4/metaprogramming-in-ruby-slides-from-my-talk-at-rubyconf-uruguay/</id>
    <content type="html"><![CDATA[<div style="width:425px" id="__ss_5634072"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/spastorino/metaprogramming-5634072" title="Metaprogramming">Metaprogramming</a></strong><object id="__sse5634072" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=metaprogramming-101101101836-phpapp02&rel=0&stripped_title=metaprogramming-5634072&userName=spastorino" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5634072" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=metaprogramming-101101101836-phpapp02&rel=0&stripped_title=metaprogramming-5634072&userName=spastorino" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/spastorino">Santiago Pastorino</a>.</div></div>

]]></content>
  </entry>
  
  <entry>
    <title>Creating your own generators on Rails 2.3</title>
    <author>
      <name>sebastian.martinez</name>
    </author>
    <link href="http://blog.wyeworks.com/2010/9/23/creating-your-own-generators-on-rails-2-3/"/>
    <updated>2010-09-23T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2010/9/23/creating-your-own-generators-on-rails-2-3/</id>
    <content type="html"><![CDATA[<p>Time has come for me to write a Rails generator, and as you're guessing right now, my first step was taking a look at the <a href="http://guides.rubyonrails.org/generators.html.">Guides</a>
They give you a pretty good idea on what you can do (despite of being for Rails 3.0), but as my friend Santiago always say, there's no better documentation than the source code itself. So, my second step was to dive into the <a href="http://github.com/rails/rails/tree/2-3-stable/railties/lib/rails_generator/.">code</a> You should definitely read the code, great stuff there.</p>

<p>After some time reading, I decided it was time for me to start playing around with that, so here it comes:</p>

<p>First thing you should know, is that all Rails generators are derived from a class called “Rails::Generator::Base.” But, if we derive our generator class from NamedBase instead of Base, then we’ll get the ability to take a name parameter from the script/generate command line. With that in mind, you can start writing the generator <em>skeleton</em>:</p>

<pre><code>class WidgetGenerator < Rails::Generator::NamedBase
  def manifest
    record do |m|
      # Do something
    end
  end
end</code></pre>


<p>In order to make the generator work on your Rails 2.3 application, you should place this file under <strong>'lib/generators/widget/widget_generator.rb'</strong></p>

<p>Is on the manifest method where the magic occurs. Depending on what exactly we want our generator to do, is what we're going to code inside it.
In my case, I wanted to behave very similar to the scaffold, so I wanted a controller class, a model, views, migration, etc... You can look at the templates of the scaffold generator, they will give you a very clear idea on how to use them. Then, you should place your templates under <strong>'lib/generators/widget/templates/'</strong></p>

<p>In most cases, you will want your generator to receive several arguments. Best way is to have an initialize method to take care of that, just like this:</p>

<pre><code>
class WidgetGenerator < Rails::Generator::NamedBase
  attr_reader   :controller_class_name,
                :class_name
  attr_accessor :attributes
  
def initialize(runtime_args, runtime_options = {})
    super
    @name = runtime_args.first
    @controller_class_name = @name.pluralize.capitalize
    @attributes = []

    runtime_args[1..-1].each do |arg|
      if arg.include? ':'
        @attributes << Rails::Generator::GeneratedAttribute.new(*arg.split(":"))
      end
    end
  end

  def manifest
    record do |m|
      # Do something
    end
  end
end</code></pre>


<p>Until now, we're just initializing the generator, but it's not doing anything yet. Let's add some action on our manifest method:</p>

<pre><code>def manifest
    record do |m|
      m.template('controller.rb', "app/controllers/#{name.pluralize}_controller.rb")
      m.template('model.rb', "app/models/#{name}.rb")
      m.migration_template("migration.rb", "db/migrate", :migration_file_name => "create_#{name.underscore.pluralize.camelize}")

      m.directory(File.join('app/views', name.pluralize))
      for action in %w[ new edit show ]
        m.template(
          "view_#{action}.html.erb",
          File.join('app/views', controller_file_name, "#{action}.html.erb")
        )
      end
    end
  end</code></pre>


<p>Cool, now we are generating a controller from our template, a model, a migration, among others...Nice!</p>

<p>You can also add a protected banner method, to display the usage of the generator right on the console:</p>

<pre><code>protected
    def banner
      "Usage: #{$0} widget WidgetName [field:type, field:type]"
    end</code></pre>


<p>And that's all !! You can now generate all the widgets you want.
The command to run this would be:</p>

<pre><code>$ ./script/generate widget MyWidget title:string viewing:integer</code></pre>


<p>Have fun generating!!</p>
]]></content>
  </entry>
  
  <entry>
    <title>RailsConf 2010: Interview with George Guimarães</title>
    <author>
      <name>jose.costa</name>
    </author>
    <link href="http://blog.wyeworks.com/2010/7/28/railsconf-2010-interview-with-george-guimaraes/"/>
    <updated>2010-07-28T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2010/7/28/railsconf-2010-interview-with-george-guimaraes/</id>
    <content type="html"><![CDATA[<p>Among the great people we met at the RailsConf was George Guimarães (<a href="http://twitter.com/georgeguimaraes">@georgeguimaraes</a>), by no surprise he was a very cool and funny dude, and he was open to talk and hang around with us.</p>

<p>George is co-founder of <a href="http://plataformatec.com.br/">Plataforma Tec</a>, that many of us got to know well through their amazing set of gems/plugins and the stunning work José Vailm has been doing as a Rails Core team member. Kind of what I hope it's happening with the great work Santiago Pastorino is doing with his contributions and how it's reinforcing WyeWorks reputation.</p>

<p>But still there are a lot of guys behind the scenes that support this great Open Source effort that's being carried in these companies, probably not so much by direct intervention but with more hard and 'real' work as we like to say to joke around and bother the OSS guys. The kind of work that pay the bills :P</p>

<p>Not that George doesn't do OSS, actually he's currently involved in the development of <a href="http://github.com/caelum/restfulie">Restfulie</a> that got many people pretty excited at the RailsConf this year, and much more stuff.</p>

<p>Hope you enjoy this not so serious take.</p>

<p>Thanks George!</p>

<object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/5VCGPPmW4dM&amp;hl=en_US&amp;fs=1?rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/5VCGPPmW4dM&amp;hl=en_US&amp;fs=1?rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object>

]]></content>
  </entry>
  
  <entry>
    <title>RailsConf 2010: Interview with Fabio Akita</title>
    <author>
      <name>jose.costa</name>
    </author>
    <link href="http://blog.wyeworks.com/2010/7/1/railsconf-2010-interview-with-fabio-akita/"/>
    <updated>2010-07-01T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2010/7/1/railsconf-2010-interview-with-fabio-akita/</id>
    <content type="html"><![CDATA[<p>In the last day of the RailsConf 2010 Santiago and I got the pleasure to hang out a few hours with Fabio Akita, a very successful guy in the Ruby and Rails community, but yet so humble and open as many of the great people we met in these past days.</p>

<p>Fabio is well known as a great evangelist of this movement, as a great speaker, for his bundle of plugins for the vim editor but also for carrying interviews with important people of the community on every conference he attends. The thing is that personally I never got to see him as the subject of the interview, and he is a wise guy that has a lot to say. So even though he was very tired, he accepted to do this improvised short interview with me, almost the first time I was holding a camera.</p>

<p>This is the first of a small series of interviews that will be posted soon.</p>

<p>I hope you all enjoy it and share his thoughts on what are the good things that makes this community so special, so that we never loose that spirit.</p>

<p>Thanks Fabio!</p>

<object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/2H4OCuhJeyw&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/2H4OCuhJeyw&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object>

]]></content>
  </entry>
  
  <entry>
    <title>Making Paperclip work with Sinatra &amp; Datamapper</title>
    <author>
      <name>sebastian.martinez</name>
    </author>
    <link href="http://blog.wyeworks.com/2010/2/10/making-paperclip-work-with-sinatra-datamapper/"/>
    <updated>2010-02-10T00:01:00+00:00</updated>
    <id>http://blog.wyeworks.com/2010/2/10/making-paperclip-work-with-sinatra-datamapper/</id>
    <content type="html"><![CDATA[<p>I was working lately on a Sinatra project, and got fascinated on how fast you can get things up and running.
Everything was beautiful, until I tried to upload a file using paperclip.</p>

<p>Although Paperclip was originally built for rails <a href="http://invalidlogic.com/dm-paperclip/">Ken Robertson</a> ported it to Datamapper.
Let me explain in few steps how you can upload with Paperclip, using Datamapper.</p>

<p>Start declaring your model like this:</p>

<pre><code>class Resource
  include DataMapper::Resource
  include Paperclip::Resource

  property :id,     Serial

  has_attached_file :file,
                    :url => "/system/:attachment/:id/:style/:basename.:extension",
                    :path => "#{APP_ROOT}/public/system/:attachment/:id/:style/:basename.:extension"
end
</code></pre>


<p>You'll need to specify your :url and :path options as the ones built into dm-paperclip are merb centric which won't quite work. Also set APP_ROOT to where ever your application root directory with your static Sinatra folder is.</p>

<p>Now your routes should look something like this:</p>

<pre><code>post '/upload' do
  resource = Resource.new(:file => make_paperclip_mash(params[:file]))
  halt "There were some errors processing your request..." unless resource.save
end
</code></pre>


<p>And there's the tricky part, on the <strong>make_paperclip_mash</strong> method.
Paperclip expects the file object loaded from the form to be in a different form than what is created by default. To fix this you should create a Mash (which is just a Hash, unless you're actually using merb):</p>

<pre><code>def make_paperclip_mash(file_hash)
  mash = Mash.new
  mash['tempfile'] = file_hash[:tempfile]
  mash['filename'] = file_hash[:filename]
  mash['content_type'] = file_hash[:type]
  mash['size'] = file_hash[:tempfile].size
  mash
end
</code></pre>


<p>And that's it, now you can upload files using Paperclip right on your Sinatra app with Datamapper.
You can check out the code of this example at: <a href="http://gist.github.com/291877">sinatra_paperclip.rb</a></p>
]]></content>
  </entry>
  
</feed>
