<?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>Engine Yard Blog &#187; Yehuda Katz</title>
	<atom:link href="http://www.engineyard.com/blog/author/yehudakatz/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.engineyard.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 07 Feb 2012 01:49:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Rails and Merb Merge: Rack (Part 6 of 6)</title>
		<link>http://www.engineyard.com/blog/2010/rails-and-merb-merge-rack-part-6-of-6/</link>
		<comments>http://www.engineyard.com/blog/2010/rails-and-merb-merge-rack-part-6-of-6/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 17:00:41 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails 3]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3742</guid>
		<description><![CDATA[<p>In this final segment, I'll talk about how Rails 3 takes advantage of the Rack standard, leveraging it in ways that make sharing code between Ruby web applications easier. There are a ton of good blog posts and presentations on Rack itself, so I won't go into too much detail beyond a brief summary.</p>
<h2>What is Rack?</h2>
<p>Rack defines a standard for interaction between web servers and Ruby web applications. It's based on the CGI standard, but stripped of CGI's global characteristics (such as its use of environment variables and standard output).</p>
<p>Servers send requests to Rack applications by calling their <code>#call</code> method with an environment Hash containing information as a number of standardized keys. For instance, it provides the requested path in the PATH_INFO variable. Applications send responses back to the server as an Array of three elements: the status code, a Hash of the headers, and the body. Applications may return any object that responds to <code>#each</code> as the body, and each iteration must return a String object.</p>
<p>Here are a couple of simple Rack applications:</p>
<pre lang="ruby"># A Proc responds to #call
proc do |env|
  [200, {"Content-Type" => "text/html"}, ["Hello world"]]
end

# Other objects that respond to #call work too
class MyApp
  def self.call(env)
    [
      200,
      {"Content-Type" => "text/html"},
      ["Hello world"]
    ]
  end
end</pre>
<h2>Rails 2.3</h2>
<p>In Rails 2.3, Rails became a fully valid Rack application, leveraging Rack in a number of places:</p>
<ul>
<li>ActionController::Dispatcher.new is the top-level Rack application</li>
<li>The parameter parser is implemented as middleware</li>
<li>The router is a Rack application that dispatches to controllers</li>
<li>Each controller is a Rack application</li>
</ul>
<p>This was a modest step toward leveraging Rack, and made Rails applications work anywhere Rack worked. However, the internals of some of these pieces were messy, and an overhaul would be needed to take full advantage of the Rack ecosystem and the power of Rack's architecture.</p>
<h2>Enter Rails 3: The Application</h2>
<p>First, rather than having a global Dispatcher object pointing at a global router, Rails 3 introduces the idea of the Rails Application. The Application, an object holding the router and other configuration, is itself a Rack application.</p>
<p>The following is a valid <code>config.ru</code>.</p>
<pre lang="ruby"># Set up load paths as desired

require "action_controller/railtie"

class FooController < ActionController::Base
  def bar
    self.response_body = "HELLO"
  end
end

class MyApp < Rails::Application
   config.session_store :disabled

   routes.draw do
     match "/foo" => "foo#bar"
  end
end

run MyApp</pre>
<p>As you can see, a Rails application is a valid Rack application. The above <code>config.ru</code> file will run with <code>rackup</code>, Passenger, Glassfish, or any other Rack server.</p>
<h2>ActionDispatch and Rack Middleware</h2>
<p>Rails 3 introduces a new framework called ActionDispatch, a library extending the features of the Rack library for Rails' use. This library can also be used standalone in any Rack application.</p>
<p>The new <code>ActionDispatch::Request</code> and <code>ActionDispatch::Response</code> objects now inherit from <code>Rack::Request</code> and <code>Rack::Response</code>. Integration tests now use <code>Rack::Test</code> and can now be used to test any Rack application.</p>
<p>Rails now includes a number of new general purpose middlewares:</p>
<ul>
<li>A middleware to run preparation callbacks, which Rails runs once in production mode, or once per request in development mode</li>
<li>A middleware to set up and write cookies</li>
<li>A middleware to clean up flash notices</li>
<li>A middleware to handle HEAD requests</li>
<li>A middleware to handle IP spoof checking</li>
<li>A middleware to serve static assets</li>
<li>Middlewares to handle rescuing exceptions down the stack</li>
<li>Middlewares for various session stores</li>
</ul>
<p>Rails also uses a number of middlewares that ship with the Rack library:</p>
<ul>
<li>A middleware to synchronize non-threadsafe requests</li>
<li>A middleware to measure and set the runtime of requests</li>
<li>A middleware to implement Send-File semantics in various web servers</li>
<li>A middleware to handle PUT and DELETE requests coming in via POST requests</li>
</ul>
<p>The middleware stack object, available as <code>config.middleware</code>, supports reordering these middlewares, or inserting new middleware relative to default ones.</p>
<p>One nice thing about implementing the functionality as middleware is that it forces them to be simple, standalone objects, and understanding, patching or even replacing them becomes much easier than trying to modify a monolithic controller or request object.</p>
<h2>The Router</h2>
<p>The Rails 3 router was written from the ground up by Josh Peek as the <code>Rack::Mount</code> project, which provides a general-purpose Rack router. <code>Rack::Mount</code> recognizes URLs and dispatches them to any Rack application. As a result, the router now natively supports matching any URL to any arbitrary Rack application--even a Sintra application.</p>
<pre lang="ruby">Rails.application.routes.draw do
  match "/blog" => Rack::Blog # Someone should write it!
end</pre>
<p>The router is itself a Rack application, so it's possible to mount a router inside the main router. Carl Lerche's <a href="http://github.com/carllerche/astaire">Astaire</a> project uses this to provide the Sinatra routing DSL inside a Rails controller. The following is a valid <code>config.ru</code>:</p>
<pre lang="ruby">$:.unshift File.expand_path('../../lib', __FILE__)

require 'rubygems'
require 'astaire'

class OmgController < ActionController::Base
  include Astaire::DSL
  append_view_paths File.expand_path('../views', __FILE__)

  get "/goodbye" do
    render :text => "goodbye"
  end

  get "/hello" do
    render "hello"
  end
end

run OmgController</pre>
<p>Astaire uses <code>ActionDispatch::Routing::RouteSet</code> internally, a Rails wrapper around <code>Rack::Mount</code>.</p>
<h2>Actions</h2>
<p>Because the router dispatches directly to Rack applications, each controller action is its own mini-application. To get a valid Rack application for a controller's action, use the <code>ArticlesController.action(:index)</code> syntax.</p>
<p>The Rails router uses the syntax <code>match "/articles" =&gt; "articles#index"</code> to match a URL to a controller/action pair. That syntax is identical to <code>match "/articles" =&gt; ArticlesController.action(:index)</code>.</p>
<p>Because actions are their own Rack applications, you can add middleware between the router and controller actions:</p>
<pre lang="ruby">class ArticlesController < ApplicationController
  use MyMiddleware
end</pre>
<p>This will insert the middleware between the router and the dispatching of an action. The following is a valid config.ru:</p>
<pre lang="ruby">class ArticlesController < ActionController::Base
  append_view_path "/path/to/views"

  def index
    render
  end

  # implicit actions, such as "articles/show" would work here
end

run ArticlesController.action(:index)</pre>
<p>This endpoint would behave exactly like a normal action, including callbacks and rendering. In fact, it's roughly identical to what happens internally inside the router.</p>
<p>You can also call into an action using this syntax:</p>
<pre lang="ruby">env = Rack::MockRequest.env_for("/articles")
status, headers, body = ArticlesController.action(:index).call(env)

# Create a response object, if you want one
response = ActionDispatch::Response.new(status, headers, body)</pre>
<p>You could also use Rack::Test:</p>
<pre lang="ruby">class TestArticles < Test::Unit::TestCase
  include Rack::Test::Methods

  def app
    ArticlesController.action(:index)
  end

  def test_get
    get "/articles"
    assert_equal "Hello world", last_response.body
  end
end

# This would include the application's middleware,
# which you probably want as it includes sessions
# and cookies
class TestApplication < Test::Unit::TestCase
  include Rack::Test::Methods

  def app
    MyApplication
  end

  def test_get
    get "/articles"
    assert_equal "Hello world", last_response.body
  end
end</pre>
<p>You would probably use Rails integration tests, which wrap Rack::Test with some additional conveniences, in practice. It's nice to know that there's very little magic going on, and that all of the individual pieces of Rails are just standard Rack.</p>
<h2>Conclusion</h2>
<p>While Rails 2 had started down the path of supporting Rack, Rails 3 took a few dozen steps forward, deeply integrating the framework with the Rack standard. In addition to improving the general interaction with servers, Rails 3 takes much more advantage of the Rack library, exposes its own functionality as reusable Rack components, and wires up the stack using the Rack architecture. This means that Rails itself integrates well with tools that work with Rack applications, and can also incorporate other applications or middleware following the Rack standard.</p>
<p>Stay tuned for more Rails 3 content to come—the series may be over, but there's <em>plenty</em> left to talk about.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/rails-and-merb-merge-rack-part-6-of-6/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Rails and Merb Merge: ORM Agnosticism (Part 5 of 6)</title>
		<link>http://www.engineyard.com/blog/2010/rails-and-merb-merge-orm-agnosticism-part-5-of-6/</link>
		<comments>http://www.engineyard.com/blog/2010/rails-and-merb-merge-orm-agnosticism-part-5-of-6/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 18:15:31 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ActionPack]]></category>
		<category><![CDATA[ActiveModel]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[DataMapper]]></category>
		<category><![CDATA[Haml]]></category>
		<category><![CDATA[Rails 3]]></category>
		<category><![CDATA[Railties]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3585</guid>
		<description><![CDATA[<p>It's been a little while since I've last posted in this series. During that time, we released Rails 3.0 beta, and announced the launch of <a href="http://www.railsplugins.org" target="_blank">RailsPlugins.org</a>. Plugin authors have registered almost 150 plugins, with 40 already boasting compatibility with Rails 3. Over the next few weeks, we're going to roll out some more features to help users find projects to help get updated, so keep an eye out.</p>
<p>Today I'm going to talk about the features we added to Rails 3 to provide ORM agnosticism. When we first started, the idea of such agnosticism was pretty fuzzy. As we approached the beta, we became convinced that we would shoot for the moon and give DataMapper, Sequel and other ORMs first-class access to all of the same parts of the framework that ActiveRecord had. Again, this sounds pretty fuzzy, so let me lay it out for you.</p>
<h2>ActiveRecord is a Framework Extension</h2>
<p>You read that right. While Rails itself ships with ActiveRecord as a default, the Railties gem, responsible for bootstrapping Rails, knows nothing about ActiveRecord. In order to achieve this, we had to make that bootstrapping process much more pluggable. While this is amazing for extensions, like DataMapper, that want to replace a built-in framework, it also exposes more functionality to any Rails extension distributed as a gem.</p>
<h3>Rails::Railtie</h3>
<p>In short, Railties now coordinates the initialization process, which involves the activation of a number of individual Railtie subclasses. Cute, no? Every Rails framework has its own Railtie subclass, which provides a number of useful pieces of functionality:</p>
<ul>
<li>The ability to add a key (like <code>config.active_record</code>) to an Application's configuration, and assign it defaults that will exist before Application configuration. For instance, a plugin could use this functionality to set a configuration key as an Array, so the Application could simply do <code>config.action_view.view_paths &lt;&lt; "my_path"</code>. While this isn't exactly earth-shattering, it levels the playing field between Rails components, like ActiveRecord, and third-party extensions, like DataMapper or Haml</li>
<li>The ability to create additional generators that hook into Rails' default generators. For instance, Rails' scaffold generator invokes sub-generators for stylesheets, template engine, test framework, helpers, and ORM. For instance, when a user installs Haml as a gem, it can register itself as the handler for template engine generators, and provide replacements for each case where Rails provides a default implementation. In this case, Haml would replace the template engine generators provide by ActionController's Railtie</li>
<li>The ability to supply Rake tasks to load when the user invokes the Rake command. If DataMapper supplies the same named Rake tasks as those supplied by the ActiveRecord Railtie, the user can completely remove ActiveRecord and replace it with DataMapper, retaining all of the named Rake tasks. This would allow other tasks, such as those used in testing, to automatically prepare the database and other tasks it performs by invoking tasks with certain names (like <code>db:create</code>)</li>
<li>Supply a log subscriber to integrate seamlessly with the uniform request logging. This allows extensions like DataMapper to add their timings into the log output. In this case, DataMapper simply replaces the "Model" timing that ActiveRecord provides, allowing a level of very tight integration with the rest of the framework</li>
<li>Specify initializers that should run at specific points in the initialization process. This allows extensions to set things up very early in the boot process, but then defer some setup until after the user has configured their application, or after specific parts of the initialization process have occurred. Each initializer also receives an instance of the Application object, giving it full access to the user's configuration</li>
</ul>
<p>In fact, if you take a look at <a href="http://github.com/rails/rails/blob/master/activerecord/lib/active_record/railtie.rb">ActiveRecord's deep integration</a> with the rest of the framework (which is roughly equivalent to its highly coupled implementation in Rails 2.3), you'll find that it looks extremely similar to <a href="http://github.com/datamapper/dm-rails/tree/master/lib/rails3_datamapper/railtie.rb">DataMapper's equally deep integration</a>. In fact, a major goal of the work we put into improving modularity in Rails 3 was to maintain the same level of stack integration we've historically had, while exposing the same toolchain for those who wanted to replace only certain <em>elements</em> of the stack.</p>
<h2>The ActiveModel API</h2>
<p>Giving DataMapper access to the same level of integration with Railties as ActiveRecord is one of two major pillars in making Rails truly ORM agnostic. The second part is decoupling Rails' historic connection between ActiveRecord, its ORM, and ActionPack, its controller and view layer. In this area, Rails takes a holistic, very conventional approach to linking the model and the view using REST principles.</p>
<p>In particular, domain objects, persisted via the ORM, can have canonical URLs that are used pervasively throughout the controller and view layer. The specific URLs can be configured via the router, and Rails 3's router is particularly powerful, but once configured, objects do have canonical URLs.</p>
<pre lang="ruby">@post = Post.first

redirect_to @post           #=> Location: /posts/orm-agnosticism
redirect_to Post            #=> Location: /posts

form_for @post              #=>
<form action="/posts/orm-agnosticism" method="PUT">
form_for Post.new           #=>

error_messages_for @post    #=> a representation of the validation errors that exist on the object

link_to @post.title, @post  #=> <a href="/posts/orm-agnosticism">
                            #     Rails and Merb Merge: ORM Agnosticism (Part 5 of 6)
                            #   </a>

posts_path                  #=> "/posts"
post_path(@post)            #=> "/posts/orm-agnosticism"

@posts = Post.where(:author => "wycats")

render @post                #=> renders "_post.html.erb", passing in @post as a local
render @posts               #=> renders a collection of "_post.html.erb", passing in each
                            #   Post instance as a local in turn

respond_with @post          #=> performs content negotiation between the formats
                            #   the client is willing to Accept (xml, json, html),
                            #   and the formats the @post object is willing to
                            #   provide. The available providable formats are
                            #   transparently determined by introspecting the @post
                            #   object. Additionally, if the object has not been persisted,
                            #   redirect it back to the editing page for further modification.
                            #   If it has been persisted, redirect it back to the index (or
                            #   some other appropriate path).</form>
</pre>
<p>In short, Rails 2.3 provided a fair bit of integrated functionality between ActiveRecord and ActionPack. For instance, to determine what an object's canonical URL was, Rails called an internal <code>.class.naming</code> method on it, which provided the information needed to form the canonical URLs. And while other ORMs could attempt to emulate these internals, there was no guarantee that they'd be used in the same way from release to release (and, in fact, they evolved quite a bit, making them a moving target at best).</p>
<p>In Rails 3, we opened them up, exposing an explicit public API via ActiveModel. The ActiveModel API requires that objects respond to <code>to_model</code>, returning an Object that complies with the larger ActiveModel API. This allows objects that already implement methods with the same names as those required by the API to create a facade that presents itself to ActionPack as a fully compliant model.</p>
<p>The API itself is fairly small, with a few methods around validation, the ability to determine whether an object has persisted or not (which can be safely stubbed by objects without persistence), and a number of methods that tell ActionPack how to convert the object into a canonical URL or template name. By doing this, Rails has completely decoupled ActionPack from ActiveRecord directly, and ActiveRecord becomes just one of many ORMs to implement the ActiveModel API.</p>
<p>The DataMapper ORM has already released a Rails extension (called <a href="http://github.com/datamapper/dm-rails">dm-rails</a>) that implements both the Railtie functionality and ActiveModel, making it a full drop-in replacement for ActiveRecord. The Sequel ORM is also hard at work on their Railtie and ActiveModel adapter.</p>
<p>The really great thing about all of this is that we didn't need to sacrifice one bit of the (some have said overly) tight integration between various parts of Rails, to provide the ability to swap in entirely different components with the same apparent "coupling" that the Rails frameworks have with each other.</p>
<p>As always, questions and comments are welcome!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/rails-and-merb-merge-orm-agnosticism-part-5-of-6/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Rails 3 Beta is Out &#8212; A Retrospective</title>
		<link>http://www.engineyard.com/blog/2010/rails-3-beta-is-out-a-retrospective/</link>
		<comments>http://www.engineyard.com/blog/2010/rails-3-beta-is-out-a-retrospective/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 20:00:08 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Rails 3]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3441</guid>
		<description><![CDATA[<p>The Rails team has finally released the Rails 3 beta, after more than a year since the Rails and Merb teams started working on this release. You can read all about it at the <a href="http://weblog.rubyonrails.org/2010/2/5/rails-3-0-beta-release">official Rails blog</a>, but I figured I'd take the opportunity to share my take on the release.</p>
<p>First of all, you're probably sick of hearing this, but we've done far, far more than we ever expected. A lot of that happened in the last few weeks.</p>
<p>One of the things that most surprised and impressed me is the Rails core team's (and especially DHH's) attention to detail and the experience of the beta release. For weeks, we've been "this close" to releasing, but the experience of starting up a new Rails app or upgrading from a Rails 2.3 app still felt too unpleasant. In this kind of situation, it's tempting to say "it's just a beta—people who use beta software know what they're getting," but that would have been a major cop-out. For many people on the leading edge, a poor beta experience will shape their perception of the product as a whole. So we waited a bit, but now we're finally here.</p>
<p>In addition to a surprising (in a good way) amount of polish, we touched nearly every part of Rails: I'll walk you through the top-level blocks.</p>
<h2>Dependencies</h2>
<p>Rails gets a bunch of new dependencies, stepping out of the "virtually zero dependencies" box it has lived in since the beginning. In order to achieve this, we wrote a brand new dependency management system (called Bundler) from scratch, remedying many of the problems with Rubygems that have made using a number of dependencies difficult (and which we encountered in Merb when taking a more-dependencies approach). Taking another step into the future, we built Bundler itself as a standalone component, so you can use it for Rails, Merb, Sinatra, or even a plain old Ruby script.</p>
<p>And even though the Rails happy path uses Bundler to manage dependencies, that happy path is limited to the generated code only. The Rails library itself does <em>not</em> rely on Rubygems, Bundler, or any package manager. This makes using a different package manager, like Debian or rip, as simple as changing a few lines of the generated code.</p>
<h2>Instrumentation</h2>
<p>A number of companies and projects have sprung up over the years attempting to provide useful information about the runtime status of a Rails process. In order to facilitate this work going forward, we've baked instrumentation into Rails itself. Instead of having to monkey-patch an appropriate method to learn about which templates Rails renders, for instance, simply listen for an event. While Rails has never officially supported the monkey-patching approach, we will commit to supporting instrumentation events in the same way as we support any other public APIs, making them future-proof stable ways to learn about what's happening inside of Rails.</p>
<p>Better yet, Rails' logging system uses these very events to emit information into the log!</p>
<h2>Every Framework is an Extension</h2>
<p>In what is possibly the biggest conceptual shift in Rails 3, we've exposed an extension API that allowed us to make ActiveRecord, ActionController, and ActionMailer simple Rails extensions. In other words, the DataMapper ORM can take a look at the part of ActiveRecord that implements its Rails extension, implement similar features, and know for sure that it'll work. Additionally, users can completely remove the ActiveRecord gem, and be rid of the generators, rake tasks and other peripheral elements. An example: if DataMapper implements a <code>db:test:prepare</code> rake task, a Rails developer can replace ActiveRecord with DataMapper, and the <code>test:units</code> rake task will use DataMapper's new tasks.</p>
<p>In short, we have completely removed references to other frameworks from Railties itself, making the frameworks of Rails true extensions to Rails itself. This makes it possible to replace any part of Rails without having to worry about entanglements with Railties.</p>
<h2>Rack</h2>
<p>Rails 2.3 took a very firm stance in favor of Rack. Rails 3 completes the story. In Rails 3, the Application itself, the router, and controller actions themselves are all Rack applications. Rails ships with a standard config.ru, and can boot using the <code>rackup</code> tool that ships with Rack, or with Passenger or Glassfish in standard Rack mode. In fact, any Rails host or server that supports the Rack protocol can run a Rails 3 application unaltered.</p>
<p>Because so many parts of Rails are Rack, you can also insert standard Rack middleware in config.ru, in your Rails application, in the router, or even in a controller's actions. Rails itself ships with a number of standard middlewares, for exception handling, cookies, parameter parsing, flash notifications, sessions and a bunch more. You can use any of these middlewares in standard Rack applications (without Rails).</p>
<h2>ActionController</h2>
<p>ActionController got a major overhaul, dividing up a monolithic component into multiple pieces.</p>
<h3>ActionDispatch</h3>
<p>You can think of ActionDispatch as rack-ext. Essentially, we packaged up all of the parts of ActionController involved in the Rack dispatching process into a single reusable component. This includes ActionDispatch::Request, ActionDispatch::Response, our mime type handling, a bunch of middleware, and integration testing support.</p>
<p>It also includes a wrapper around <code>rack-mount</code> a new powerful routing library. Josh Peek, a member of the Rails Core Team, wrote <code>rack-mount</code> as a standalone component, so that it could be used in standard Rack projects without any Rails dependencies. By default, it simply dispatches inbound requests to Rack endpoints.</p>
<p>Because Rails 3 controller actions are Rack endpoints, Josh could easily wire up a thin shim around <code>rack-mount</code> to dispatch inbound requests to Rails controller actions. But because we built the Rails router on top of <code>rack-mount</code>, Rails applications can route inbound requests to <strong>any</strong> Rack application, like Sinatra or <a href="http://getcloudkit.com/">Cloudkit</a>.</p>
<h3>AbstractController</h3>
<p>The disparity between ActionController and ActionMailer has long been a personal pet peeve of mine. For Rails 3, we refactored ActionController and ActionMailer to inherit from a common superclass: AbstractController. AbstractController includes the basic concept of controllers, rendering, layouts, helpers, and callbacks, but nothing about HTTP or mail delivery. This means that ActionMailer can no longer drift away from ActionController, leaving us with two distant cousin APIs.</p>
<h3>ActionController</h3>
<p>ActionController got a big overhaul, completely eliminating <code>alias_method_chain</code> in favor of a module-based system that extension author can more easily extend. For instance, we exposed a Renderer interface, allowing extension authors to easily add <code>render :pdf</code> or <code>render :csv</code> without having to override the <code>render</code> method in brittle ways.</p>
<p>While the API did not change much in general, we did add a few new features, such as the ability to add middleware directly to a controller's actions or the ability to wrap up common idioms more cleanly using responders. Additionally, we improved the overall architecture to reduce the need for certain hacks.</p>
<p>For instance, ActionController will now look up the layout for an action using the details (such as format and locale) that its template used. In Rails 2.3, an RJS template could end up using an HTML layout, requiring us to exempt RJS templates from layouts altogether. However, this was a band-aid (what if you <strong>wanted</strong> an RJS layout?) and the improved architecture eliminates the possibility for other, similar problems.</p>
<h3>ActionView</h3>
<p>ActionView got a significant overhaul, improving its internal architecture, increasing performance, adding pervasive XSS protection, and making all JavaScript helpers unobtrusive.</p>
<p>In terms of architecture, Rails 3 defines a clear boundary between ActionController and ActionView. Now, ActionView exposes a single API entry point for rendering templates and partials, making the code path easier to understand, eliminating a number of latent (but unusual) bugs, and making it easier to reason about caching lookups for performance.</p>
<p>When doing a performance audit of Rails applications, ActiveRecord and ActionView (specifically, template rendering) pop up as major costs. In particular, ActionView has had a fair bit of overhead that's impossible to avoid without throwing certain features out the window. For instance, partials and especially collections of partials had enough overhead to become noticeable on profiles of real applications.</p>
<p>In Rails 3, we optimized both the template lookup logic (which should now take up extremely small amounts of time) and the logic inside the loop of partial collections. In particular, partial collections should often be much faster in Rails 3 than a manual loop, and not much slower than manually inlining and unrolling the loop. Finally, the improved architecture has made additional optimizations possible, so expect further performance improvements in Rails 3.1.</p>
<p>We also switched to Erubis, a fully compatible ERB implementation with much better extensibility characteristics. In particular, it allows us to easily hook in the code that it generates for any ERB construct. This will allow compile-time performance optimizations in the future and enables the next feature: pervasive XSS protection.</p>
<p>Rails has always shipped with a simple way to escape any user-generated content. Unfortunately, this required constant vigilance. A number of highly visible, successful attacks against websites on a number of platforms taught the world that successful mitigation of this threat requires treating all Strings as suspicious, and allowing developers to mark Strings as safe. Rails 3 escapes all Strings, allowing developers to convert Strings into safe Strings easily. We have also modified all of our internal helpers to mark Strings that we create as safe, while not modifying Strings passed in by the application developer.</p>
<p>Finally, we have overhauled all of the JavaScript helpers to emit plain HTML markup instead of JavaScript. As part of the process, we have created drivers for jQuery and Prototype that bind events to the appropriately marked up elements in the DOM. This means that Rails can now support any JavaScript library as a first-class citizen. We will support and maintain the markup and JavaScript developers can develop pure-JavaScript libraries to make use of the markup (without ever having to touch Ruby). If other frameworks emit the same markup, the same JavaScript libraries will work with their helpers.</p>
<h2>ActiveModel</h2>
<p>Over the years, people have created a number of ActiveRecord lookalike libraries for things like MongoDB or CouchDB. In Rails 3, we have extracted elements of ActiveRecord unrelated to RDBMS persistence, such as validations, callbacks, dirty tracking, and serialization into a separate library. Other libraries, or even plain old Ruby code, can use these components on an à la carte basis, choosing to look as much or as little like ActiveRecord as they wish.</p>
<p>Additionally, ActiveModel defines an API that any object can implement in order to work seamlessly with ActionPack. It provides drop-in implementations of the API, but Ruby libraries that wish to participate may implement the APIs themselves. This means that ActionPack itself is agnostic as to the ORM used, and even supports hand-rolled models.</p>
<h2>ActiveRecord</h2>
<p>ActiveRecord has undergone a large internal change, integrating <a href="http://twitter.com/Nk">Nick Kallen's</a> <a href="http://github.com/brynary/arel">ActiveRelation</a> codebase. This replaces the internal ad-hoc query generation with query generation based on relational algebra. In essence, it means that you can chain queries for refinement before Rails builds the actual SQL query.</p>
<p>For instance, instead of <code>Post.scoped</code> immediately connecting to the database and retrieving all posts, it creates a relation object representing the idea of "all posts". You can then refine further, such as <code>Post.scoped.where(:author =&gt; "Yehuda")</code>. This means that you can pass around relations, refining them as appropriate in helper methods before the view finally kicks off the query when it iterates over the objects.</p>
<p>This also unifies similar concepts in ActiveRecord, like named scopes, into a single relational concept that pervades the entire ORM.</p>
<h2>ActiveSupport</h2>
<p>In order to facilitate use of ActiveSupport by other libraries, ActiveSupport 3.0 makes it easy for developers to cherry-pick specific parts of the library they wish to use. In particular, we have made all dependencies between ActiveSupport files explicit, so that if you require a particular extension, you can be sure that you get everything that you need. In the past, in order to use ActiveSupport extensions reliably, you needed to require the full library.</p>
<p>ActiveSupport also comes with some new and retooled modules, such as ActiveSupport::Concern (which makes it easier to manage dependencies between modules) and a significantly faster ActiveSupport::Callbacks.</p>
<h2>Railties</h2>
<p>We made the biggest user-facing changes in Railties. A Rails 3 application is an object (of the class Rails::Application), which also doubles as a valid Rack application. Instead of configuring your application in a block, you configure the Application itself (which now lives in config/application.rb).</p>
<p>The Rails::Application class also inherits from an Engine class, making Engines behave almost identically to Applications, as appropriate. And Engines are a special kind of Railtie, again simplifying and unifying the concepts in the Rails glue code.</p>
<p>The <code>rails</code> command itself now has special powers inside of Rails applications, replacing the commands in <code>script</code> with subcommands of <code>rails</code>. For instance, use <code>rails server</code> instead of <code>script/server</code>.</p>
<h2>In Conclusion...</h2>
<p>It's been an incredibly busy and productive year. Rails 3 is the culmination of thousands of man-hours by numerous dedicated open source contributors. It's been a long journey, filled with debate, feedback, and writing code, refactoring it and  then refactoring it yet again. While this release is just a beta, it represents the bulk of things to come in a stable and tested state.</p>
<p>Plugin authors should take a look at the new exposed APIs and start porting plugins to work on Rails 3. The community is excited, and we expect adoption to be rapid, aggressive and just as importantly, vocal. We'll be listening to that feedback to help get Rails 3 to its final perfected state, and you should be listening too, so your plugins can make the jump with us.</p>
<p>Leave comments here and on the official <a href="http://weblog.rubyonrails.org/">Ruby on Rails blog</a>; we'll be here to respond!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/rails-3-beta-is-out-a-retrospective/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>Rails and Merb Merge: Rails Core (Part 4 of 6)</title>
		<link>http://www.engineyard.com/blog/2010/rails-and-merb-merge-rails-core-part-4-of-6/</link>
		<comments>http://www.engineyard.com/blog/2010/rails-and-merb-merge-rails-core-part-4-of-6/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 20:00:58 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails 3]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3364</guid>
		<description><![CDATA[<p>After working to make Rails <a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/">faster</a> and more <a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-the-anniversary-part-1-of-6/">modular</a>, we took a look at the glue code holding Rails together: Railties. Railties started life as a relatively modest piece of code in the early days of Rails, but it eventually grew to encompass quite a few different areas. For instance, Rails 2.3 included quite a bit of code for managing plugins, and some additional code for managing gems. Adding in explicit support for engines meant yet <em>more</em> code.</p>
<p>In isolation, each of these pieces of code made a lot of sense as they were added, but as the pieces accumulated, plugin authors, and even Rails itself, had to often resort to contortions to get the job done. Our goal in Rails 3 was to solve these problems.</p>
<h2>An Application Object</h2>
<p>The first thing we addressed was that a Rails 2.3 application had pieces spread out in a number of places. For example, it stored the configuration on a global configuration object, stored the routes on a global router object, and booted up the server and console from this collection of global state. It also looked up plugins using PluginLocators and PluginLoaders. While all of this <strong>worked</strong>, we found it difficult to reason about and it was easy to trip over when implementing new features. We wanted to unify these pieces.</p>
<p>Second, we wanted to make it possible to run multiple applications in a single process. This meant we had to remove as much global state as possible. We will likely be continuing to work toward this goal over the next several releases, but the nice thing is that removing global state has already resulted in improvements in code quality and we have found that it makes code easier to understand.</p>
<p>If you take a look at a newly generated Rails 3 app, you now find a named application.</p>
<pre lang="ruby">module YourApp
  class Application &lt; Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Add additional load paths for your own custom dirs
    # config.load_paths += %W( #{config.root}/extras )

    # Only load the plugins named here, in the order given (default is alphabetical).
    # :all can be used as a placeholder for all plugins not explicitly named
    # config.plugins = [ :exception_notification, :ssl_requirement, :all ]

    # Activate observers that should always be running
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US &amp; Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
    # config.i18n.default_locale = :de

    # Configure generators values. Many other options are available, be sure to check the documentation.
    # config.generators do |g|
    #   g.orm             :active_record
    #   g.template_engine :erb
    #   g.test_framework  :test_unit, :fixture =&gt; true
    # end
  end
end</pre>
<p>This looks a whole lot like the initializer block in Rails 2.3, but the Application object, not a global configuration object, now has the configuration information. Similarly, <code>routes.rb</code> now begins <code>YourApp::Application.routes.draw</code>. The application object lives in the center of Railties in Rails 3, providing a core object that the rest of the frameworks can build on.</p>
<h2>Improving Initialization</h2>
<p>Rails 2.3 initialized a Rails application by calling a number of methods in sequence. Correct operation relied heavily on the order of those methods, and Rails ran some methods multiple times (apparently to hack around long-forgotten issues). As a next step towards getting a grip on Railties, we refactored the initializers so that Rails declared each initializer separately in a way that users could easily hook into.</p>
<p>This idea originated in Merb, where the framework defined each initializer as a separate class. Merb also provided a mechanism for declaring in the class body, that the framework should run a particular initializer before or after another one. By breaking the initializers up into reusable chunks, we provided a convenient API for extensions to hook in at whatever part of the process they wanted to.</p>
<p>In Rails 3, we have defined a slightly different API, inspired by the same ideas.</p>
<pre lang="ruby">initializer :load_all_active_support do
  require "active_support/all" unless config.active_support.bare
end

# Set the <tt>$LOAD_PATH</tt> based on the value of
# Configuration#load_paths. Duplicates are removed.
initializer :set_load_path do
  config.paths.add_to_load_path
  $LOAD_PATH.uniq!
end</pre>
<p>These first initializers in the Rails bootup process require <code>active_support/all</code> and set the load paths. Each initializer has a name, which allows other initializers (in plugins) to hook in at the appropriate time. Initializers also have access to the configuration object.</p>
<p>Making initializers their own isolated chunks definitely improves the code, and exposed a number of issues in the existing initializers. With initializers now living on the brand new application object, we then took a hard look at plugins.</p>
<h2>Unifying Plugins</h2>
<p>We wanted to unify plugins into one coherent system. Rails 2.3 supported several different kinds of plugins: <code>vendor/plugins</code>, gem plugins, <code>vendor/plugins</code> engines, and gem engines.</p>
<p>Rails 2.3 had a number of objects to find and load each kind of plugin, that resulted in a certain amount of magical behavior in each case. For instance, it automatically ran <code>init.rb</code> for plugins in <code>vendor/plugins</code> at the appropriate time. For Rails 3, we have created a new class, called Rails::Plugin, that can itself set configuration and have initializers. Rails 3 now merges in those initializers, giving plugins the ability to directly participate in the initialization process.</p>
<p>Each plugin in <code>vendor/plugins</code> automatically become a <code>Rails::Plugin</code>, but we also allow gems to explicitly create a subclass and add their own initialization. This makes plugins more powerful, giving them the ability to hook in at more precise parts of the process.</p>
<pre lang="ruby">initializer :load_init_rb, :before =&gt; :load_application_initializers do |app|
  file   = "#{@path}/init.rb"
  config = app.config
  eval File.read(file), binding, file if File.file?(file)
end</pre>
<p>Here, <code>vendor/plugins</code> defines an initializer called <code>:load_init_rb</code>, which runs <em>before</em> the application initializers. The block receives the application object, so it can take a look at the configuration, or other parts of the application in question.</p>
<h2>Railties (Or, How Frameworks Became Plugins)</h2>
<p>After making all of this progress, we revisited an earlier mission set out at the beginning of the merge: make all frameworks, like ActiveRecord and ActionController, behave like regular plugins. This would allow other plugins, like DataMapper, to use exactly the same APIs used by ActiveRecord. By definition, other projects could then replace all the functionality in ActiveRecord in a self-contained gem.</p>
<p>After moving each initializer into its own block, we noticed that a large number of the initializers were wrapped in <code>if config.frameworks.include?(:active_record)</code> and the like. If we fixed this, we could make good on our promise to make each framework a plugin. So now, instead of having Railties inspect the list of available frameworks and run appropriate initializers, the frameworks themselves add their own initializers, <strong>but only when loaded</strong>. When the user loads ActiveRecord, its plugin adds its initializers; when the user loads DataMapper, <em>its</em> plugin adds <em>its</em> initializers.</p>
<p>The monolithic Railties framework is now a set of individual Railties, each inheriting from a new class, Rails::Railtie. Railties has more power than simple plugins. For instance, a Railtie's name also serves as its key in the configuration object. And a Railtie can also specify rake tasks. For instance, if the user chooses DataMapper instead of ActiveRecord, he only sees DataMapper's rake tasks.</p>
<p>Because Railties merely specifies how Rails initializes them, requiring them has no side-effects. Taking a look at the ActiveRecord Railtie, you can see that the file first requires "rails" and "action_controller/railtie", ensuring that Rails runs the ActionController initializers before the ActiveRecord ones. It also allows ActiveRecord to define initializers that run before or after ActionController initializers.</p>
<p>Exposing an API to allow ActiveRecord to run decoupled from Railties forced us to enable functionality for third parties. For instance, because Rails loads Railties before initialization, this allows third-party plugins to hook into the very earliest stages of the process. By making the keys on <code>config</code> more general, we now can have <code>config.data_mapper </code>as well as <code>config.active_record</code>. By moving rake tasks and generators to the frameworks, and triggering them through the Railtie, Rails guarantees that the user can remove all artifacts of these frameworks by installing an alternative plugin. It also means that any plugin can add these artifacts.</p>
<p>Most usefully, it moves everything about how Rails should initialize ActiveRecord in a different context, such as booting up an app, running rake tasks, or running generators, into a single location that we can more easily maintain and that others can more easily copy. We think this will result in people being able to easily write Rails extensions that behave similarly to builtin Rails frameworks.</p>
<p>In short, Rails frameworks are now plugins to Rails.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/rails-and-merb-merge-rails-core-part-4-of-6/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Render Options in Rails 3</title>
		<link>http://www.engineyard.com/blog/2010/render-options-in-rails-3/</link>
		<comments>http://www.engineyard.com/blog/2010/render-options-in-rails-3/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 19:30:23 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[ActionController]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Newsletter]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails 3]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3201</guid>
		<description><![CDATA[<p><em>This article was originally included in the October issue of the Engine Yard Newsletter. To read more posts like this one, subscribe to the </em><a href="http://www.engineyard.com/newsletter"><em>Engine Yard Newsletter</em></a><em>.</em></p>
<p><em>In </em><strong><em>Inside Rails</em></strong><em>, Yehuda Katz, Rails expert and core team member, and Carl Lerche, Rails expert and full-time contributor, present expert advice and insight on the Rails platform and Rails development.</em></p>
<hr />In previous versions of Rails, adding a new rendering option to Rails required performing an <code>alias_method_chain</code> on the render method, adding your new options, and hoping they didn't conflict with any of the other code in the rendering pipeline.</p>
<p>Rails 3 makes rendering options a first class citizen, and uses the same new system internally that plugins authors are expected to use. Before we get into how you can use this feature yourself, let's take a look at how Rails uses it:</p>
<pre lang="ruby" escaped="true">ActionController.add_renderer :json do |json, options|
 json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
 json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
 self.content_type ||= Mime::JSON
 self.response_body = json
end</pre>
<p>Here, we are creating a new <code>render :json</code> option, which behaves exactly like <code>render :json</code> in Rails 2.3. In the <code>render_json method</code>, we use the same lower-level (but still public) APIs that are used by Rails itself to set the MIME type and response body. Using a render option entirely skips the rest of the render pipeline, so you don't have to worry about blocking normal template selection and rendering, or any other internal changes that might break your added option.</p>
<p>Next, let's take a look at adding a new render :pdf option. We'll use JRuby and the Flying Saucer library, which takes HTML and CSS and converts it to a PDF file. The syntax for the new option will be <code>render :pdf =&gt; "template_name", :css =&gt; %w(main.css print.pdf), :layout =&gt; "print"</code>.</p>
<p>In order to understand how to do this, let's first take a look at the code necessary to use Flying Saucer in JRuby. First, you'll need to grab the Flying Saucer jars (you can get them from my Muse git repo). Next, let's write the code necessary to convert HTML and CSS to PDF with Flying Saucer:</p>
<pre lang="ruby" escaped="true"># Both of these are .jar files
require "/path/to/itext"
require "/path/to/core-renderer"

module PdfUtils
 def self.string_to_pdf(input_string)
  io = StringIO.new
  renderer = org.xhtmlrenderer.pdf.ITextRenderer.new
  renderer.set_document_from_string_input input_string
  renderer.layout
  renderer.create_pdf(io.to_outputstream)
  io.string # the PDF file in a String
 end
end</pre>
<p>It's a bit verbose, but it does work. Now that we have a way to make the PDF, let's wire it up into a render option.</p>
<pre lang="ruby" escaped="true">ActionController.add_renderer :pdf do |template, options|
 css_files = Array.wrap(options.delete(:css))
 css = css_files.map {|file| File.read(file) }.join("\n")

 # Reuse the render semantics to get a string from the
 # template and options
 string = render_to_string template, options

 # Drop in the CSS before the  in a style tag.
 # In practice, you would probably cache the file reads
 # and the merging of the CSS and HTML.
 string.gsub!(%r{}, "
<!--
#{css}
-->

")
 send_data PdfUtils.string_to_pdf(string), :type =&gt; Mime::PDF
end</pre>
<p>You'd also need to register the PDF mime type:</p>
<pre lang="ruby" escaped="true">Mime::Type.register "application/pdf", :pdf</pre>
<p>You could now do the following in a controller:</p>
<pre lang="ruby" escaped="true">class PostsController &lt; ActionController::Base
 def show
  @post = Post.find(params[:id])

  respond_to do |format|
   format.html
   format.pdf
   # or
   format.pdf { render :pdf =&gt; "show", :css =&gt; %w(application print) }
  end
 end
end</pre>
<p>The tricky bits of this process are now reserved to figuring out how to build and return the output, not how to inject your option into render. Pretty cool, no?
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/render-options-in-rails-3/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Rails and Merb Merge: Plugin API (Part 3 of 6)</title>
		<link>http://www.engineyard.com/blog/2010/rails-and-merb-merge-plugin-api-part-3-of-6/</link>
		<comments>http://www.engineyard.com/blog/2010/rails-and-merb-merge-plugin-api-part-3-of-6/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 18:00:56 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ActionController]]></category>
		<category><![CDATA[ActionView]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails 3]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3188</guid>
		<description><![CDATA[<p>I started off this series on the Rails/Merb merge (aka Rails 3) talking about <a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-the-anniversary-part-1-of-6/">modularity</a>, and then <a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/">performance</a>. Next up, plugins!</p>
<p>When we announced the Rails/Merb merge,  we promised to bring a more stable plugin API to Rails 3.  Merb had strong opinions about an explicitly exposed plugin API, so we hoped to end the complications of <code>alias_method_chain</code> in favor of exposed APIs which plugin authors could rely on across versions.</p>
<h2>Dogfooding</h2>
<p>By far the most important element in developing the plugin APIs for Rails 3 was to eliminate the "secret" APIs used in Rails itself. Instead, we wanted to build Rails on top of the same core components that we would ask plugin authors to build on. The focal point of this effort (because we already had experience doing this with Merb) was ActionPack, and specifically ActionController.</p>
<p>ActionController presented us with another excellent opportunity: because ActionMailer reused a lot of the controller functionality, we had a built-in opportunity to create components that could be used in both ActionController and ActionMailer. In a sense, ActionController and ActionMailer would become plugins of the core system we were creating.</p>
<p>We also took a second important conceptual step. In Rails 2.3, the idea of "metal" was that you could skip the entire ActionController chain and write raw Rack handlers where needed for performance. In Rails 3, we are exposing an incremental series of components that, in sum, make up <code>ActionController::Base</code>. These components include rendering, layouts, conditional get, respond_to, streaming, and others.</p>
<p>In Rails 3, <code>ActionController::Metal</code> is the simplest possible controller, with no additional components added in. <code>ActionController::Base</code> is simply a subclass of <code>ActionController::Metal</code> with all components included. Again, we are dog-fooding our componentized APIs, not simply giving you a watered down version of what we use internally.</p>
<p>Now, let's dig into a few specific examples of new APIs.</p>
<h2>ActionController::Renderers</h2>
<p>One of the most common reasons people extend controllers is to expose additional renderers. For instance, you may want to render a PDF as well as HTML. The Rails 3 API that we expose to plugin authors for this purpose is identical to the one that we use internally.  (As you probably know, in addition to being able to render templates, you can render <code>:json</code>, <code>:xml</code>, or <code>:js</code> in normal Rails controllers.)</p>
<p>If you take a look at the source for <code>ActionController::Renderers</code>, here's how we do it:</p>
<pre lang="ruby">add :json do |json, options|
  json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
  json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
  self.content_type ||= Mime::JSON
  self.response_body  = json
end</pre>
<p>This method is in <code>ActionController::Renderers</code>, so it's like saying <code>ActionController::Renderers.add(:json) do |json, options|</code>. You can add additional renderers easily in Rails 3 plugins, and you don''t have to figure out how to hook into Rails at the appropriate time. Like other parts of the public API, we're committing to keeping this API unchanged across multiple versions of Rails. If and when when the API <strong>DOES</strong> change, the change will be flagged for you first, via the normal Rails API deprecation process.</p>
<h2>ActionController::Metal</h2>
<p>In Rails 3, there's a supported way to use a simple, stripped down controller, and opt into the functionality you want. The overhead of the completely stripped down controller is a mere 8 microseconds (not much more than the overhead for a pure Rack app), compared with 100 or so microseconds of overhead for the full <code>ActionController::Base</code> (as I said last time, <a href="http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/">this itself is <em>significantly</em> less</a> than Rails 2.3).</p>
<p>Here's an example of using <code>ActionController::Metal</code>:</p>
<pre lang="ruby">class SimpleController < ActionController::Metal
  abstract!
end

class HelloController < SimpleController
  def index
    self.response_body = "Hello World"
  end
end</pre>
<p>A few things to note here. First of all, you don't need a superclass, but you can build one to re-use in multiple places. The <code>abstract!</code> declaration tells Rails 3 not to include public methods on the superclass as controller actions. It's not strictly needed here (because there are no public methods), but it's a good habit for custom <code>ActionController::Metal</code> subclasses. Second of all, because this is a controller, you can route to it through the normal Rails router. From the perspective of the rest of Rails, this is a perfectly normal controller.</p>
<p>Finally, the <code>self.response_body</code> usage is the simple, low-level API used in <code>ActionController</code> itself (for instance, during template rendering), but it's now 100% first-class and available for your use. You can also set <code>status</code>, <code>content_type</code> and <code>headers</code> directly, regardless of whether you use the <code>Request</code> and <code>Response</code> helpers or not.</p>
<p>If you want to add rendering in, you can do something like this:
</pre>
<pre lang="ruby">class SimpleController < ActionController::Metal
  abstract!
  include ActionController::Rendering
  append_view_path "#{Rails.root}/app/views"
end

class HelloController  "hello"
  end
end</pre>
<p>You've now added in a new module, which provides rendering support. This keeps things simple by not including layout support, because you don't need it in this case. With this capability, you can add the features that you want to add, leaving out what you don't. This means that as a metal grows, you don't need to completely rewrite it as a "normal" controller. Instead, you can pull in the specific features you need. This process is seamless, and again, you can route to it as a normal controller throughout.</p>
<p>If you look at the source for <code>ActionController::Base</code>, you can see that we aren't doing anything particularly special anymore:
</pre>
<pre lang="ruby">module ActionController
  class Base < Metal
    abstract!

    include AbstractController::Callbacks
    include AbstractController::Layouts

    include ActionController::Helpers
    helper :all # By default, all helpers should be included

    include ActionController::HideActions
    include ActionController::UrlFor
    include ActionController::Redirecting
    include ActionController::Rendering
    include ActionController::Renderers::All
    include ActionController::ConditionalGet
    include ActionController::RackDelegation
    include ActionController::Logger
    include ActionController::Configuration
    ...</pre>
<p>Here, <code>ActionController::Base</code> inherits from <code>Metal</code>, and then proceeds to pull in all of the functionality not exposed as separate modules. Although <code>Base</code> pulls them all in, you don't have to worry about dependencies between these modules; handling dependencies is built into the way these modules work.</p>
<h2>View Contexts</h2>
<p>As one last example, the way that ActionController communicates with ActionView itself has become a fully defined, exposed API. From the perspective of ActionController, a view implements three APIs:</p>
<ul>
<li><code>Context.for_controller(controller)</code></li>
<li><code>Context#render_partial(options)</code></li>
<li><code>Context#render_template(template, layout, options)</code></li>
</ul>
<p>By implementing this API, you can drop in any object in place of ActionView. How would you use this? Well to date, I can think of two examples: rspec_rails is going to use this functionality to implement isolation tests, and you can use this to implement a Merb shim in which the controller and view are the same object (<a href="http://yehudakatz.com/2009/07/19/rails-3-the-great-decoupling/">an implementation using an earlier version of the API</a>).</p>
<p>In addition to the usefulness of exposing this functionality via a stable Public API, reducing the boundary between ActionController and ActionView significantly improved the architecture, and exposed areas of brittleness that benefited quite a bit from the definition.</p>
<h2>Conclusion</h2>
<p>The APIs provided here, while stable at this point, are not final. If you feel that they (or any other part of Rails 3) aren't adequate for a plugin you're building, please let us know by commenting.</p>
<p>This post is just a taste of the new ways you can extend Rails 3. In the weeks ahead, expect a lot more documentation and discussion about the exposed plugin hooks.</pre>
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/rails-and-merb-merge-plugin-api-part-3-of-6/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Rails and Merb Merge: Performance (Part 2 of 6)</title>
		<link>http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/</link>
		<comments>http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 21:45:32 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Merb]]></category>
		<category><![CDATA[Rails 3]]></category>
		<category><![CDATA[Rails Performance]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3099</guid>
		<description><![CDATA[<p>The next significant improvement that we hoped to bring to Rails from Merb was faster performance. Because Merb came after Rails, we had the luxury of knowing which parts of Rails were used most often and optimizing performance for those parts.</p>
<p>For Rails 3, we wanted to take the performance optimizations in Merb and bring them over to Rails. In this post, I'll talk about just a few of the performance optimizations we've added to Rails 3: reducing general controller overhead and (greatly) speeding up rendering a collection of partials.</p>
<p>For our initial performance work, we focused on a few specific but commonly used parts of Rails:</p>
<ul>
<li>General overhead (the router plus the cost of getting in and out of a controller)</li>
<li>render :text</li>
<li>render :template</li>
<li>render :partial</li>
<li>rendering a number (10 and 100) of the same partials in a loop</li>
<li>rendering a number (10 and 100) of the same partials via the collection feature</li>
</ul>
<p>This was definitely a limited evaluation, but it covered most of the cases where performance might be at a premium and the Rails developer was unable to do anything about it.</p>
<h2><strong>General Controller Overhead</strong></h2>
<p>The first thing was improving the general overhead of a Rails controller. Rails 2.3 doesn't have any way to test this, because you're forced to use <code>render :string</code> to send back text to the client, which implicates the render pipeline. Still, we wanted to reduce it as much as possible.</p>
<p>When doing this work, we used Stefan Kaes' fork of ruby-prof that comes with the <code>CallStackPrinter</code> (the best way I've ever seen to visualize profile data from a Ruby application.) We also wrote a number of benchmarks that could double as profile runs if I wanted to zero in and get more precise data.</p>
<p>When we looked at overhead, it was dominated by setting the response. Digging a bit deeper, it turned out that ActionController was setting headers directly, which then needed to be re-parsed before returning the response to get additional information. A good example of this phenomenon was in the <code>Content-Type</code> header, which had two components (the content-type itself and an optional charset). The two components were available on the Response object as getters and setters:</p>
<pre lang="ruby">def content_type=(mime_type)
  self.headers["Content-Type"] =
    if mime_type =~ /charset/ || (c = charset).nil?
      mime_type.to_s
    else
      "#{mime_type}; charset=#{c}"
    end
end

# Returns the response's content MIME type, or nil if content type has been set.
def content_type
  content_type = String(headers["Content-Type"] || headers["type"]).split(";")[0]
  content_type.blank? ? nil : content_type
end

# Set the charset of the Content-Type header. Set to nil to remove it.
# If no content type is set, it defaults to HTML.
def charset=(charset)
  headers["Content-Type"] =
    if charset
      "#{content_type || Mime::HTML}; charset=#{charset}"
    else
      content_type || Mime::HTML.to_s
    end
end

def charset
  charset = String(headers["Content-Type"] || headers["type"]).split(";")[1]
  charset.blank? ? nil : charset.strip.split("=")[1]
end</pre>
<p>As you can see, the Response object was working directly against the <code>Content-Type</code> header, and parsing out the part of the header as needed. This was especially problematic because as part of preparing the response to be sent back to the client, the Response did additional work on the headers:</p>
<pre lang="ruby">def assign_default_content_type_and_charset!
  self.content_type ||= Mime::HTML
  self.charset ||= default_charset unless sending_file?
end</pre>
<p>So before sending the response, Rails was once again splitting the <code>Content-Type</code> header over semicolon, and then doing some more String work to put it back together again. And of course, <code>Response#content_type=</code> was used in other parts of Rails, so that it was correctly set based on the template type or via <code>respond_to</code> blocks.</p>
<p>This was not costing hundreds of milliseconds per request, but in applications that are extremely cache-heavy, the overhead cost could be larger than the cost of pulling something out of cache and returning it to the client.</p>
<p>The solution in this case was to store the content type and charset in instance variables in the response, and merge them in a quick, simple operation when preparing the response.</p>
<pre lang="ruby">attr_accessor :charset, :content_type

def assign_default_content_type_and_charset!
  return if headers[CONTENT_TYPE].present?

  @content_type ||= Mime::HTML
  @charset      ||= self.class.default_charset

  type = @content_type.to_s.dup
  type < < "; charset=#{@charset}" unless @sending_file

  headers[CONTENT_TYPE] = type
end</pre>
<p>So now, we're just looking up instance variables and creating a single String. A number of changes along these lines got overhead down from about 400usec to 100usec. Again, not a huge amount of time, but it could really add up in performance-sensitive applications.</p>
<h2>Render Collections of Partials</h2>
<p>Rendering collections of partials presented another good opportunity for optimization. And this time, the improvement ranked in milliseconds not microseconds!</p>
<p>First, here was the Rails 2.3 implementation:
</pre>
<pre lang="ruby">def render_partial_collection(options = {}) #:nodoc:
  return nil if options[:collection].blank?

  partial = options[:partial]
  spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : ''
  local_assigns = options[:locals] ? options[:locals].clone : {}
  as = options[:as]

  index = 0
  options[:collection].map do |object|
    _partial_path ||= partial ||
      ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
    template = _pick_partial_template(_partial_path)
    local_assigns[template.counter_name] = index
    result = template.render_partial(self, object, local_assigns.dup, as)
    index += 1
    result
  end.join(spacer).html_safe!
end</pre>
<p>The important part here is what happened inside the loop, which could occur hundreds of times in a large collection of partials. Here, Merb had a higher performance implementation which we were able to bring over to Rails. This is the Merb implementation.</p>
<pre lang="ruby">with = [opts.delete(:with)].flatten
as = (opts.delete(:as) || template.match(%r[(?:.*/)?_([^\./]*)])[1]).to_sym

# Ensure that as is in the locals hash even if it isn't passed in here
# so that it's included in the preamble.
locals = opts.merge(:collection_index => -1, :collection_size => with.size, as => opts[as])
template_method, template_location = _template_for(
  template,
  opts.delete(:format) || content_type,
  kontroller,
  template_path,
  locals.keys)

# this handles an edge-case where the name of the partial is _foo.* and your opts
# have :foo as a key.
named_local = opts.key?(as)

sent_template = with.map do |temp|
  locals[as] = temp unless named_local

  if template_method && self.respond_to?(template_method)
    locals[:collection_index] += 1
    send(template_method, locals)
  else
    raise TemplateNotFound, "Could not find template at #{template_location}.*"
  end
end.join

sent_template</pre>
<p>Now this wasn't perfect by a long shot. There was a lot going on here (and I'd personally like to have seen the method refactored). But the interesting part is what happened inside the loop (starting from <code>sent_template = with.map</code>). Unlike ActionView, which figured out the name of the template, got the template object, got the counter name, and so on, Merb limited the activity inside the loop to setting a couple of Hash values and calling a method.</p>
<p>For a collection of 100 partials, this could be the difference between overhead of around 10ms and overhead of around 3ms. For a collection of small partials, this could be significant (and a reason to inline partials that were appropriate to be partials in the first place).</p>
<p>In Rails 3, we've improved performance by reducing what happens inside the loop. Unfortunately,there was a specific feature of Rails that made it a bit harder to optimize this generically. Specifically, you could render a partial with a heterogenous collection (a collection containing Post, Article and Page objects, for instance) and Rails would render the correct template for each object (Article objects render <code>_article.html.erb</code>, etc.). This means that it was not always possible to determine the template to render up front.</p>
<p>In order to deal with this problem, we haven't been able to optimize the heterogenous case completely, but we have made <code>render :partial => "name", :collection => @array</code> faster. In order to achieve this, we split the code paths, with a fast path for when we knew the template, and a slow path for where it had to be determined based on the object.</p>
<p>So now, here's what rendering a collection looks like, when we know the template:</p>
<pre lang="ruby">def collection_with_template(template = @template)
  segments, locals, as = [], @locals, @options[:as] || template.variable_name

  counter_name  = template.counter_name
  locals[counter_name] = -1

  @collection.each do |object|
    locals[counter_name] += 1
    locals[as] = object

    segments < < template.render(@view, locals)
  end

  @template = template
  segments
end</pre>
<p>Importantly, the loop is now tiny (even simpler than what happened in Merb inside the loop). Something else worth mentioning is that in improving the performance of this code, we created a PartialRenderer object to track state. Even though you might expect that creating a new object would be expensive, it turns out that object allocations are relatively cheap in Ruby, and objects can provide opportunities for caching that are more difficult in procedural code.</p>
<p>For those of you want to see the improvements in pictures, here are a few things to look at: first, we have the improvement between Rails 2.3 and Rails 3 edge on Ruby 1.9 (smaller is faster).</p>
<p><img src="http://eyweb-images.s3.amazonaws.com/blog_19big.jpg" alt="" width="565" height="317" /></p>
<p>And here it is for more expensive operations:</p>
<p><img src="http://eyweb-images.s3.amazonaws.com/blog_19small.jpg" alt="" width="563" height="319" /></p>
<p>Last we've got a comparison of Rails 3 across four implementations (Ruby 1.8, Ruby 1.9, Rubinius, and JRuby):</p>
<p><img src="http://eyweb-images.s3.amazonaws.com/blog_crossimp.jpg" alt="" width="592" height="276" /></p>
<p>You can see that Rails 3 is significantly faster than Rails 2.3 across the board, and that all implementations (including Rubinius!) are significantly improved over Ruby 1.8. All in all, a great year for Ruby!</p>
<p>Next post, I'll talk about improvements in the Rails 3 API for plugin authors—keep an eye out, and as always, leave your comments!</pre>
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/rails-and-merb-merge-performance-part-2-of-6/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Rails and Merb Merge: The Anniversary (Part 1 of 6)</title>
		<link>http://www.engineyard.com/blog/2009/rails-and-merb-merge-the-anniversary-part-1-of-6/</link>
		<comments>http://www.engineyard.com/blog/2009/rails-and-merb-merge-the-anniversary-part-1-of-6/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 22:30:37 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Merb]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3062</guid>
		<description><![CDATA[<p>A year ago today, <a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/">we announced</a> <a href="http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3">that Rails and Merb would merge</a>. At the time, there was much skepticism about the likelihood of the success of this endeavor. Indeed, The most common imagery invoked by those who learned about our plans was a unicorn. At RailsConf last year (well into the effort), both DHH and I used unicorns in our talks, poking fun at the vast expectations we'd set, and the apparent impossibility of achieving everything we'd said we wanted to achieve for 3.0.</p>
<p>A year has gone by, so it's a good time to reflect on how well we've done at achieving those expectations. Over the next few days, I'll take each bullet point that I provided in my original post, and go into detail about the progress we've made on that front.</p>
<p>I've given a few recent talks on these topics, so some of you may already have seen some of this, but I wanted to get it down in writing for those who hadn't. I've also added new information, some of which was omitted because it was difficult to explain in a talk, and some of which is too current for any of my recent talks.</p>
<h3>Modularity</h3>
<blockquote><p>Rails will become more modular, starting with a rails-core, and including the ability to opt in or out of specific components. We will focus on reducing coupling across Rails, and making it possible to replace parts of Rails without disturbing other parts. This is exactly what Merb means when it touts "modularity".</p></blockquote>
<p>We've spent a significant amount of time on this step which has been really fruitful. I'll give a few specific examples.</p>
<h4>ActiveSupport</h4>
<p>First, we've gone through ActiveSupport, making it viable to cherry-pick specific elements. This means that using ActiveSupport's inflector, time extensions, class extensions, or anything your heart desires is now possible without having to personally track the dependency graph. Here's an example of what I mean, from the <code>to_sentence</code> method in ActiveSupport from Rails 2.3:</p>
<pre lang="ruby" escaped="true">
module ActiveSupport #:nodoc:
  module CoreExtensions #:nodoc:
    module Array #:nodoc:
      module Conversions
        def to_sentence(options = {})
          ...
          options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
          ...
        end
        ...
      end
    end
  end
end</pre>
<p>As you can see, <code>to_sentence</code> has an implicit requirement on assert_valid_keys, which means that in order to cherry-pick <code>active_support/core_ext/array/conversions</code>, you are forced to work through the file, find any unsatisfied dependencies, and be sure to require them as well. And of course, the structure of these dependencies could easily change in a future version of Rails, so relying on what you'd found would be unsafe. In Rails 3, the top of that same file looks like:</p>
<pre lang="ruby" escaped="true">require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/inflector'</pre>
<p>This is because we've gone through the entire ActiveSupport library, found the unsatisfied dependencies, and made them explicit. As a result, you can pull out the specific libraries you want for a small project, and not get the full weight of ActiveSupport.</p>
<p>Even better, other parts of Rails now explicitly declare the dependencies <strong>they</strong> have on ActiveSupport. So for instance, the code that adds logging support to ActionController has the following lines on top:</p>
<pre lang="ruby" escaped="true">require 'active_support/core_ext/logger'
require 'active_support/benchmarkable'</pre>
<p>This means that all of Rails knows what parts of ActiveSupport are needed. For simplicity, Rails 3 ships with all of ActiveSupport still provided, so you'll be able to use things like <code>3.days</code> or <code>3.kilobytes</code> without interruption. However, if you want more control over what gets included, that's possible. You can declare <code>config.active_support.bare = true</code> in your configuration and we'll pull in only the parts of ActiveSupport explicitly needed for the parts of <em>Rails</em> that you use. You'll still need to include the fancy parts if you want to use them - <code>3.days</code> wont work out of the box with bare enabled.</p>
<h4>ActionController</h4>
<p>Another area that really needed an overhaul was ActionController. Previously, ActionController had a number of disparate elements all in one place. When we looked closely, we found that there were really three discrete components masquerading as one.</p>
<p>First, there was the dispatching functionality. This included the dispatcher itself, routing, middleware, and rack extensions. Second there was generic controller code that was meant to be reused elsewhere, and was in fact reused in ActionMailer. Finally, there was the subset of controller code that brought those two concerns together: code that handled requests and responses through a controller architecture.</p>
<p>In Rails 3, each of those components has been separated out. The dispatcher functionality has been moved into ActionDispatch, with the code inside tightened up and really made a conceptual component. The parts of ActionController that were meant to be reused by non-HTTP controllers was moved into a new component called AbstractController, which both ActionController and ActionMailer inherit from.</p>
<p>Finally, ActionController itself has gotten a significant overhaul. Essentially, we've isolated every standalone component, and made it possible to start with a stripped-down controller and pull in just the components you want. Our old friend <code>ActionController::Base</code> simply starts with that same stripped-down controller and pulls <strong>everything</strong> in. For instance, take a look at the beginning of the new version of that class:</p>
<pre lang="ruby" escaped="true">module ActionController
  class Base &lt; Metal
    abstract!

    include AbstractController::Callbacks
    include AbstractController::Logger

    include ActionController::Helpers
    include ActionController::HideActions
    include ActionController::UrlFor
    include ActionController::Redirecting
    include ActionController::Rendering
    include ActionController::Renderers::All
    include ActionController::Layouts
    include ActionController::ConditionalGet
    include ActionController::RackDelegation
    include ActionController::Logger
    include ActionController::Benchmarking
    include ActionController::Configuration</pre>
<p>All we're doing here is pulling in every available module, so the default experience of Rails is the same as before. However, the real power of what we've done here is the same as what we've done in ActiveSupport: every module declares its dependencies on other modules, so you can pull in <code>Rendering</code>, for instance, without having to wonder what other modules need to be included and in what order.</p>
<p>The following is a perfectly valid controller in Rails 3:</p>
<pre lang="ruby" escaped="true">class FasterController &lt; ActionController::Metal
  abstract!

  # Rendering would be pulled in by layouts, but I include
  # it here for clarity
  include ActionController::Rendering
  include ActionController::Layouts

  append_view_path Rails.root.join("app/views")
end

class AwesomeController &lt; FasterController
  def index
    render "so_speedy"
  end
end</pre>
<p>And then, in your routes, it would be perfectly valid to do:</p>
<pre lang="ruby" escaped="true">MyApp.routes.draw do
  match "/must_be_fast", :to =&gt; "awesome#index"
end</pre>
<p>Essentially, <code>ActionController::Base</code> has become just one way to express your controllers. Think of it like Rails Classic, with the ability to roll your own if you're not so into that taste. It's really easy to mix and match too: if you wanted to pull in <code>before_filter</code> functionality to <code>FasterController</code>, we could simply include <code>AbstractController::Callbacks</code>.</p>
<p>Note that without doing anything else, including those modules pulled in <code>AbstractController::Rendering</code> (the subset of rendering functionality shared with ActionMailer), <code>AbstractController::Layouts</code>, and <code>ActiveSupport::Callbacks</code>.</p>
<p>This makes it really possible to trivially pull in just the specific functionality you need in performance-sensitive cases without having to use an entirely different API. If you need additional functionality, you can easily just pull in additional modules or eventually upgrade to the full <code>ActionController::Base</code> without needing to rip anything apart along the way.</p>
<p>This, in fact, is a core idea of Rails 3: there are no monolithic components, only modules that work seamlessly together in a great package of defaults. This allows people to continue using Rails as they have used it successfully in previous versions, but really leverage the codebase for alternative uses. No more functionality locked away in non-reusable forms.</p>
<p>One nice immediate benefit of all of this is that ActionMailer gets all of the functionality of ActionController in a clean, intentional way. Everything from layouts and helpers to filters is using the identical code that ActionController uses, so ActionMailer can never again drift away from the functionality of ActionController (as ActionController itself evolves).</p>
<p>Middleware gets a helping hand too. <code>ActionController::Middleware</code>, which is middleware with all of the powers of ActionController, allows you to pull in whatever ActionController features you want (like Rendering, ConditionalGet, robust Request and Response objects, and more) as needed. Here's an example:</p>
<pre lang="ruby" escaped="true"># The long way
class AddMyName &lt; ActionController::Middleware
  def call(env)
    status, headers, body = @app.call(env)
    headers["X-Author"] = "Yehuda Katz"
    headers["Content-Type"] = "application/xml"

    etag = env["If-None-Match"]
    key = ActiveSupport::Cache.expand_cache_key(body + "Yehuda Katz")
    headers["ETag"] = %["#{Digest::MD5.hexdigest(key)}"]
    if headers["ETag"] == etag
      headers["Cache-Control" = "public"]
      return [304, headers, [" "]]
    end

    return status, headers, body
  end
end</pre>
<pre lang="ruby" escaped="true"># Using extra Rack helpers
class AddMyName &lt; ActionController::Middleware
  include ActionController::RackDelegation

  def call(env)
    self.status, self.headers, self.response_body = @app.call(env)

    headers["X-Author"] = "Yehuda Katz"

    # but you can do more nice stuff now
    self.content_type = Mime::XML # delegates to the response
    response.etag = "#{response.body}Yehuda Katz"
    response.cache_control[:public] = true

    self.status, self.response_body = 304, nil if request.fresh?(response)

    response.to_a
  end
end</pre>
<pre lang="ruby" escaped="true"># Using ConditionalGet helpers
class AddMyName &lt; ActionController::Middleware
  # pulls in RackDelegation
  include ActionController::ConditionalGet

  def call(env)
    self.status, self.headers, self.response_body = @app.call(env)

    headers["X-Author"] = "Yehuda Katz"

    self.content_type = Mime::XML
    fresh_when :etag =&gt; "#{response.body}Yehuda Katz", :public =&gt; true

    response.to_a
  end
end</pre>
<p>In all, I really think we've delivered on our promise to bring significant modularity improvements to Rails (and then some). In fact, I think the level of success that we've had with this version exceeds most people's expectations of a year ago, and is solidly in golden unicorn territory. Enjoy!</p>
<p>Next, I'll talk about bringing performance improvements to Rails 3. Hopefully it won't go by too fast. :)
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/rails-and-merb-merge-the-anniversary-part-1-of-6/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Your Pages Will Load Faster with Rails!</title>
		<link>http://www.engineyard.com/blog/2009/your-pages-will-load-faster-with-rails/</link>
		<comments>http://www.engineyard.com/blog/2009/your-pages-will-load-faster-with-rails/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 18:21:09 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[GZip]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Newsletter]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[YSlow]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3043</guid>
		<description><![CDATA[<p><em>This article was originally included in the October issue of the Engine Yard Newsletter. To read more posts like this one, subscribe to the </em><a href="http://www.engineyard.com/newsletter"><em>Engine Yard Newsletter</em></a><em>.</em></p>
<p><em>In </em><strong><em>Inside Rails</em></strong><em>, Yehuda Katz, Rails expert and core team member, and Carl Lerche, Rails expert and full-time contributor, present expert advice and insight on the Rails platform and Rails development.</em></p>
<hr />Server-side programmers tend to spend a lot of time tuning their server-side code. Studies show, however, that 90 percent of the user's perceived performance is on the client-side. The YSlow recommendations are the gold standard for client-side performance, providing a list of things web developers can do both on the server-side and the client-side to improve performance. If you use Rails, a large number of these recommendations are baked into the framework.</p>
<p>These tips are not extremely difficult to implement yourself with another framework, but Rails and Engine Yard believe in making your websites <em>fast by default</em>: you shouldn't need to understand all the minutiae in order to get a snappy application.</p>
<h2>Use Far-Future Expires</h2>
<p>YSlow recommends using an <code>Expires</code> header set far into the future. This means that browsers don't need to ask for your images, JavaScripts, or stylesheets again after the first request. However, this introduces an additional problem: what happens if you (inevitably) change these files? Won't the browser be stuck with the old file forever?</p>
<p>The solution is to include a last modified timestamp with your assets (something like <code>&lt;img src="/images/myasset.png?84392578943" alt="" /&gt;</code>). When the file is modified, you update the timestamp, and the browser will know to ask for the file again.</p>
<p>When you use Rails, this timestamping is the default behavior; all you need to do is set up your Nginx or Apache config to serve with far future headers and you're ready to go. And if you use Engine Yard, we set up those headers for you.</p>
<h2>GZip Components</h2>
<p>YSlow recommends GZipping JavaScript, CSS, and other textual assets. This reduces their file size over the wire by approximately 70%. This can be set up using your Apache or Nginx config. If you use Engine Yard, your assets are gzipped by default.</p>
<h2>Split Components Across Domains</h2>
<p>Some older browsers (*cough* IE *cough*) will only download two assets from a host at a time. This means that if you have two JavaScript files, two CSS files, and 10 images, these assets will come down two at a time, even though the user's connection is fast enough to download them in parallel. The solution to this problem is to split your assets up over multiple hosts (assets0.yourapp.com, assets1.yourapp.com, and so on).</p>
<p>When using server-side code you wrote yourself, or using a traditional server-side framework, you'd be forced to go through all of the URLs you generated and update them to use an asset host helper. With Rails, you can simply add a single line to your configuration and all of your generated URLs will start using the asset hosts you specified:</p>
<p><code>config.action_controller.asset_host = "assets%d.yourapp.com"</code></p>
<p>Of course, you'll need to set up a CNAME entry in your DNS to point the new virtual domains at the same host, but that should be trivial.</p>
<p>This also single-handedly resolves another YSlow recommendation: "Use Cookie-free Domains for Components." If your assets and application are on the same domain, the browser and server will pass cookies back and forth (up to 4k worth) for each asset request. By using asset hosts for your assets, you get the side benefit of cookie-free domains for your assets.</p>
<p>When comparing frameworks, it's tempting to look at something like "Etag Support" as a feature and simply check it off. Looking under the surface, however, there are complex considerations that are begging to be abstracted away from you. Why should you have to know what the header name in the request is called (If-None-Match) or how to generate a reliable unique key for an object?</p>
<p>Rails makes working with these ideas drop-dead simple, so you won't have to stress about following web best practices; when using Rails, you'll be doing the right thing and hardly know it. Stay tuned for a follow up post on more of the ways Rails makes fast page loading a breeze.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/your-pages-will-load-faster-with-rails/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>My Five Favorite Things About Rails 3</title>
		<link>http://www.engineyard.com/blog/2009/my-five-favorite-things-about-rails-3/</link>
		<comments>http://www.engineyard.com/blog/2009/my-five-favorite-things-about-rails-3/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 18:00:22 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ActionController]]></category>
		<category><![CDATA[ActiveMerchant]]></category>
		<category><![CDATA[ActiveModel]]></category>
		<category><![CDATA[ActiveSupport]]></category>
		<category><![CDATA[Nokogiri]]></category>
		<category><![CDATA[Rack]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails 3]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1969</guid>
		<description><![CDATA[<p>Over the last few months Rails 3 has really begun to take shape. We've been hard at work building, refactoring, building, and then refactoring all over again, and I'm pretty pleased with how things are going. There's still a lot of work to be done (we're working on it, these things just take time :P ), but I wanted to pause for a bit and talk about some of my favorite features.</p>
<p>I know a lot of you are eager for information on Rails 3. While this isn't a <em>whole</em> lot of code... think of it more like a movie trailer, and keep an eye out here, on the <a href="http://weblog.rubyonrails.org/">rubyonrails.org blog</a> and on <a href="http://yehudakatz.com/">my personal blog</a> for more information as we get closer to the release.</p>
<h2>1. New Bundler</h2>
<p>A lot of you have had trouble with the various efforts to make it possible to declare gem dependencies in your application and ensure that they're available on your development and production environment. Merb had an early solution to this problem that got about 90% of the way there, but didn't handle a large number of gems very well. This was exposed by the <a href="http://www.engineyard.com/products/cloud">Engine Yard Cloud</a> team, who had some trouble with the Merb gem bundler with a large number of potentially interdependent gems.</p>
<p>The new bundler handles virtually all issues we could think of around bundling gems in Rails applications, and then some.</p>
<h4>Rubygems Resolution</h4>
<p>This problem arises when you have multiple gems that depend on overlapping versions of some other gem. For instance, let's say you depend on ActiveMerchant 1.4.2 and Rails 2.3.2. ActiveMerchant depends on <code>activesupport &gt;= 2.3.2</code>. Rails 2.3.2 depends on <code>activesupport = 2.3.2</code>. Now let's say you have Rails 2.3.2 and Rails 2.3.3 on your system.</p>
<p>If you go ahead and <code>require "activemerchant"</code>, it will see the <code>&gt;= 2.3.2</code>. Since you have 2.3.3 on your system, it will pull it next. Next, you <code>gem "action_controller", "= 2.3.2"</code>. Since ActionController depends on <code>activesupport = 2.3.2</code>, it'll see that 2.3.3 was already activated and fail. You'll get the dreaded <code>Gem::LoadError: can't activate activesupport (= 2.3.2, runtime), already activated activesupport-2.3.3</code>.</p>
<p>This problem arises because gems are currently resolved <strong>linearly</strong> instead of doing an algorithmic dependency resolution. It turns out that doing dependency resolution with overlapping arbitrary ranges over a large set of potential dependencies is a hard problem. It took us a number of iterations over about a year to get it right, but our current solution is simple, elegant, reasonably fast, and most importantly, correct.</p>
<h4>Limit Network Dependencies for Deploy</h4>
<p>This is something we felt very strongly about with the Merb bundler, and most people seem to be coming around. The basic idea is that you should store your app's dependencies inside your application, not require a connection to Rubyforge, Github, and who knows what else at deploy time.</p>
<p>In addition to the possible risk of a network resource being down, there is the risk that you declared a dependency on something like <code>nokogiri</code>, and a new version was released to Rubyforge since staging, which breaks your code. You could solve this by always hardcoding all of your versions, but it's nicer to be able to declare your conceptual dependencies ("I want Nokogiri -- any version"). Once you pull the latest versions of your declared dependencies into your application, they should stay put, rather than possibly changing at deploy time.</p>
<h4>Consistent Environment</h4>
<p>By bundling specific .gem files inside of your application, you ensure that every developer, staging, and production are all running with the same environment.</p>
<h4>Native Gems</h4>
<p>By storing just the .gem file in the application, we can have a command that compiles the native gems for the architecture in question.</p>
<h2>2. ActionController Architecture</h2>
<p>In Rails 3, <code>ActionController::Base</code> is built on top of <code>ActionController::Metal</code>, a stripped down version of ActionController with support for simple Rack semantics. We then include a series of modules to add support for things like callbacks, rendering, layouts, helpers, and on and on. This means that it's easy for you to start with <code>ActionController::Metal</code> and pull in just the features you want, paying just the performance cost you want.</p>
<p>We even implemented deprecated 2.3 features as a module that gets mixed in to ActionController::Base. If you aren't using any deprecated features, you can simply stop including the module and get some performance back. You also know that you're not using any features you shouldn't be.</p>
<h2>3. Responder</h2>
<p>Since we got RESTful controllers, it has been very common to see idiomatic controllers that have actions looking like this:</p>
<pre>def create
  @user = User.new(params[:user])

  respond_to do |format|
    if @user.save
      flash[:notice] = 'User was successfully created.'
      format.html { redirect_to(@user) }
      format.xml { render :xml =&gt; @user, :status =&gt; :created, :location =&gt; @user }
    else
      format.html { render :action =&gt; "new" }
      format.xml { render :xml =&gt; @user.errors, :status =&gt; :unprocessable_entity }
    end
  end
end</pre>
<p>In Rails 3, this will be shrunk down to:</p>
<pre>respond_to :html, :xml # class level

def create
  @user = User.new(params[:user])
  flash[:notice] = 'User was successfully created.' if @user.save
  respond_with(@user)
end</pre>
<p>What we do is move the idiomatic logic into a new object called a Responder. By default, we use the Responder that ships with Rails, but you can use your own subclass the same way you would set a controller-wide (or application-wide) layout. That way, you can package up your own RESTful idioms into objects and use those.</p>
<h2>4. ActiveModel</h2>
<p>You've probably heard that things like validations are now available to any Ruby object by simply including a module: it's true. Take a look:</p>
<pre>class Person
  include ActiveModel::Validations

  validates_presence_of :name
  attr_accessor :name
  def initialize(name)
    @name = name
  end
end

Person.new.valid?         #=&gt; false
Person.new.errors         #=&gt; {:name =&gt; ["cannot be blank"]} # localizable of course
Person.new("matz").valid? #=&gt; true</pre>
<p>This is pretty cool, and provides a lot of ActiveRecord functionality for other ORMs. What's really exciting to me, however, is that ActiveModel provides an API that can be used by ORM plugins to hook directly into ActionPack. If an object complies with the ActiveModel API, it will work seamlessly with the rest of Rails, just as well as ActiveRecord works in Rails 2.3.</p>
<p>This requires:</p>
<ul>
<li>Object#to_model: A method that returns an ActiveModel compliant version of the object. In most cases, this will return <code>self</code></li>
<li>Model#new_record?: true if the record has not yet been persisted</li>
<li>Model#valid?: true if the record is valid (or the object has no concept of validations)</li>
<li>Model#errors: a valid errors object. The errors object should respond to #[](field) and #full_messages</li>
<li>Model#class.model_name: a valid naming object that responds to <code>singular</code>, <code>plural</code>, <code>element</code>, <code>collection</code>, <code>partial_path</code>, and <code>human</code>. This is used in routing, URL generation, and a number of other areas, and is possibly the most important integration point.</li>
</ul>
<p>If your object implements these APIs, it will work with ActionPack with the same level of support as ActiveRecord. Pretty exciting!</p>
<h2>5. Performance</h2>
<p>Over the past several weeks, I've spent a lot of time working on reducing Rails' overhead. There's still a lot to be done, but I was able to reduce the overhead of Rails between two and five times, with especially good gains on Ruby 1.9. While this does not improve the time spent in your code, it reduces the overhead in calling partials, rendering collections, rendering templates, and rendering the entire response. This will be especially apparent for action-cached pages where most of the cost of the request is in Rails, not your request.</p>
<p>I've also started to look at general bottlenecks, like stylesheet_link_tag (surprising!) and URL generation in Paperclip, two things that bubbled up in a recent performance analysis of a real application.</p>
<p>Most of the improvement came from finding bottlenecks and then caching them, which can be tricky because of the possibility of dynamic changes. For instance, it is possible to modify the view_paths during any request, so it's hard to cache view lookup, since someone might prepend a path to the lookup order. In this case, my current approach has been to take a slower path, which means that doing dynamic things in Rails 3 is noticeably more expensive than the same operations in Rails 2.3 (where none of this was cached). I'll have some details on what kinds of things to avoid for optimal performance in a later post.</p>
<p>For now, until the next batch of awesomeness, there are my top upcoming features of Rails 3. Feel free to comment with questions on these or other Rails 3 features and topics. As always, I'm happy to help however I can.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/my-five-favorite-things-about-rails-3/feed/</wfw:commentRss>
		<slash:comments>52</slash:comments>
		</item>
	</channel>
</rss>

