From a8ba6773a7c08d0489c8fc9cdc62ebbfe9b8b3aa Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 23 Oct 2008 19:19:23 +0530 Subject: Add release notes --- railties/doc/guides/html/2_2_release_notes.html | 1086 ++++++++++++++++++++ .../guides/html/benchmarking_and_profiling.html | 25 +- railties/doc/guides/source/2_2_release_notes.txt | 396 +++++++ .../source/benchmarking_and_profiling/index.txt | 3 +- 4 files changed, 1498 insertions(+), 12 deletions(-) create mode 100644 railties/doc/guides/html/2_2_release_notes.html create mode 100644 railties/doc/guides/source/2_2_release_notes.txt (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html new file mode 100644 index 0000000000..e30145c90f --- /dev/null +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -0,0 +1,1086 @@ + + + + + Ruby on Rails 2.2 Release Notes + + + + + + + + + +
+ + + +
+

Ruby on Rails 2.2 Release Notes

+
+
+

Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the list of commits in the main Rails repository on GitHub.

+

Along with Rails, 2.2 marks the launch of the Ruby on Rails Guides, the first results of the ongoing Rails Guides hackfest. This site will deliver high-quality documentation of the major features of Rails.

+
+
+

1. Infrastructure

+
+

Rails 2.2 is a significant release for the infrastructure that keeps Rails humming along and connected to the rest of the world.

+

1.1. Internationalization

+

Rails 2.2 supplies an easy system for internationalization (or i18n, for those of you tired of typing).

+
+

1.2. Compatibility with Ruby 1.9 and JRuby

+

Along with thread safety, a lot of work has been done to make Rails work well with JRuby and the upcoming Ruby 1.9. With Ruby 1.9 being a moving target, running edge Rails on edge Ruby is still a hit-or-miss proposition, but Rails is ready to make the transition to Ruby 1.9 when the latter is released.

+
+

2. Documentation

+
+

The internal documentation of Rails, in the form of code comments, has been improved in numerous places. In addition, the Ruby on Rails Guides project is the definitive source for information on major Rails components. In its first official release, the Guides page includes:

+
    +
  • +

    +Getting Started with Rails +

    +
  • +
  • +

    +Rails Database Migrations +

    +
  • +
  • +

    +Active Record Associations +

    +
  • +
  • +

    +Active Record Finders +

    +
  • +
  • +

    +Layouts and Rendering in Rails +

    +
  • +
  • +

    +Action View Form Helpers +

    +
  • +
  • +

    +Rails Routing from the Outside In +

    +
  • +
  • +

    +Basics of Action Controller +

    +
  • +
  • +

    +Rails Caching +

    +
  • +
  • +

    +Testing Rails Applications +

    +
  • +
  • +

    +Securing Rails Applications +

    +
  • +
  • +

    +Debugging Rails Applications +

    +
  • +
  • +

    +Benchmarking and Profiling Rails Applications +

    +
  • +
  • +

    +The Basics of Creating Rails Plugins +

    +
  • +
+

All told, the Guides provide tens of thousands of words of guidance for beginning and intermediate Rails developers.

+

If you want to these generate guides locally, inside your application:

+
+
+
rake doc:guides
+
+

This will put the guides inside RAILS_ROOT/doc/guides and you may start surfing straight away by opening RAILS_ROOT/doc/guides/index.html in your favourite browser.

+
+
+

3. Better integration with HTTP : Out of the box ETag support

+
+

Supporting the etag and last modified timestamp in HTTP headers means that Rails can now send back an empty response if it gets a request for a resource that hasn't been modified lately. This allows you to check whether a response needs to be sent at all.

+
+
+
class ArticlesController < ApplicationController
+  def show_with_respond_to_block
+    @article = Article.find(params[:id])
+
+    # If the request sends headers that differs from the options provided to stale?, then
+    # the request is indeed stale and the respond_to block is triggered (and the options
+    # to the stale? call is set on the response).
+    #
+    # If the request headers match, then the request is fresh and the respond_to block is
+    # not triggered. Instead the default render will occur, which will check the last-modified
+    # and etag headers and conclude that it only needs to send a "304 Not Modified" instead
+    # of rendering the template.
+    if stale?(:last_modified => @article.published_at.utc, :etag => @article)
+      respond_to do |wants|
+        # normal response processing
+      end
+    end
+  end
+
+  def show_with_implied_render
+    @article = Article.find(params[:id])
+
+    # Sets the response headers and checks them against the request, if the request is stale
+    # (i.e. no match of either etag or last-modified), then the default render of the template happens.
+    # If the request is fresh, then the default render will return a "304 Not Modified"
+    # instead of rendering the template.
+    fresh_when(:last_modified => @article.published_at.utc, :etag => @article)
+  end
+end
+
+
+

4. Thread Safety

+
+

The work done to make Rails thread-safe is rolling out in Rails 2.2. Depending on your web server infrastructure, this means you can handle more requests with fewer copies of Rails in memory, leading to better server performance and higher utilization of multiple cores.

+

To enable multithreaded dispatching in production mode of your application, add the following line in your config/environments/production.rb:

+
+
+
config.threadsafe!
+
+
+
+

5. Active Record

+
+

There are two big additions to talk about here: transactional migrations and pooled database transactions. There's also a new (and cleaner) syntax for join table conditions, as well as a number of smaller improvements.

+

5.1. Transactional Migrations

+

Historically, multiple-step Rails migrations have been a source of trouble. If something went wrong during a migration, everything before the error changed the database and everything after the error wasn't applied. Also, the migration version was stored as having been executed, which means that it couldn't be simply rerun by rake db:migrate:redo after you fix the problem. Transactional migrations change this by wrapping migration steps in a DDL transaction, so that if any of them fail, the entire migration is undone. In Rails 2.2, transactional migrations are supported on PostgreSQL only. The code is extensible to other database types in the future.

+
+

5.2. Connection Pooling

+

Connection pooling lets Rails distribute database requests across a pool of database connections that will grow to a maximum size (by default 5, but you can add a pool key to your database.yml to adjust this). This helps remove bottlenecks in applications that support many concurrent users. There's also a wait_timeout that defaults to 5 seconds before giving up. ActiveRecord::Base.connection_pool gives you direct access to the pool if you need it.

+
+
+
development:
+  adapter: mysql
+  username: root
+  database: sample_development
+  pool: 10
+  wait_timeout: 10
+
+
+

5.3. Hashes for Join Table Conditions

+

You can now specify conditions on join tables using a hash. This is a big help if you need to query across complex joins.

+
+
+
class Photo < ActiveRecord::Base
+  belongs_to :Product
+end
+
+class Product < ActiveRecord::Base
+  has_many :products
+end
+
+# Get all products with copyright-free photos:
+Product.find(:all, :joins => :photo,
+  :conditions => { :photos => { :copyright => false }})
+
+
+

5.4. New Dynamic Finders

+

Two new sets of methods have been added to Active Record's dynamic finders family.

+

5.4.1. find_last_by_<attributes>

+

The find_last_by_<attribute> method is equivalent to Model.last(:conditions ⇒ {:attribute ⇒ value})

+
+
+
# Get the last user who signed up from London
+User.find_last_by_city('London')
+
+
+

5.4.2. find_by_<attributes>!

+

The new bang! version of find_by_<attribute>! is equivalent to +Model.first(:conditions ⇒ {:attribute ⇒ value}) || raise ActiveRecord::RecordNotFound Instead of returning nil if it can't find a matching record, this method will raise an exception if it cannot find a match.

+
+
+
# Raise ActiveRecord::RecordNotFound exception if 'Moby' hasn't signed up yet!
+User.find_by_name!('Moby')
+
+
+

5.5. Other ActiveRecord Changes

+
    +
  • +

    +rake db:migrate:redo now accepts an optional VERSION to target that specific migration to redo +

    +
  • +
  • +

    +Set config.active_record.timestamped_migrations = false to have migrations with numeric prefix instead of UTC timestamp. +

    +
  • +
  • +

    +Counter cache columns (for associations declared with :counter_cache ⇒ true) do not need to be initialized to zero any longer. +

    +
  • +
  • +

    +ActiveRecord::Base.human_name for an internationalization-aware humane translation of model names +

    +
  • +
+
+

6. Action Controller

+
+

On the controller side, there are a couple of changes that will help tidy up your routes.

+

6.1. Shallow Route Nesting

+

Shallow route nesting provides a solution to the well-known difficulty of using deeply-nested resources. With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with - but you can supply more information.

+
+
+
map.resources :publishers, :shallow => true do |publisher|
+  publisher.resources :magazines do |magazine|
+    magazine.resources :photos
+  end
+end
+
+

This will enable recognition of (among others) these routes:

+
+
+
/publishers/1           ==> publisher_path(1)
+/publishers/1/magazines ==> publisher_magazines_path(1)
+/magazines/2            ==> magazine_path(2)
+/magazines/2/photos     ==> magazines_photos_path(2)
+/photos/3               ==> photo_path(3)
+
+
+

6.2. Method Arrays for Member or Collection Routes

+

You can now supply an array of methods for new member or collection routes. This removes the annoyance of having to define a route as accepting any verb as soon as you need it to handle more than one. With Rails 2.2, this is a legitimate route declaration:

+
+
+
map.resources :photos, :collection => { :search => [:get, :post] }
+
+
+

Action Controller now offers good support for HTTP conditional GET requests, as well as some other additions.

+

6.3. Other Action Controller Changes

+
    +
  • +

    +You can now easily show a custom error page for exceptions raised while routing a request. +

    +
  • +
  • +

    +The HTTP Accept header is disabled by default now. You should prefer the use of formatted URLs (such as /customers/1.xml) to indicate the format that you want. If you need the Accept headers, you can turn them back on with config.action_controller.user_accept_header = true. +

    +
  • +
  • +

    +Benchmarking numbers are now reported in milliseconds rather than tiny fractions of seconds +

    +
  • +
  • +

    +Rails now supports HTTP-only cookies (and uses them for sessions), which help mitigate some cross-site scripting risks in newer browsers. +

    +
  • +
+
+

7. Action View

+
+
    +
  • +

    +javascript_include_tag and stylesheet_link_tag support a new :recursive option to be used along with :all, so that you can load an entire tree of files with a single line of code. +

    +
  • +
  • +

    +The included Prototype javascript library has been upgraded to version 1.6.0.2. +

    +
  • +
  • +

    +RJS#page.reload to reload the browser's current location via javascript +

    +
  • +
  • +

    +The atom_feed helper now takes an :instruct option to let you insert XML processing instructions. +

    +
  • +
+
+

8. Action Mailer

+
+

Action Mailer now supports mailer layouts. You can make your HTML emails as pretty as your in-browser views by supplying an appropriately-named layout - for example, the CustomerMailer class expects to use layouts/customer_mailer.html.erb.

+
+
+

9. Active Support

+
+

Active Support now offers built-in memoization for Rails applications, the each_with_object method, prefix support on delegates, and various other new utility methods.

+

9.1. Memoization

+

Memoization is a pattern of initializing a method once and then stashing its value away for repeat use. You've probably used this pattern in your own applications:

+
+
+
def full_name
+  @full_name ||= "#{first_name} #{last_name}"
+end
+
+

Memoization lets you handle this task in a declarative fashion:

+
+
+
extend ActiveSupport::Memoizable
+
+def full_name
+  "#{first_name} #{last_name}"
+end
+memoize :full_name
+
+

Other features of memoization include unmemoize, unmemoize_all, and memoize_all to turn memoization on or off.

+
+

9.2. each_with_object

+

The each_with_object method provides an alternative to inject, using a method backported from Ruby 1.9. It iterates over a collection, passing the current element and the memo into the block.

+
+
+
%w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'}
+
+

Lead Contributor: Adam Keys

+

9.3. Delegates With Prefixes

+

If you delegate behavior from one class to another, you can now specify a prefix that will be used to identify the delegated methods. For example:

+
+
+
class Vendor << ActiveRecord::Base
+  has_one :account
+  delegate :email, :password, :to => :account, :prefix => true
+end
+
+

This will produce delegated methods vendor.account_email and vendor.account_password. You can also specify a custom prefix:

+
+
+
class Vendor << ActiveRecord::Base
+  has_one :account
+  delegate :email, :password, :to => :account, :prefix => :owner
+end
+
+

This will produce delegated methods vendor.owner_email and vendor.owner_password.

+

Lead Contributor: Daniel Schierbeck

+

9.4. Other Active Support Changes

+
    +
  • +

    +Extensive updates to ActiveSupport::Multibyte, including Ruby 1.9 compatibility fixes. +

    +
  • +
  • +

    +The addition of ActiveSupport::Rescuable allows any class to mix in the rescue_from syntax. +

    +
  • +
  • +

    +past?, today? and future? for Date and Time classes to facilitate date/time comparisons. +

    +
  • +
  • +

    +Array#second through Array#tenth as aliases for Array#[1] through Array#[9] +

    +
  • +
  • +

    +Enumerable#several? to encapsulate collection.size > 1 +

    +
  • +
  • +

    +Inflector#parameterize produces a URL-ready version of its input, for use in to_param. +

    +
  • +
  • +

    +Time#advance recognizes fractional days and weeks, so you can do 1.7.weeks.ago, 1.5.hours.since, and so on. +

    +
  • +
  • +

    +The included TzInfo library has been upgraded to version 0.3.11. +

    +
  • +
+
+

10. Railties

+
+

In Railties (the core code of Rails itself) the biggest changes are in the config.gems mechanism.

+

10.1. config.gems

+

To avoid deployment issues and make Rails applications more self-contained, it's possible to place copies of all of the gems that your Rails application requires in /vendor/gems. This capability first appeared in Rails 2.1, but it's much more flexible and robust in Rails 2.2, handling complicated dependencies between gems. Gem management in Rails includes these commands:

+
    +
  • +

    +config.gem gem_name in your config/environment.rb file +

    +
  • +
  • +

    +rake gems to list all configured gems, as well as whether they (and their dependencies) are installed or frozen +

    +
  • +
  • +

    +rake gems:install to install missing gems to the computer +

    +
  • +
  • +

    +rake gems:unpack to place a copy of the required gems into /vendor/gems +

    +
  • +
  • +

    +rake gems:unpack:dependencies to get copies of the required gems and their dependencies into /vendor/gems +

    +
  • +
  • +

    +rake gems:build to build any missing native extensions +

    +
  • +
  • +

    +rake gems:refresh_specs to bring vendored gems created with Rails 2.1 into alignment with the Rails 2.2 way of storing them +

    +
  • +
+

You can unpack or install a single gem by specifying GEM=_gem_name on the command line.

+
+

10.2. Other Railties Changes

+
    +
  • +

    +If you're a fan of the Thin web server, you'll be happy to know that script/server now supports Thin directly. +

    +
  • +
  • +

    +script/plugin install <plugin> -r <revision> now works with git-based as well as svn-based plugins. +

    +
  • +
  • +

    +script/console now supports a —debugger option +

    +
  • +
  • +

    +Instructions for setting up a continuous integration server to build Rails itself are included in the Rails source +

    +
  • +
  • +

    +rake notes:custom ANNOTATION=MYFLAG lets you list out custom annotations. +

    +
  • +
  • +

    +Wrapped Rails.env in StringQuestioneer so you can do Rails.env.development? +

    +
  • +
  • +

    +script/generate works without deprecation warnings when RubyGems 1.3.0 is present +

    +
  • +
+
+

11. Deprecated

+
+

A few pieces of older code are deprecated in this release:

+
    +
  • +

    +Rails::SecretKeyGenerator has been replaced by ActiveSupport::SecureRandom +

    +
  • +
  • +

    +render_component is deprecated. There's a render_components plugin available if you need this functionality. +

    +
  • +
  • +

    +country_select has been removed. See the deprecation page for more information and a plugin replacement. +

    +
  • +
  • +

    +ActiveRecord::Base.allow_concurrency no longer has any effect. +

    +
  • +
  • +

    +ActiveRecord::Errors.default_error_messages has been deprecated in favor of I18n.translate(activerecord.errors.messages) +

    +
  • +
  • +

    +The %s and %d interpolation syntax for internationalization is deprecated. +

    +
  • +
  • +

    +String#chars has been deprecated in favor of String#mb_chars. +

    +
  • +
  • +

    +Durations of fractional months or fractional years are deprecated. Use Ruby's core Date and Time class arithmetic instead. +

    +
  • +
+
+

12. Credits

+
+

Release notes compiled by Mike Gunderloy

+
+ +
+
+ + diff --git a/railties/doc/guides/html/benchmarking_and_profiling.html b/railties/doc/guides/html/benchmarking_and_profiling.html index 0a2c995580..9bd1c10dc8 100644 --- a/railties/doc/guides/html/benchmarking_and_profiling.html +++ b/railties/doc/guides/html/benchmarking_and_profiling.html @@ -497,21 +497,24 @@ http://www.gnu.org/software/src-highlite --> by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite --> -
[User profiling_tester (master)]$ script/generate performance_test homepage
+
[lifo@null application (master)]$ script/generate performance_test homepage
 

This will generate test/performance/homepage_test.rb:

-
-
require 'test_helper'
-require 'performance_test_help'
+
+
require 'test_helper'
+require 'performance_test_help'
 
-class HomepageTest < ActionController::PerformanceTest
-  # Replace this with your real tests.
-  def test_homepage
-    get '/'
-  end
-end
-
+class HomepageTest < ActionController::PerformanceTest + # Replace this with your real tests. + def test_homepage + get '/' + end +end +

Which you can modify to suit your needs.

4.6. Running tests

diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt new file mode 100644 index 0000000000..57037e04e9 --- /dev/null +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -0,0 +1,396 @@ +Ruby on Rails 2.2 Release Notes +=============================== + +Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the link:http://github.com/rails/rails/commits/master[list of commits] in the main Rails repository on GitHub. + +Along with Rails, 2.2 marks the launch of the link:http://guides.rubyonrails.org/[Ruby on Rails Guides], the first results of the ongoing link:http://hackfest.rubyonrails.org/guide[Rails Guides hackfest]. This site will deliver high-quality documentation of the major features of Rails. + +== Infrastructure + +Rails 2.2 is a significant release for the infrastructure that keeps Rails humming along and connected to the rest of the world. + +=== Internationalization + +Rails 2.2 supplies an easy system for internationalization (or i18n, for those of you tired of typing). + +* Lead Contributors: Rails i18 Team +* More information : + - link:http://rails-i18n.org[Official Rails i18 website] + - link:http://www.artweb-design.de/2008/7/18/finally-ruby-on-rails-gets-internationalized[Finally. Ruby on Rails gets internationalized] + - link:http://i18n-demo.phusion.nl[Localizing Rails : Demo application] + +=== Compatibility with Ruby 1.9 and JRuby + +Along with thread safety, a lot of work has been done to make Rails work well with JRuby and the upcoming Ruby 1.9. With Ruby 1.9 being a moving target, running edge Rails on edge Ruby is still a hit-or-miss proposition, but Rails is ready to make the transition to Ruby 1.9 when the latter is released. + +== Documentation + +The internal documentation of Rails, in the form of code comments, has been improved in numerous places. In addition, the link:http://guides.rubyonrails.org/[Ruby on Rails Guides] project is the definitive source for information on major Rails components. In its first official release, the Guides page includes: + +* Getting Started with Rails +* Rails Database Migrations +* Active Record Associations +* Active Record Finders +* Layouts and Rendering in Rails +* Action View Form Helpers +* Rails Routing from the Outside In +* Basics of Action Controller +* Rails Caching +* Testing Rails Applications +* Securing Rails Applications +* Debugging Rails Applications +* Benchmarking and Profiling Rails Applications +* The Basics of Creating Rails Plugins + +All told, the Guides provide tens of thousands of words of guidance for beginning and intermediate Rails developers. + +If you want to these generate guides locally, inside your application: + +[source, ruby] +------------------------------------------------------- +rake doc:guides +------------------------------------------------------- + +This will put the guides inside +RAILS_ROOT/doc/guides+ and you may start surfing straight away by opening +RAILS_ROOT/doc/guides/index.html+ in your favourite browser. + +* Lead Contributors: link:http://guides.rails.info/authors.html[Rails Documentation Team] +* Major contributions from link:http://advogato.org/person/fxn/diary.html[Xavier Nora] and link:http://izumi.plan99.net/blog/[Hongli Lai]. +* More information: + - link:http://hackfest.rubyonrails.org/guide[Rails Guides hackfest] + - link:http://weblog.rubyonrails.org/2008/5/2/help-improve-rails-documentation-on-git-branch[Help improve Rails documentation on Git branch] + +== Better integration with HTTP : Out of the box ETag support + +Supporting the etag and last modified timestamp in HTTP headers means that Rails can now send back an empty response if it gets a request for a resource that hasn't been modified lately. This allows you to check whether a response needs to be sent at all. + +[source, ruby] +------------------------------------------------------- +class ArticlesController < ApplicationController + def show_with_respond_to_block + @article = Article.find(params[:id]) + + # If the request sends headers that differs from the options provided to stale?, then + # the request is indeed stale and the respond_to block is triggered (and the options + # to the stale? call is set on the response). + # + # If the request headers match, then the request is fresh and the respond_to block is + # not triggered. Instead the default render will occur, which will check the last-modified + # and etag headers and conclude that it only needs to send a "304 Not Modified" instead + # of rendering the template. + if stale?(:last_modified => @article.published_at.utc, :etag => @article) + respond_to do |wants| + # normal response processing + end + end + end + + def show_with_implied_render + @article = Article.find(params[:id]) + + # Sets the response headers and checks them against the request, if the request is stale + # (i.e. no match of either etag or last-modified), then the default render of the template happens. + # If the request is fresh, then the default render will return a "304 Not Modified" + # instead of rendering the template. + fresh_when(:last_modified => @article.published_at.utc, :etag => @article) + end +end +------------------------------------------------------- + +== Thread Safety + +The work done to make Rails thread-safe is rolling out in Rails 2.2. Depending on your web server infrastructure, this means you can handle more requests with fewer copies of Rails in memory, leading to better server performance and higher utilization of multiple cores. + +To enable multithreaded dispatching in production mode of your application, add the following line in your +config/environments/production.rb+: + +[source, ruby] +------------------------------------------------------- +config.threadsafe! +------------------------------------------------------- + +* More information : + - link:http://weblog.rubyonrails.org/2008/8/16/josh-peek-officially-joins-the-rails-core[Thread safety project announcement] + - link:http://blog.headius.com/2008/08/qa-what-thread-safe-rails-means.html[Q/A: What Thread-safe Rails Means] + +== Active Record + +There are two big additions to talk about here: transactional migrations and pooled database transactions. There's also a new (and cleaner) syntax for join table conditions, as well as a number of smaller improvements. + +=== Transactional Migrations + +Historically, multiple-step Rails migrations have been a source of trouble. If something went wrong during a migration, everything before the error changed the database and everything after the error wasn't applied. Also, the migration version was stored as having been executed, which means that it couldn't be simply rerun by +rake db:migrate:redo+ after you fix the problem. Transactional migrations change this by wrapping migration steps in a DDL transaction, so that if any of them fail, the entire migration is undone. In Rails 2.2, transactional migrations are supported *on PostgreSQL only*. The code is extensible to other database types in the future. + +* Lead Contributor: link:http://adam.blog.heroku.com/[Adam Wiggins] +* More information: + - link:http://adam.blog.heroku.com/past/2008/9/3/ddl_transactions/[DDL Transactions] + +=== Connection Pooling + +Connection pooling lets Rails distribute database requests across a pool of database connections that will grow to a maximum size (by default 5, but you can add a +pool+ key to your +database.yml+ to adjust this). This helps remove bottlenecks in applications that support many concurrent users. There's also a +wait_timeout+ that defaults to 5 seconds before giving up. +ActiveRecord::Base.connection_pool+ gives you direct access to the pool if you need it. + +[source, ruby] +------------------------------------------------------- +development: + adapter: mysql + username: root + database: sample_development + pool: 10 + wait_timeout: 10 +------------------------------------------------------- + +* Lead Contributor: link:http://blog.nicksieger.com/[Nick Sieger] +* More information: + - link:http://ryandaigle.com/articles/2008/9/7/what-s-new-in-edge-rails-connection-pools[What's New in Edge Rails: Connection Pools] + +=== Hashes for Join Table Conditions + +You can now specify conditions on join tables using a hash. This is a big help if you need to query across complex joins. + +[source, ruby] +------------------------------------------------------- +class Photo < ActiveRecord::Base + belongs_to :Product +end + +class Product < ActiveRecord::Base + has_many :products +end + +# Get all products with copyright-free photos: +Product.find(:all, :joins => :photo, + :conditions => { :photos => { :copyright => false }}) +------------------------------------------------------- + +* More information: + - link:http://ryandaigle.com/articles/2008/7/7/what-s-new-in-edge-rails-easy-join-table-conditions[What's New in Edge Rails: Easy Join Table Conditions] + +=== New Dynamic Finders + +Two new sets of methods have been added to Active Record's dynamic finders family. + +==== find_last_by_ + +The +find_last_by_+ method is equivalent to +Model.last(:conditions => {:attribute => value})+ + +[source, ruby] +------------------------------------------------------- +# Get the last user who signed up from London +User.find_last_by_city('London') +------------------------------------------------------- + +* Lead Contributor: link:http://www.workingwithrails.com/person/9147-emilio-tagua[Emilio Tagua] + +==== find_by_! + +The new bang! version of +find_by_! is equivalent to +Model.first(:conditions => {:attribute => value}) || raise ActiveRecord::RecordNotFound+ Instead of returning +nil+ if it can't find a matching record, this method will raise an exception if it cannot find a match. + +[source, ruby] +------------------------------------------------------- +# Raise ActiveRecord::RecordNotFound exception if 'Moby' hasn't signed up yet! +User.find_by_name!('Moby') +------------------------------------------------------- + +* Lead Contributor: link:http://blog.hasmanythrough.com[Josh Susser] + +=== Other ActiveRecord Changes + +* +rake db:migrate:redo+ now accepts an optional VERSION to target that specific migration to redo +* Set +config.active_record.timestamped_migrations = false+ to have migrations with numeric prefix instead of UTC timestamp. +* Counter cache columns (for associations declared with +:counter_cache => true+) do not need to be initialized to zero any longer. +* +ActiveRecord::Base.human_name+ for an internationalization-aware humane translation of model names + +== Action Controller + +On the controller side, there are a couple of changes that will help tidy up your routes. + +=== Shallow Route Nesting + +Shallow route nesting provides a solution to the well-known difficulty of using deeply-nested resources. With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with - but you _can_ supply more information. + +[source, ruby] +------------------------------------------------------- +map.resources :publishers, :shallow => true do |publisher| + publisher.resources :magazines do |magazine| + magazine.resources :photos + end +end +------------------------------------------------------- + +This will enable recognition of (among others) these routes: + +------------------------------------------------------- +/publishers/1 ==> publisher_path(1) +/publishers/1/magazines ==> publisher_magazines_path(1) +/magazines/2 ==> magazine_path(2) +/magazines/2/photos ==> magazines_photos_path(2) +/photos/3 ==> photo_path(3) +------------------------------------------------------- + +* Lead Contributor: link:http://www.unwwwired.net/[S. Brent Faulkner] +* More information: + - link:http://guides.rails.info/routing/routing_outside_in.html#_nested_resources[Rails Routing from the Outside In] + - link:http://ryandaigle.com/articles/2008/9/7/what-s-new-in-edge-rails-shallow-routes[What's New in Edge Rails: Shallow Routes] + +=== Method Arrays for Member or Collection Routes + +You can now supply an array of methods for new member or collection routes. This removes the annoyance of having to define a route as accepting any verb as soon as you need it to handle more than one. With Rails 2.2, this is a legitimate route declaration: + +[source, ruby] +------------------------------------------------------- +map.resources :photos, :collection => { :search => [:get, :post] } +------------------------------------------------------- + +* Lead Contributor: link:http://brennandunn.com/[Brennan Dunn] + +Action Controller now offers good support for HTTP conditional GET requests, as well as some other additions. + +=== Other Action Controller Changes + +* You can now easily link:http://m.onkey.org/2008/7/20/rescue-from-dispatching[show a custom error page] for exceptions raised while routing a request. +* The HTTP Accept header is disabled by default now. You should prefer the use of formatted URLs (such as +/customers/1.xml+) to indicate the format that you want. If you need the Accept headers, you can turn them back on with +config.action_controller.user_accept_header = true+. +* Benchmarking numbers are now reported in milliseconds rather than tiny fractions of seconds +* Rails now supports HTTP-only cookies (and uses them for sessions), which help mitigate some cross-site scripting risks in newer browsers. + +== Action View + +* +javascript_include_tag+ and +stylesheet_link_tag+ support a new +:recursive+ option to be used along with +:all+, so that you can load an entire tree of files with a single line of code. +* The included Prototype javascript library has been upgraded to version 1.6.0.2. +* +RJS#page.reload+ to reload the browser's current location via javascript +* The +atom_feed+ helper now takes an +:instruct+ option to let you insert XML processing instructions. + +== Action Mailer + +Action Mailer now supports mailer layouts. You can make your HTML emails as pretty as your in-browser views by supplying an appropriately-named layout - for example, the +CustomerMailer+ class expects to use +layouts/customer_mailer.html.erb+. + +* More information: + - link:http://ryandaigle.com/articles/2008/9/7/what-s-new-in-edge-rails-mailer-layouts[What's New in Edge Rails: Mailer Layouts] + +== Active Support + +Active Support now offers built-in memoization for Rails applications, the +each_with_object+ method, prefix support on delegates, and various other new utility methods. + +=== Memoization + +Memoization is a pattern of initializing a method once and then stashing its value away for repeat use. You've probably used this pattern in your own applications: + +[source, ruby] +------------------------------------------------------- +def full_name + @full_name ||= "#{first_name} #{last_name}" +end +------------------------------------------------------- + +Memoization lets you handle this task in a declarative fashion: + +[source, ruby] +------------------------------------------------------- +extend ActiveSupport::Memoizable + +def full_name + "#{first_name} #{last_name}" +end +memoize :full_name +------------------------------------------------------- + +Other features of memoization include +unmemoize+, +unmemoize_all+, and +memoize_all+ to turn memoization on or off. + +* Lead Contributor: link:http://joshpeek.com/[Josh Peek] +* More information: + - link:http://ryandaigle.com/articles/2008/7/16/what-s-new-in-edge-rails-memoization[What's New in Edge Rails: Easy Memoization] + - link:http://www.railway.at/articles/2008/09/20/a-guide-to-memoization[Memo-what? A Guide to Memoization] + +=== +each_with_object+ + +The +each_with_object+ method provides an alternative to +inject+, using a method backported from Ruby 1.9. It iterates over a collection, passing the current element and the memo into the block. + +[source, ruby] +------------------------------------------------------- +%w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'} +------------------------------------------------------- + +Lead Contributor: link:http://therealadam.com/[Adam Keys] + +=== Delegates With Prefixes + +If you delegate behavior from one class to another, you can now specify a prefix that will be used to identify the delegated methods. For example: + +[source, ruby] +------------------------------------------------------- +class Vendor << ActiveRecord::Base + has_one :account + delegate :email, :password, :to => :account, :prefix => true +end +------------------------------------------------------- + +This will produce delegated methods +vendor.account_email+ and +vendor.account_password+. You can also specify a custom prefix: + +[source, ruby] +------------------------------------------------------- +class Vendor << ActiveRecord::Base + has_one :account + delegate :email, :password, :to => :account, :prefix => :owner +end +------------------------------------------------------- + +This will produce delegated methods +vendor.owner_email+ and +vendor.owner_password+. + +Lead Contributor: link:http://workingwithrails.com/person/5830-daniel-schierbeck[Daniel Schierbeck] + +=== Other Active Support Changes + +* Extensive updates to +ActiveSupport::Multibyte+, including Ruby 1.9 compatibility fixes. +* The addition of +ActiveSupport::Rescuable+ allows any class to mix in the +rescue_from+ syntax. +* +past?+, +today?+ and +future?+ for +Date+ and +Time+ classes to facilitate date/time comparisons. +* +Array#second+ through +Array#tenth+ as aliases for +Array#[1]+ through +Array#[9]+ +* +Enumerable#several?+ to encapsulate +collection.size > 1+ +* +Inflector#parameterize+ produces a URL-ready version of its input, for use in +to_param+. +* +Time#advance+ recognizes fractional days and weeks, so you can do +1.7.weeks.ago+, +1.5.hours.since+, and so on. +* The included TzInfo library has been upgraded to version 0.3.11. + +== Railties + +In Railties (the core code of Rails itself) the biggest changes are in the +config.gems+ mechanism. + +=== +config.gems+ + +To avoid deployment issues and make Rails applications more self-contained, it's possible to place copies of all of the gems that your Rails application requires in +/vendor/gems+. This capability first appeared in Rails 2.1, but it's much more flexible and robust in Rails 2.2, handling complicated dependencies between gems. Gem management in Rails includes these commands: + +* +config.gem _gem_name_+ in your +config/environment.rb+ file +* +rake gems+ to list all configured gems, as well as whether they (and their dependencies) are installed or frozen +* +rake gems:install+ to install missing gems to the computer +* +rake gems:unpack+ to place a copy of the required gems into +/vendor/gems+ +* +rake gems:unpack:dependencies+ to get copies of the required gems and their dependencies into +/vendor/gems+ +* +rake gems:build+ to build any missing native extensions +* +rake gems:refresh_specs+ to bring vendored gems created with Rails 2.1 into alignment with the Rails 2.2 way of storing them + +You can unpack or install a single gem by specifying +GEM=_gem_name+ on the command line. + +* Lead Contributor: link:http://github.com/al2o3cr[Matt Jones] +* More information: + - link:http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies[What's New in Edge Rails: Gem Dependencies] + +=== Other Railties Changes + +* If you're a fan of the link:http://code.macournoyer.com/thin/[Thin] web server, you'll be happy to know that +script/server+ now supports Thin directly. +* +script/plugin install -r + now works with git-based as well as svn-based plugins. +* +script/console+ now supports a +--debugger+ option +* Instructions for setting up a continuous integration server to build Rails itself are included in the Rails source +* +rake notes:custom ANNOTATION=MYFLAG+ lets you list out custom annotations. +* Wrapped +Rails.env+ in +StringQuestioneer+ so you can do +Rails.env.development?+ +* +script/generate+ works without deprecation warnings when RubyGems 1.3.0 is present + +== Deprecated + +A few pieces of older code are deprecated in this release: + +* +Rails::SecretKeyGenerator+ has been replaced by +ActiveSupport::SecureRandom+ +* +render_component+ is deprecated. There's a link:http://github.com/rails/render_component/tree/master[render_components plugin] available if you need this functionality. +* +country_select+ has been removed. See the link:http://www.rubyonrails.org/deprecation/list-of-countries[deprecation page] for more information and a plugin replacement. +* +ActiveRecord::Base.allow_concurrency+ no longer has any effect. +* +ActiveRecord::Errors.default_error_messages+ has been deprecated in favor of +I18n.translate('activerecord.errors.messages')+ +* The +%s+ and +%d+ interpolation syntax for internationalization is deprecated. +* +String#chars+ has been deprecated in favor of +String#mb_chars+. +* Durations of fractional months or fractional years are deprecated. Use Ruby's core +Date+ and +Time+ class arithmetic instead. + +== Credits + +Release notes compiled by link:http://afreshcup.com[Mike Gunderloy] \ No newline at end of file diff --git a/railties/doc/guides/source/benchmarking_and_profiling/index.txt b/railties/doc/guides/source/benchmarking_and_profiling/index.txt index 15bf7f6a20..ef45ff62c6 100644 --- a/railties/doc/guides/source/benchmarking_and_profiling/index.txt +++ b/railties/doc/guides/source/benchmarking_and_profiling/index.txt @@ -204,11 +204,12 @@ Rails provides a simple generator for creating new performance tests: [source, shell] ---------------------------------------------------------------------------- -[User profiling_tester (master)]$ script/generate performance_test homepage +[lifo@null application (master)]$ script/generate performance_test homepage ---------------------------------------------------------------------------- This will generate +test/performance/homepage_test.rb+: +[source, ruby] ---------------------------------------------------------------------------- require 'test_helper' require 'performance_test_help' -- cgit v1.2.3 From 1a0e7390fc29cd2dee03bcf9e4c80e546a2134b8 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 23 Oct 2008 19:26:52 +0530 Subject: Fix a typo in fxn's name --- railties/doc/guides/html/2_2_release_notes.html | 2 +- railties/doc/guides/source/2_2_release_notes.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index e30145c90f..c00165efb0 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -422,7 +422,7 @@ Lead Contributors: Rails Documen
  • -Major contributions from Xavier Nora and Hongli Lai. +Major contributions from Xavier Noria and Hongli Lai.

  • diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index 57037e04e9..a73e79f6af 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -54,7 +54,7 @@ rake doc:guides This will put the guides inside +RAILS_ROOT/doc/guides+ and you may start surfing straight away by opening +RAILS_ROOT/doc/guides/index.html+ in your favourite browser. * Lead Contributors: link:http://guides.rails.info/authors.html[Rails Documentation Team] -* Major contributions from link:http://advogato.org/person/fxn/diary.html[Xavier Nora] and link:http://izumi.plan99.net/blog/[Hongli Lai]. +* Major contributions from link:http://advogato.org/person/fxn/diary.html[Xavier Noria] and link:http://izumi.plan99.net/blog/[Hongli Lai]. * More information: - link:http://hackfest.rubyonrails.org/guide[Rails Guides hackfest] - link:http://weblog.rubyonrails.org/2008/5/2/help-improve-rails-documentation-on-git-branch[Help improve Rails documentation on Git branch] -- cgit v1.2.3 From 57c31a380e0136607f3ce6ee568730ec1539e163 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 23 Oct 2008 20:14:20 +0200 Subject: Prepare for Rails 2.2.0 [RC1] --- railties/CHANGELOG | 2 +- railties/Rakefile | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'railties') diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 51d66e4c01..3d848b267c 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,4 +1,4 @@ -*Edge* +*2.2.0 [RC1] (October 23rd, 2008)* * Fixed that sqlite would report "db/development.sqlite3 already exists" whether true or not on db:create #614 [Antonio Cangiano] diff --git a/railties/Rakefile b/railties/Rakefile index 5100b4bd9b..981b3ab58b 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -348,12 +348,12 @@ spec = Gem::Specification.new do |s| on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates. EOF - s.add_dependency('rake', '>= 0.8.1') - s.add_dependency('activesupport', '= 2.1.0' + PKG_BUILD) - s.add_dependency('activerecord', '= 2.1.0' + PKG_BUILD) - s.add_dependency('actionpack', '= 2.1.0' + PKG_BUILD) - s.add_dependency('actionmailer', '= 2.1.0' + PKG_BUILD) - s.add_dependency('activeresource', '= 2.1.0' + PKG_BUILD) + s.add_dependency('rake', '>= 0.8.3') + s.add_dependency('activesupport', '= 2.2.0' + PKG_BUILD) + s.add_dependency('activerecord', '= 2.2.0' + PKG_BUILD) + s.add_dependency('actionpack', '= 2.2.0' + PKG_BUILD) + s.add_dependency('actionmailer', '= 2.2.0' + PKG_BUILD) + s.add_dependency('activeresource', '= 2.2.0' + PKG_BUILD) s.rdoc_options << '--exclude' << '.' s.has_rdoc = false -- cgit v1.2.3 From eec6e0cbbddcc9bf141387536d4b910cc0df9d4d Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 23 Oct 2008 20:18:11 +0200 Subject: Push to new gem server --- railties/Rakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'railties') diff --git a/railties/Rakefile b/railties/Rakefile index 981b3ab58b..6b98798632 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -378,8 +378,8 @@ end # Publishing ------------------------------------------------------- desc "Publish the rails gem" task :pgem => [:gem] do - Rake::SshFilePublisher.new("wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh wrath.rubyonrails.org './gemupdate.sh'` + Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload + `ssh gems.rubyonrails.org './gemupdate.sh'` end desc "Publish the API documentation" -- cgit v1.2.3 From 5366e61458cb642429a80297abefddcda6696abe Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 23 Oct 2008 20:29:25 +0200 Subject: Proper update call for gem server --- railties/Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties') diff --git a/railties/Rakefile b/railties/Rakefile index 6b98798632..adb6db0b64 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -379,7 +379,7 @@ end desc "Publish the rails gem" task :pgem => [:gem] do Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh gems.rubyonrails.org './gemupdate.sh'` + `ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'` end desc "Publish the API documentation" -- cgit v1.2.3 From d224e6ccb131559190f35c8ddfc9b31274ac5a89 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 24 Oct 2008 13:08:47 +0200 Subject: Update CHANGELOGs with the last few fixes, set date for today --- railties/CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties') diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 3d848b267c..390da3b890 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,4 +1,4 @@ -*2.2.0 [RC1] (October 23rd, 2008)* +*2.2.0 [RC1] (October 24th, 2008)* * Fixed that sqlite would report "db/development.sqlite3 already exists" whether true or not on db:create #614 [Antonio Cangiano] -- cgit v1.2.3 From f8079b815b41c5f7ecac736a232471f285fa0330 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 24 Oct 2008 17:59:45 +0530 Subject: Add some more info to the release notes --- railties/doc/guides/html/2_2_release_notes.html | 36 +++++++++++++++++++++++- railties/doc/guides/source/2_2_release_notes.txt | 19 +++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index c00165efb0..199a673a06 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -229,6 +229,8 @@ ul#navMain {
  • New Dynamic Finders
  • +
  • Associations Respect Private/Protected Scope
  • +
  • Other ActiveRecord Changes
  • @@ -502,6 +504,11 @@ More information :
    -

    5.5. Other ActiveRecord Changes

    +

    5.5. Associations Respect Private/Protected Scope

    +

    Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) @user.account.private_method would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use @user.account.send(:private_method) (or make the method public instead of private or protected). Please note that if you're overriding method_missing, you should also override respond_to to match the behavior in order for associations to function normally.

    +
      +
    • +

      +Lead Contributor: Adam Milligan +

      +
    • +
    +

    5.6. Other ActiveRecord Changes

    • @@ -1045,6 +1061,24 @@ Wrapped Rails.env in StringQuestioneer so you can do Rails

    • +Implicit local assignments when rendering partials has been deprecated. +

      +
    • +
    +
    +
    +
    def partial_with_implicit_local_assignment
    +  @customer = Customer.new("Marcel")
    +  render :partial => "customer"
    +end
    +
    +

    Previously the above code made available a local variable called customer available inside the partial customer. You should explicitly pass all the variables via :locals hash now.

    +
      +
    • +

      country_select has been removed. See the deprecation page for more information and a plugin replacement.

    • diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index a73e79f6af..303d03548b 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -108,6 +108,7 @@ config.threadsafe! ------------------------------------------------------- * More information : + - link:http://m.onkey.org/2008/10/23/thread-safety-for-your-rails[Thread safety for your Rails] - link:http://weblog.rubyonrails.org/2008/8/16/josh-peek-officially-joins-the-rails-core[Thread safety project announcement] - link:http://blog.headius.com/2008/08/qa-what-thread-safe-rails-means.html[Q/A: What Thread-safe Rails Means] @@ -191,6 +192,12 @@ User.find_by_name!('Moby') * Lead Contributor: link:http://blog.hasmanythrough.com[Josh Susser] +=== Associations Respect Private/Protected Scope + +Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) +@user.account.private_method+ would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use +@user.account.send(:private_method)+ (or make the method public instead of private or protected). Please note that if you're overriding +method_missing+, you should also override +respond_to+ to match the behavior in order for associations to function normally. + +* Lead Contributor: Adam Milligan + === Other ActiveRecord Changes * +rake db:migrate:redo+ now accepts an optional VERSION to target that specific migration to redo @@ -384,6 +391,18 @@ A few pieces of older code are deprecated in this release: * +Rails::SecretKeyGenerator+ has been replaced by +ActiveSupport::SecureRandom+ * +render_component+ is deprecated. There's a link:http://github.com/rails/render_component/tree/master[render_components plugin] available if you need this functionality. +* Implicit local assignments when rendering partials has been deprecated. + +[source, ruby] +------------------------------------------------------- +def partial_with_implicit_local_assignment + @customer = Customer.new("Marcel") + render :partial => "customer" +end +------------------------------------------------------- + +Previously the above code made available a local variable called +customer+ available inside the partial 'customer'. You should explicitly pass all the variables via :locals hash now. + * +country_select+ has been removed. See the link:http://www.rubyonrails.org/deprecation/list-of-countries[deprecation page] for more information and a plugin replacement. * +ActiveRecord::Base.allow_concurrency+ no longer has any effect. * +ActiveRecord::Errors.default_error_messages+ has been deprecated in favor of +I18n.translate('activerecord.errors.messages')+ -- cgit v1.2.3 From a17fc20eb122d45a017e99e592e5e159025ab26b Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 24 Oct 2008 18:05:52 +0530 Subject: Fix a typo --- railties/doc/guides/html/2_2_release_notes.html | 68 ++++++++++++------------ railties/doc/guides/source/2_2_release_notes.txt | 2 +- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index 199a673a06..c657be20b4 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -230,7 +230,7 @@ ul#navMain {
    • New Dynamic Finders
    • Associations Respect Private/Protected Scope
    • - +
    • Other ActiveRecord Changes
    @@ -504,11 +504,11 @@ More information : -

    5.5. Associations Respect Private/Protected Scope

    -

    Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) @user.account.private_method would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use @user.account.send(:private_method) (or make the method public instead of private or protected). Please note that if you're overriding method_missing, you should also override respond_to to match the behavior in order for associations to function normally.

    -
      -
    • -

      -Lead Contributor: Adam Milligan -

      -
    • -
    -

    5.6. Other ActiveRecord Changes

    +

    5.5. Associations Respect Private/Protected Scope

    +

    Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) @user.account.private_method would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use @user.account.send(:private_method) (or make the method public instead of private or protected). Please note that if you're overriding method_missing, you should also override respond_to to match the behavior in order for associations to function normally.

    +
      +
    • +

      +Lead Contributor: Adam Milligan +

      +
    • +
    +

    5.6. Other ActiveRecord Changes

    • @@ -1061,24 +1061,24 @@ Wrapped Rails.env in StringQuestioneer so you can do Rails

    • -Implicit local assignments when rendering partials has been deprecated. -

      -
    • -
    -
    -
    -
    def partial_with_implicit_local_assignment
    -  @customer = Customer.new("Marcel")
    -  render :partial => "customer"
    -end
    -
    -

    Previously the above code made available a local variable called customer available inside the partial customer. You should explicitly pass all the variables via :locals hash now.

    -
      -
    • -

      +Implicit local assignments when rendering partials has been deprecated. +

      +
    • +
    +
    +
    +
    def partial_with_implicit_local_assignment
    +  @customer = Customer.new("Marcel")
    +  render :partial => "customer"
    +end
    +
    +

    Previously the above code made available a local variable called customer inside the partial customer. You should explicitly pass all the variables via :locals hash now.

    +
      +
    • +

      country_select has been removed. See the deprecation page for more information and a plugin replacement.

    • diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index 303d03548b..2623f21371 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -401,7 +401,7 @@ def partial_with_implicit_local_assignment end ------------------------------------------------------- -Previously the above code made available a local variable called +customer+ available inside the partial 'customer'. You should explicitly pass all the variables via :locals hash now. +Previously the above code made available a local variable called +customer+ inside the partial 'customer'. You should explicitly pass all the variables via :locals hash now. * +country_select+ has been removed. See the link:http://www.rubyonrails.org/deprecation/list-of-countries[deprecation page] for more information and a plugin replacement. * +ActiveRecord::Base.allow_concurrency+ no longer has any effect. -- cgit v1.2.3 From 75320ac50ab86e60d3413c20e663e64f1108c72c Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Fri, 24 Oct 2008 07:42:17 -0500 Subject: Added details on how Rails locates layouts to Layouts & Rendering guide --- .../doc/guides/source/layouts_and_rendering.txt | 124 ++++++++++++++++++++- 1 file changed, 120 insertions(+), 4 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/source/layouts_and_rendering.txt b/railties/doc/guides/source/layouts_and_rendering.txt index ed56b82ffd..c4bb5b0591 100644 --- a/railties/doc/guides/source/layouts_and_rendering.txt +++ b/railties/doc/guides/source/layouts_and_rendering.txt @@ -186,7 +186,7 @@ render :file => filename, :content_type => 'application/rss' ===== The +:layout+ Option -With most of the options to +render+, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide. To find the current layout, Rails first looks for a file in +app/views/layouts+ with the same base name as the controller. For example, rendering actions from the +PhotosController+ class will use +/app/views/layouts/photos.html.erb+. If there is no such controller-specific layout, Rails will use +/app/views/layouts/application.html.erb+. +With most of the options to +render+, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide. You can use the +:layout+ option to tell Rails to use a specific file as the layout for the current action: @@ -223,6 +223,124 @@ You can use the +:location+ option to set the HTTP +Location+ header: render :xml => photo, :location => photo_url(photo) ------------------------------------------------------- +==== Finding Layouts + +To find the current layout, Rails first looks for a file in +app/views/layouts+ with the same base name as the controller. For example, rendering actions from the +PhotosController+ class will use +/app/views/layouts/photos.html.erb+. If there is no such controller-specific layout, Rails will use +/app/views/layouts/application.html.erb+. If there is no +.erb+ layout, Rails will use a +.builder+ layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions. + +===== Specifying Layouts on a per-Controller Basis + +You can override the automatic layout conventions in your controllers by using the +layout+ declaration in the controller. For example: + +[source, ruby] +------------------------------------------------------- +class ProductsController < ApplicationController + layout "inventory" + #... +end +------------------------------------------------------- + +With this declaration, all methods within +ProductsController+ will use +app/views/layouts/inventory.html.erb+ for their layout. + +To assign a specific layout for the entire application, use a declaration in your +ApplicationController+ class: + +[source, ruby] +------------------------------------------------------- +class ApplicationController < ActionController::Base + layout "main" + #... +end +------------------------------------------------------- + +With this declaration, all views in the entire application will use +app/views/layouts/main.html.erb+ for their layout. + +===== Choosing Layouts at Runtime + +You can use a symbol to defer the choice of layout until a request is processed: + +[source, ruby] +------------------------------------------------------- +class ProductsController < ApplicationController + layout :products_layout + + def show + @product = Product.find(params[:id]) + end + + private + def products_layout + @current_user.special? ? "special" : "products" + end + +end +------------------------------------------------------- + +Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout: + +[source, ruby] +------------------------------------------------------- +class ProductsController < ApplicationController + layout proc{ |controller| controller. + # ... +end +------------------------------------------------------- + +===== Conditional Layouts + +Layouts specified at the controller level support +:only+ and +:except+ options that take either a method name or an array of method names: + +------------------------------------------------------- +class ProductsController < ApplicationController + layout "inventory", :only => :index + layout "product", :except => [:index, :rss] + #... +end +------------------------------------------------------- + +With those declarations, the +inventory+ layout would be used only for the +index+ method, the +product+ layout would be used for everything else except the +rss+ method, and the +rss+ method will have its layout determined by the automatic layout rules. + +===== Layout Inheritance + +Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example: + +[source, ruby] +------------------------------------------------------- +class ApplicationController < ActionController::Base + layout "main" + #... +end + +class PostsController < ApplicationController + # ... +end + +class SpecialPostsController < PostsController + layout "special" + # ... +end + +class OldPostsController < SpecialPostsController + layout nil + + def show + @post = Post.find(params[:id]) + end + + def index + @old_posts = Post.older + render :layout => "old" + end + # ... +end +------------------------------------------------------- + +In this application: + +* In general, views will be rendered in the +main+ layout +* +PostsController#index+ will use the +main+ layout +* +SpecialPostsController#index+ will use the +special+ layout +* +OldPostsController#show+ will use no layout at all +* +OldPostsController#index+ will use the +old+ layout + ==== Avoiding Double Render Errors Sooner or later, most Rails developers will see the error message "Can only render or redirect once per action". While this is annoying, it's relatively easy to fix. Usually it happens because of a fundamental misunderstanding of the way that +render+ works. @@ -332,9 +450,7 @@ head :created, :location => photo_path(@photo) == Structuring Layouts -When Rails renders a view as a response, it does so by combining the view with the current layout. To find the current layout, Rails first looks for a file in +app/views/layouts+ with the same base name as the controller. For example, rendering actions from the +PhotosController+ class will use +/app/views/layouts/photos.html.erb+. If there is no such controller-specific layout, Rails will use +/app/views/layouts/application.html.erb+. You can also specify a particular layout by using the +:layout+ option to +render+. - -Within a layout, you have access to three tools for combining different bits of output to form the overall response: +When Rails renders a view as a response, it does so by combining the view with the current layout (using the rules for finding the current layout that were covered earlier in this guide). Within a layout, you have access to three tools for combining different bits of output to form the overall response: * Asset tags * +yield+ and +content_for+ -- cgit v1.2.3 From 3e6686dc9ee900e75828bafa63a0bfecc4cd504a Mon Sep 17 00:00:00 2001 From: Tore Darell Date: Fri, 24 Oct 2008 15:42:26 +0200 Subject: Add link to Layouts & rendering guide --- railties/doc/guides/source/actioncontroller_basics/methods.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties') diff --git a/railties/doc/guides/source/actioncontroller_basics/methods.txt b/railties/doc/guides/source/actioncontroller_basics/methods.txt index a1ef204adb..370b492e41 100644 --- a/railties/doc/guides/source/actioncontroller_basics/methods.txt +++ b/railties/doc/guides/source/actioncontroller_basics/methods.txt @@ -34,4 +34,4 @@ def new end ---------------------------------------------- -The Layouts & rendering guide explains this in more detail. +The link:../layouts_and_rendering.html[Layouts & rendering guide] explains this in more detail. -- cgit v1.2.3 From 9ae15df21c3c3be4f46759b41a752f5b05333196 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Fri, 24 Oct 2008 08:50:05 -0500 Subject: Updates to Getting Started: REST references, partials, filters, some cleanup. --- .../guides/source/getting_started_with_rails.txt | 131 ++++++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/source/getting_started_with_rails.txt b/railties/doc/guides/source/getting_started_with_rails.txt index 8f0ebe674e..45e6485886 100644 --- a/railties/doc/guides/source/getting_started_with_rails.txt +++ b/railties/doc/guides/source/getting_started_with_rails.txt @@ -107,6 +107,12 @@ For example, to a Rails application a request such as this: would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities. +If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis: + +* link:http://www.infoq.com/articles/rest-introduction[A Brief Introduction to REST] by Stefan Tilkov +* link:http://bitworking.org/news/373/An-Introduction-to-REST[An Introduction to REST] (video tutorial) by Joe Gregorio +* link:http://en.wikipedia.org/wiki/Representational_State_Transfer[Representational State Transfer] article in Wikipedia + == Creating a New Rails Project If you follow this guide, you'll create a Rails project called +blog+, a (very) simple weblog. Before you can start building the application, you need to make sure that you have Rails itself installed. @@ -715,7 +721,7 @@ end In the +update+ action, Rails first uses the +:id+ parameter passed back from the edit view to locate the database record that's being edited. The +update_attributes+ call then takes the rest of the parameters from the request and applies them to this record. If all goes well, the user is redirected to the post's +show+ view. If there are any problems, it's back to +edit+ to correct them. -NOTE: Sharp-eyed readers will have noticed that the +form_for+ declaration is identical for the +create+ and +edit+ views. Rails generates different code for the two forms because it's smart enough to notice that in the one case it's being passed a new record that has never been saved, and in the other case an existing record that has already been saved to the database. In a production Rails application, you would ordinarily eliminate this duplication by moving identical code to a _partial template_, which you could then include in both parent templates. But the scaffold generator tries not to make too many assumptions, and generates code that’s easy to modify if you want different forms for +create+ and +edit+. +NOTE: Sharp-eyed readers will have noticed that the +form_for+ declaration is identical for the +new+ and +edit+ views. Rails generates different code for the two forms because it's smart enough to notice that in the one case it's being passed a new record that has never been saved, and in the other case an existing record that has already been saved to the database. In a production Rails application, you would ordinarily eliminate this duplication by moving identical code to a _partial template_, which you could then include in both parent templates. But the scaffold generator tries not to make too many assumptions, and generates code that’s easy to modify if you want different forms for +create+ and +edit+. === Destroying a Post @@ -736,6 +742,125 @@ end The +destroy+ method of an Active Record model instance removes the corresponding record from the database. After that's done, there isn't any record to display, so Rails redirects the user's browser to the index view for the model. +== DRYing up the Code + +At this point, it’s worth looking at some of the tools that Rails provides to eliminate duplication in your code. In particular, you can use _partials_ to clean up duplication in views and _filters_ to help with duplication in controllers. + +=== Using Partials to Eliminate View Duplication + +As you saw earlier, the scaffold-generated views for the +new+ and +edit+ actions are largely identical. You can pull the shared code out into a +partial+ template. This requires editing the new and edit views, and adding a new template: + ++new.html.erb+: +[source, ruby] +------------------------------------------------------- +

      New post

      + +<%= render :partial => "form" %> + +<%= link_to 'Back', posts_path %> +------------------------------------------------------- + ++edit.html.erb+: +[source, ruby] +------------------------------------------------------- +

      Editing post

      + +<%= render :partial => "form" %> + +<%= link_to 'Show', @post %> | +<%= link_to 'Back', posts_path %> +------------------------------------------------------- + ++_form.html.erb+: +[source, ruby] +------------------------------------------------------- +<% form_for(@post) do |f| %> + <%= f.error_messages %> + +

      + <%= f.label :name %>
      + <%= f.text_field :name %> +

      +

      + <%= f.label :title, "title" %>
      + <%= f.text_field :title %> +

      +

      + <%= f.label :content %>
      + <%= f.text_area :content %> +

      +

      + <%= f.submit "Save" %> +

      +<% end %> +------------------------------------------------------- + +Now, when Rails renders the +new+ or +edit+ view, it will insert the +_form+ partial at the indicated point. Note the naming convention for partials: if you refer to a partial named +form+ inside of a view, the corresponding file is +_form.html.erb+, with a leading underscore. + +For more information on partials, refer to the link:../layouts_and_rendering.html[Layouts and Rending in Rails] guide. + +=== Using Filters to Eliminate Controller Duplication + +At this point, if you look at the controller for posts, you’ll see some duplication: + +[source, ruby] +------------------------------------------------------- +class PostsController < ApplicationController + # ... + def show + @post = Post.find(params[:id]) + # ... + end + + def edit + @post = Post.find(params[:id]) + end + + def update + @post = Post.find(params[:id]) + # ... + end + + def destroy + @post = Post.find(params[:id]) + # ... + end +end +------------------------------------------------------- + +Four instances of the exact same line of code doesn’t seem very DRY. Rails provides _filters_ as a way to address this sort of repeated code. In this case, you can DRY things up by using a +before_filter+: + +[source, ruby] +------------------------------------------------------- +class PostsController < ApplicationController + before_filter :find_post, :only => [:show, :edit, :update, :destroy] + # ... + def show + # ... + end + + def edit + end + + def update + # ... + end + + def destroy + # ... + end + + private + def find_post + @post = Post.find(params[:id]) + end +end +------------------------------------------------------- + +Rails runs _before filters_ before any action in the controller. You can use the +:only+ clause to limit a before filter to only certain actions, or an +:except+ clause to specifically skip a before filter for certain actions. Rails also allows you to define _after filters_ that run after processing an action, as well as _around filters_ that surround the processing of actions. Filters can also be defined in external classes to make it easy to share them between controllers. + +For more information on filters, see the link:actioncontroller_basics.html[Action Controller Basics] guide. + == Adding a Second Model Now that you've seen what's in a model built with scaffolding, it's time to add a second model to the application. The second model will handle comments on blog posts. @@ -798,7 +923,7 @@ Rails is smart enough to only execute the migrations that have not already been === Associating Models -Active Record associations let you declaratively quantify the relationship between two models. In the case of comments and posts, you could write out the relationships this way: +Active Record associations let you easily declare the relationship between two models. In the case of comments and posts, you could write out the relationships this way: * Each comment belongs to one post * One post can have many comments @@ -825,7 +950,7 @@ end These two declarations enable a good bit of automatic behavior. For example, if you have an instance variable +@post+ containing a post, you can retrieve all the comments belonging to that post as the array +@post.comments+. -TIP: For more information on Active Record associations, see the link:../association_basics.html+[Active Record Associations] guide. +TIP: For more information on Active Record associations, see the link:../association_basics.html[Active Record Associations] guide. === Adding a Route -- cgit v1.2.3 From 190381ae95e06446e1bd0f848a05ae614bb5121f Mon Sep 17 00:00:00 2001 From: Heiko Webers Date: Fri, 24 Oct 2008 18:38:46 +0200 Subject: new header injection section for security guide --- railties/doc/guides/source/security.txt | 63 +++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/source/security.txt b/railties/doc/guides/source/security.txt index d068a22491..53819babb7 100644 --- a/railties/doc/guides/source/security.txt +++ b/railties/doc/guides/source/security.txt @@ -2,7 +2,7 @@ Ruby On Rails Security Guide ============================ This manual describes common security problems in web applications and how to avoid them with Rails. If you have any questions or suggestions, please -mail me at 42 {_et_} rorsecurity.info. After reading it, you should be familiar with: +mail me, Heiko Webers, at 42 {_et_} rorsecurity.info. After reading it, you should be familiar with: - All countermeasures [,#fffcdb]#that are highlighted# - The concept of sessions in Rails, what to put in there and popular attack methods @@ -858,7 +858,8 @@ This example, again, showed that a blacklist filter is never complete. However, -- _If you want to provide text formatting other than HTML (due to security), use a mark-up language which is converted to HTML on the server-side. http://whytheluckystiff.net/ruby/redcloth/[RedCloth] is such a language for Ruby, but without precautions, it is also vulnerable to XSS._ -For example, RedCloth translates _test_ to test, which makes the text italic. However, up to the current version 3.0.4, it is still vulnerable to XSS: + For example, RedCloth translates _test_ to test, which makes the text italic. However, up to the current version 3.0.4, it is still vulnerable to XSS. Get the http://www.redcloth.org[all-new version 4] that removed serious bugs. However, even that version has http://www.rorsecurity.info/journal/2008/10/13/new-redcloth-security.html[some security bugs], so the countermeasures still apply. Here is an example for version 3.0.4: + ........... >> RedCloth.new('').to_html @@ -908,6 +909,64 @@ system("/bin/echo","hello; rm *") # prints "hello; rm *" and does not delete files .......... + +=== Header Injection +-- _HTTP headers are dynamically generated and under certain circumstances user input may be injected. This can lead to false redirection, XSS or HTTP response splitting._ + +HTTP request headers have a Referer, User-Agent (client software) and Cookie field, among others. Response headers for example have a status code, Cookie and Location (redirection target URL) field. All of them are user-supplied and may be manipulated with more or less effort. [,#fffcdb]#Remember to escape these header fields, too.# For example when you display the user agent in an administration area. + +Besides that, it is [,#fffcdb]#important to know what you are doing when building response headers partly based on user input.# For example you want to redirect the user back to a specific page. To do that you introduced a “referer“ field in a form to redirect to the given address: + +.......... +redirect_to params[:referer] +.......... + +What happens is that Rails puts the string into the Location header field and sends a 302 (redirect) status to the browser. The first thing a malicious user would do, is this: + +.......... +http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld +.......... + +And due to a bug in (Ruby and) Rails up to version 2.1.2 (excluding it), a hacker may inject arbitrary header fields; for example like this: + +.......... +http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld%0d%0aX-Header:+Hi! +http://www.yourapplication.com/controller/action?referer=path/at/your/app%0d%0aLocation:+http://www.malicious.tld +.......... + +Note that "%0d%0a" is URL-encoded for "\r\n" which is a carriage-return and line-feed (CRLF) in Ruby. So the resulting HTTP header for the second example will be the following because the second Location header field overwrites the first. + +.......... +HTTP/1.1 302 Moved Temporarily +(...) +Location: http://www.malicious.tld +.......... + +So [,#fffcdb]#attack vectors for Header Injection are based on the injection of CRLF characters in a header field.# And what could an attacker do with a false redirection? He could redirect to a phishing site that looks the same as yours, but asks to login again (and sends the login credentials to the attacker). Or he could install malicious software through browser security holes on that site. [,#fffcdb]#Rails 2.1.2 escapes these characters for the Location field in the redirect_to method. Make sure you do it yourself when you build other header fields with user input.# + +==== Response Splitting +If Header Injection was possible, Response Splitting might be, too. In HTTP, the header block is followed by two CRLFs and the actual data (usually HTML). The idea of Response Splitting is to inject two CRLFs into a header field, followed by another response with malicious HTML. The response will be: + +.......... +HTTP/1.1 302 Found [First standard 302 response] +Date: Tue, 12 Apr 2005 22:09:07 GMT +Location:
Content-Type: text/html + + +HTTP/1.1 200 OK [Second New response created by attacker begins] +Content-Type: text/html + + +hey [Arbitary malicious input is +Keep-Alive: timeout=15, max=100 shown as the redirected page] +Connection: Keep-Alive +Transfer-Encoding: chunked +Content-Type: text/html +.......... + +Under certain circumstances this would present the malicious HTML to the victim. However, this seems to work with Keep-Alive connections, only (and many browsers are using one-time connections). But you can't rely on this. [,#fffcdb]#In any case this is a serious bug, and you should update your Rails to version 2.0.5 or 2.1.2 to eliminate Header Injection (and thus response splitting) risks.# + + == Additional resources The security landscape shifts and it is important to keep up to date, because missing a new vulnerability can be catastrophic. You can find additional resources about (Rails) security here: -- cgit v1.2.3 From ec5070c2e2d46c5f209da99bb2f3b455ec02c349 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 24 Oct 2008 22:13:06 +0530 Subject: Generate new guides --- .../doc/guides/html/actioncontroller_basics.html | 2 +- .../guides/html/getting_started_with_rails.html | 166 +++++++++++++++++++-- .../doc/guides/html/layouts_and_rendering.html | 140 ++++++++++++++++- 3 files changed, 291 insertions(+), 17 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/actioncontroller_basics.html b/railties/doc/guides/html/actioncontroller_basics.html index 9bba0d301a..4057981a0d 100644 --- a/railties/doc/guides/html/actioncontroller_basics.html +++ b/railties/doc/guides/html/actioncontroller_basics.html @@ -331,7 +331,7 @@ http://www.gnu.org/software/src-highlite --> @client = Client.new end
    -

    The Layouts & rendering guide explains this in more detail.

    +

    The Layouts & rendering guide explains this in more detail.

    3. Parameters

    diff --git a/railties/doc/guides/html/getting_started_with_rails.html b/railties/doc/guides/html/getting_started_with_rails.html index e7be98d34a..c53167a6ac 100644 --- a/railties/doc/guides/html/getting_started_with_rails.html +++ b/railties/doc/guides/html/getting_started_with_rails.html @@ -269,6 +269,16 @@ ul#navMain {
  • + DRYing up the Code + +
  • +
  • Adding a Second Model
      @@ -480,6 +490,24 @@ Transferring representations of the state of that resource between system compon

      For example, to a Rails application a request such as this:

      DELETE /photos/17

      would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities.

      +

      If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis:

      +
  • 3. Creating a New Rails Project

    @@ -1402,7 +1430,7 @@ http://www.gnu.org/software/src-highlite --> Note -Sharp-eyed readers will have noticed that the form_for declaration is identical for the create and edit views. Rails generates different code for the two forms because it's smart enough to notice that in the one case it's being passed a new record that has never been saved, and in the other case an existing record that has already been saved to the database. In a production Rails application, you would ordinarily eliminate this duplication by moving identical code to a partial template, which you could then include in both parent templates. But the scaffold generator tries not to make too many assumptions, and generates code that’s easy to modify if you want different forms for create and edit. +Sharp-eyed readers will have noticed that the form_for declaration is identical for the new and edit views. Rails generates different code for the two forms because it's smart enough to notice that in the one case it's being passed a new record that has never been saved, and in the other case an existing record that has already been saved to the database. In a production Rails application, you would ordinarily eliminate this duplication by moving identical code to a partial template, which you could then include in both parent templates. But the scaffold generator tries not to make too many assumptions, and generates code that’s easy to modify if you want different forms for create and edit.

    6.12. Destroying a Post

    @@ -1424,10 +1452,124 @@ http://www.gnu.org/software/src-highlite -->

    The destroy method of an Active Record model instance removes the corresponding record from the database. After that's done, there isn't any record to display, so Rails redirects the user's browser to the index view for the model.

    -

    7. Adding a Second Model

    +

    7. DRYing up the Code

    +
    +

    At this point, it’s worth looking at some of the tools that Rails provides to eliminate duplication in your code. In particular, you can use partials to clean up duplication in views and filters to help with duplication in controllers.

    +

    7.1. Using Partials to Eliminate View Duplication

    +

    As you saw earlier, the scaffold-generated views for the new and edit actions are largely identical. You can pull the shared code out into a partial template. This requires editing the new and edit views, and adding a new template:

    +

    new.html.erb: +[source, ruby]

    +
    +
    +
    <h1>New post</h1>
    +
    +<%= render :partial => "form" %>
    +
    +<%= link_to 'Back', posts_path %>
    +
    +

    edit.html.erb: +[source, ruby]

    +
    +
    +
    <h1>Editing post</h1>
    +
    +<%= render :partial => "form" %>
    +
    +<%= link_to 'Show', @post %> |
    +<%= link_to 'Back', posts_path %>
    +
    +

    _form.html.erb: +[source, ruby]

    +
    +
    +
    <% form_for(@post) do |f| %>
    +  <%= f.error_messages %>
    +
    +  <p>
    +    <%= f.label :name %><br />
    +    <%= f.text_field :name %>
    +  </p>
    +  <p>
    +    <%= f.label :title, "title" %><br />
    +    <%= f.text_field :title %>
    +  </p>
    +  <p>
    +    <%= f.label :content %><br />
    +    <%= f.text_area :content %>
    +  </p>
    +  <p>
    +    <%= f.submit "Save" %>
    +  </p>
    +<% end %>
    +
    +

    Now, when Rails renders the new or edit view, it will insert the _form partial at the indicated point. Note the naming convention for partials: if you refer to a partial named form inside of a view, the corresponding file is _form.html.erb, with a leading underscore.

    +

    For more information on partials, refer to the Layouts and Rending in Rails guide.

    +

    7.2. Using Filters to Eliminate Controller Duplication

    +

    At this point, if you look at the controller for posts, you’ll see some duplication:

    +
    +
    +
    class PostsController < ApplicationController
    +  # ...
    +  def show
    +    @post = Post.find(params[:id])
    +        # ...
    +  end
    +
    +  def edit
    +    @post = Post.find(params[:id])
    +  end
    +
    +  def update
    +    @post = Post.find(params[:id])
    +    # ...
    +  end
    +
    +  def destroy
    +    @post = Post.find(params[:id])
    +    # ...
    +  end
    +end
    +
    +

    Four instances of the exact same line of code doesn’t seem very DRY. Rails provides filters as a way to address this sort of repeated code. In this case, you can DRY things up by using a before_filter:

    +
    +
    +
    class PostsController < ApplicationController
    +  before_filter :find_post, :only => [:show, :edit, :update, :destroy]
    +  # ...
    +  def show
    +        # ...
    +  end
    +
    +  def edit
    +  end
    +
    +  def update
    +    # ...
    +  end
    +
    +  def destroy
    +    # ...
    +  end
    +
    +  private
    +    def find_post
    +      @post = Post.find(params[:id])
    +    end
    +end
    +
    +

    Rails runs before filters before any action in the controller. You can use the :only clause to limit a before filter to only certain actions, or an :except clause to specifically skip a before filter for certain actions. Rails also allows you to define after filters that run after processing an action, as well as around filters that surround the processing of actions. Filters can also be defined in external classes to make it easy to share them between controllers.

    +

    For more information on filters, see the Action Controller Basics guide.

    +
    +

    8. Adding a Second Model

    Now that you've seen what's in a model built with scaffolding, it's time to add a second model to the application. The second model will handle comments on blog posts.

    -

    7.1. Generating a Model

    +

    8.1. Generating a Model

    Models in Rails use a singular name, and their corresponding database tables use a plural name. For the model to hold comments, the convention is to use the name Comment. Even if you don't want to use the entire apparatus set up by scaffolding, most Rails developers still use generators to make things like models and controllers. To create the new model, run this command in your terminal:

    $ rake db:migrate
     

    Rails is smart enough to only execute the migrations that have not already been run against this particular database.

    -

    7.2. Associating Models

    -

    Active Record associations let you declaratively quantify the relationship between two models. In the case of comments and posts, you could write out the relationships this way:

    +

    8.2. Associating Models

    +

    Active Record associations let you easily declare the relationship between two models. In the case of comments and posts, you could write out the relationships this way:

    • @@ -1538,10 +1680,10 @@ http://www.gnu.org/software/src-highlite --> Tip -For more information on Active Record associations, see the Active Record Associations guide. +For more information on Active Record associations, see the Active Record Associations guide.

    -

    7.3. Adding a Route

    +

    8.3. Adding a Route

    Routes are entries in the config/routes.rb file that tell Rails how to match incoming HTTP requests to controller actions. Open up that file and find the existing line referring to posts. Then edit it as follows:

    For more information on routing, see the Rails Routing from the Outside In guide.
    -

    7.4. Generating a Controller

    +

    8.4. Generating a Controller

    With the model in hand, you can turn your attention to creating a matching controller. Again, there's a generator for this:

    @comment = @post.comments.build
     

    This creates a new Comment object and sets up the post_id field to have the id from the specified Post object in a single operation.

    -

    7.5. Building Views

    +

    8.5. Building Views

    Because you skipped scaffolding, you'll need to build views for comments "by hand." Invoking script/generate controller will give you skeleton views, but they'll be devoid of actual content. Here's a first pass at fleshing out the comment views.

    The index.html.erb view:

    @@ -1795,7 +1937,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', post_comments_path(@post) %>

    Again, the added complexity here (compared to the views you saw for managing comments) comes from the necessity of juggling a post and its comments at the same time.

    -

    7.6. Hooking Comments to Posts

    +

    8.6. Hooking Comments to Posts

    As a final step, I'll modify the show.html.erb view for a post to show the comments on that post, and to allow managing those comments:

    Note that each post has its own individual comments collection, accessible as @post.comments. That's a consequence of the declarative associations in the models. Path helpers such as post_comments_path come from the nested route declaration in config/routes.rb.

    -

    8. What's Next?

    +

    9. What's Next?

    Now that you've seen your first Rails application, you should feel free to update it and experiment on your own. But you don't have to do everything without help. As you need assistance getting up and running with Rails, feel free to consult these support resources:

    -

    9. Changelog

    +

    10. Changelog

      diff --git a/railties/doc/guides/html/layouts_and_rendering.html b/railties/doc/guides/html/layouts_and_rendering.html index 916cdd2053..63d060049a 100644 --- a/railties/doc/guides/html/layouts_and_rendering.html +++ b/railties/doc/guides/html/layouts_and_rendering.html @@ -523,7 +523,7 @@ http://www.gnu.org/software/src-highlite -->
      render :file => filename, :content_type => 'application/rss'
       
    The :layout Option
    -

    With most of the options to render, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide. To find the current layout, Rails first looks for a file in app/views/layouts with the same base name as the controller. For example, rendering actions from the PhotosController class will use /app/views/layouts/photos.html.erb. If there is no such controller-specific layout, Rails will use /app/views/layouts/application.html.erb.

    +

    With most of the options to render, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide.

    You can use the :layout option to tell Rails to use a specific file as the layout for the current action:

    render :xml => photo, :location => photo_url(photo)
     
    -

    2.2.11. Avoiding Double Render Errors

    +

    2.2.11. Finding Layouts

    +

    To find the current layout, Rails first looks for a file in app/views/layouts with the same base name as the controller. For example, rendering actions from the PhotosController class will use /app/views/layouts/photos.html.erb. If there is no such controller-specific layout, Rails will use /app/views/layouts/application.html.erb. If there is no .erb layout, Rails will use a .builder layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions.

    +
    Specifying Layouts on a per-Controller Basis
    +

    You can override the automatic layout conventions in your controllers by using the layout declaration in the controller. For example:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout "inventory"
    +  #...
    +end
    +
    +

    With this declaration, all methods within ProductsController will use app/views/layouts/inventory.html.erb for their layout.

    +

    To assign a specific layout for the entire application, use a declaration in your ApplicationController class:

    +
    +
    +
    class ApplicationController < ActionController::Base
    +  layout "main"
    +  #...
    +end
    +
    +

    With this declaration, all views in the entire application will use app/views/layouts/main.html.erb for their layout.

    +
    Choosing Layouts at Runtime
    +

    You can use a symbol to defer the choice of layout until a request is processed:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout :products_layout
    +
    +  def show
    +    @product = Product.find(params[:id])
    +  end
    +
    +  private
    +    def products_layout
    +      @current_user.special? ? "special" : "products"
    +    end
    +
    +end
    +
    +

    Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout proc{ |controller| controller.
    +  # ...
    +end
    +
    +
    Conditional Layouts
    +

    Layouts specified at the controller level support :only and :except options that take either a method name or an array of method names:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout "inventory", :only => :index
    +  layout "product", :except => [:index, :rss]
    +  #...
    +end
    +
    +

    With those declarations, the inventory layout would be used only for the index method, the product layout would be used for everything else except the rss method, and the rss method will have its layout determined by the automatic layout rules.

    +
    Layout Inheritance
    +

    Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example:

    +
    +
    +
    class ApplicationController < ActionController::Base
    +  layout "main"
    +  #...
    +end
    +
    +class PostsController < ApplicationController
    +  # ...
    +end
    +
    +class SpecialPostsController < PostsController
    +  layout "special"
    +  # ...
    +end
    +
    +class OldPostsController < SpecialPostsController
    +  layout nil
    +
    +  def show
    +    @post = Post.find(params[:id])
    +  end
    +
    +  def index
    +    @old_posts = Post.older
    +    render :layout => "old"
    +  end
    +  # ...
    +end
    +
    +

    In this application:

    +
      +
    • +

      +In general, views will be rendered in the main layout +

      +
    • +
    • +

      +PostsController#index will use the main layout +

      +
    • +
    • +

      +SpecialPostsController#index will use the special layout +

      +
    • +
    • +

      +OldPostsController#show will use no layout at all +

      +
    • +
    • +

      +OldPostsController#index will use the old layout +

      +
    • +
    +

    2.2.12. Avoiding Double Render Errors

    Sooner or later, most Rails developers will see the error message "Can only render or redirect once per action". While this is annoying, it's relatively easy to fix. Usually it happens because of a fundamental misunderstanding of the way that render works.

    For example, here's some code that will trigger this error:

    @@ -666,8 +799,7 @@ http://www.gnu.org/software/src-highlite -->

    3. Structuring Layouts

    -

    When Rails renders a view as a response, it does so by combining the view with the current layout. To find the current layout, Rails first looks for a file in app/views/layouts with the same base name as the controller. For example, rendering actions from the PhotosController class will use /app/views/layouts/photos.html.erb. If there is no such controller-specific layout, Rails will use /app/views/layouts/application.html.erb. You can also specify a particular layout by using the :layout option to render.

    -

    Within a layout, you have access to three tools for combining different bits of output to form the overall response:

    +

    When Rails renders a view as a response, it does so by combining the view with the current layout (using the rules for finding the current layout that were covered earlier in this guide). Within a layout, you have access to three tools for combining different bits of output to form the overall response:

    • -- cgit v1.2.3 From e7f06a8d50b8418c265b859c5e7809bcf0d67cf2 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 24 Oct 2008 22:19:38 +0530 Subject: Fix release notes --- railties/doc/guides/html/2_2_release_notes.html | 7 +++---- railties/doc/guides/source/2_2_release_notes.txt | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index c657be20b4..0be9596a7d 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -586,16 +586,15 @@ by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->

      class Photo < ActiveRecord::Base
      -  belongs_to :Product
      +  belongs_to :product
       end
       
       class Product < ActiveRecord::Base
      -  has_many :products
      +  has_many :photos
       end
       
       # Get all products with copyright-free photos:
      -Product.find(:all, :joins => :photo,
      -  :conditions => { :photos => { :copyright => false }})
      +Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }})
       
    • diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index 00243d6941..d5eeefb16f 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -149,16 +149,15 @@ You can now specify conditions on join tables using a hash. This is a big help i [source, ruby] ------------------------------------------------------- class Photo < ActiveRecord::Base - belongs_to :Product + belongs_to :product end class Product < ActiveRecord::Base - has_many :products + has_many :photos end # Get all products with copyright-free photos: -Product.find(:all, :joins => :photo, - :conditions => { :photos => { :copyright => false }}) +Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }}) ------------------------------------------------------- * More information: -- cgit v1.2.3 From b02e010751d9ffbed01603b525c50a0c2a225ea3 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 24 Oct 2008 22:57:05 +0530 Subject: Regenerate guides again --- railties/doc/guides/html/2_2_release_notes.html | 6 +- .../doc/guides/html/actioncontroller_basics.html | 2 +- .../guides/html/getting_started_with_rails.html | 294 ++++++++++----------- .../doc/guides/html/layouts_and_rendering.html | 272 +++++++++---------- railties/doc/guides/html/security.html | 56 +++- 5 files changed, 341 insertions(+), 289 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index 0be9596a7d..f458c0fa57 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -586,15 +586,15 @@ by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
      class Photo < ActiveRecord::Base
      -  belongs_to :product
      +  belongs_to :product
       end
       
       class Product < ActiveRecord::Base
      -  has_many :photos
      +  has_many :photos
       end
       
       # Get all products with copyright-free photos:
      -Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }})
      +Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }})
       
    • diff --git a/railties/doc/guides/html/actioncontroller_basics.html b/railties/doc/guides/html/actioncontroller_basics.html index 4057981a0d..2809034e27 100644 --- a/railties/doc/guides/html/actioncontroller_basics.html +++ b/railties/doc/guides/html/actioncontroller_basics.html @@ -331,7 +331,7 @@ http://www.gnu.org/software/src-highlite --> @client = Client.new end
    -

    The Layouts & rendering guide explains this in more detail.

    +

    The Layouts & rendering guide explains this in more detail.

    3. Parameters

    diff --git a/railties/doc/guides/html/getting_started_with_rails.html b/railties/doc/guides/html/getting_started_with_rails.html index c53167a6ac..d9a1779d56 100644 --- a/railties/doc/guides/html/getting_started_with_rails.html +++ b/railties/doc/guides/html/getting_started_with_rails.html @@ -271,11 +271,11 @@ ul#navMain {
  • DRYing up the Code
  • @@ -490,24 +490,24 @@ Transferring representations of the state of that resource between system compon

    For example, to a Rails application a request such as this:

    DELETE /photos/17

    would be understood to refer to a photo resource with the ID of 17, and to indicate a desired action - deleting that resource. REST is a natural style for the architecture of web applications, and Rails makes it even more natural by using conventions to shield you from some of the RESTful complexities.

    -

    If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis:

    -
    +

    If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis:

    +
  • 3. Creating a New Rails Project

    @@ -1430,7 +1430,7 @@ http://www.gnu.org/software/src-highlite --> Note -Sharp-eyed readers will have noticed that the form_for declaration is identical for the new and edit views. Rails generates different code for the two forms because it's smart enough to notice that in the one case it's being passed a new record that has never been saved, and in the other case an existing record that has already been saved to the database. In a production Rails application, you would ordinarily eliminate this duplication by moving identical code to a partial template, which you could then include in both parent templates. But the scaffold generator tries not to make too many assumptions, and generates code that’s easy to modify if you want different forms for create and edit. +Sharp-eyed readers will have noticed that the form_for declaration is identical for the new and edit views. Rails generates different code for the two forms because it's smart enough to notice that in the one case it's being passed a new record that has never been saved, and in the other case an existing record that has already been saved to the database. In a production Rails application, you would ordinarily eliminate this duplication by moving identical code to a partial template, which you could then include in both parent templates. But the scaffold generator tries not to make too many assumptions, and generates code that’s easy to modify if you want different forms for create and edit.

    6.12. Destroying a Post

    @@ -1452,124 +1452,124 @@ http://www.gnu.org/software/src-highlite -->

    The destroy method of an Active Record model instance removes the corresponding record from the database. After that's done, there isn't any record to display, so Rails redirects the user's browser to the index view for the model.

    -

    7. DRYing up the Code

    -
    -

    At this point, it’s worth looking at some of the tools that Rails provides to eliminate duplication in your code. In particular, you can use partials to clean up duplication in views and filters to help with duplication in controllers.

    -

    7.1. Using Partials to Eliminate View Duplication

    -

    As you saw earlier, the scaffold-generated views for the new and edit actions are largely identical. You can pull the shared code out into a partial template. This requires editing the new and edit views, and adding a new template:

    -

    new.html.erb: -[source, ruby]

    -
    -
    -
    <h1>New post</h1>
    -
    -<%= render :partial => "form" %>
    -
    -<%= link_to 'Back', posts_path %>
    -
    -

    edit.html.erb: -[source, ruby]

    -
    -
    -
    <h1>Editing post</h1>
    -
    -<%= render :partial => "form" %>
    -
    -<%= link_to 'Show', @post %> |
    -<%= link_to 'Back', posts_path %>
    -
    -

    _form.html.erb: -[source, ruby]

    -
    -
    -
    <% form_for(@post) do |f| %>
    -  <%= f.error_messages %>
    -
    -  <p>
    -    <%= f.label :name %><br />
    -    <%= f.text_field :name %>
    -  </p>
    -  <p>
    -    <%= f.label :title, "title" %><br />
    -    <%= f.text_field :title %>
    -  </p>
    -  <p>
    -    <%= f.label :content %><br />
    -    <%= f.text_area :content %>
    -  </p>
    -  <p>
    -    <%= f.submit "Save" %>
    -  </p>
    -<% end %>
    -
    -

    Now, when Rails renders the new or edit view, it will insert the _form partial at the indicated point. Note the naming convention for partials: if you refer to a partial named form inside of a view, the corresponding file is _form.html.erb, with a leading underscore.

    -

    For more information on partials, refer to the Layouts and Rending in Rails guide.

    -

    7.2. Using Filters to Eliminate Controller Duplication

    -

    At this point, if you look at the controller for posts, you’ll see some duplication:

    -
    -
    -
    class PostsController < ApplicationController
    -  # ...
    -  def show
    -    @post = Post.find(params[:id])
    -        # ...
    -  end
    -
    -  def edit
    -    @post = Post.find(params[:id])
    -  end
    -
    -  def update
    -    @post = Post.find(params[:id])
    -    # ...
    -  end
    -
    -  def destroy
    -    @post = Post.find(params[:id])
    -    # ...
    -  end
    -end
    -
    -

    Four instances of the exact same line of code doesn’t seem very DRY. Rails provides filters as a way to address this sort of repeated code. In this case, you can DRY things up by using a before_filter:

    -
    -
    -
    class PostsController < ApplicationController
    -  before_filter :find_post, :only => [:show, :edit, :update, :destroy]
    -  # ...
    -  def show
    -        # ...
    -  end
    -
    -  def edit
    -  end
    -
    -  def update
    -    # ...
    -  end
    -
    -  def destroy
    -    # ...
    -  end
    -
    -  private
    -    def find_post
    -      @post = Post.find(params[:id])
    -    end
    -end
    -
    -

    Rails runs before filters before any action in the controller. You can use the :only clause to limit a before filter to only certain actions, or an :except clause to specifically skip a before filter for certain actions. Rails also allows you to define after filters that run after processing an action, as well as around filters that surround the processing of actions. Filters can also be defined in external classes to make it easy to share them between controllers.

    -

    For more information on filters, see the Action Controller Basics guide.

    -
    -

    8. Adding a Second Model

    +

    7. DRYing up the Code

    +
    +

    At this point, it’s worth looking at some of the tools that Rails provides to eliminate duplication in your code. In particular, you can use partials to clean up duplication in views and filters to help with duplication in controllers.

    +

    7.1. Using Partials to Eliminate View Duplication

    +

    As you saw earlier, the scaffold-generated views for the new and edit actions are largely identical. You can pull the shared code out into a partial template. This requires editing the new and edit views, and adding a new template:

    +

    new.html.erb: +[source, ruby]

    +
    +
    +
    <h1>New post</h1>
    +
    +<%= render :partial => "form" %>
    +
    +<%= link_to 'Back', posts_path %>
    +
    +

    edit.html.erb: +[source, ruby]

    +
    +
    +
    <h1>Editing post</h1>
    +
    +<%= render :partial => "form" %>
    +
    +<%= link_to 'Show', @post %> |
    +<%= link_to 'Back', posts_path %>
    +
    +

    _form.html.erb: +[source, ruby]

    +
    +
    +
    <% form_for(@post) do |f| %>
    +  <%= f.error_messages %>
    +
    +  <p>
    +    <%= f.label :name %><br />
    +    <%= f.text_field :name %>
    +  </p>
    +  <p>
    +    <%= f.label :title, "title" %><br />
    +    <%= f.text_field :title %>
    +  </p>
    +  <p>
    +    <%= f.label :content %><br />
    +    <%= f.text_area :content %>
    +  </p>
    +  <p>
    +    <%= f.submit "Save" %>
    +  </p>
    +<% end %>
    +
    +

    Now, when Rails renders the new or edit view, it will insert the _form partial at the indicated point. Note the naming convention for partials: if you refer to a partial named form inside of a view, the corresponding file is _form.html.erb, with a leading underscore.

    +

    For more information on partials, refer to the Layouts and Rending in Rails guide.

    +

    7.2. Using Filters to Eliminate Controller Duplication

    +

    At this point, if you look at the controller for posts, you’ll see some duplication:

    +
    +
    +
    class PostsController < ApplicationController
    +  # ...
    +  def show
    +    @post = Post.find(params[:id])
    +        # ...
    +  end
    +
    +  def edit
    +    @post = Post.find(params[:id])
    +  end
    +
    +  def update
    +    @post = Post.find(params[:id])
    +    # ...
    +  end
    +
    +  def destroy
    +    @post = Post.find(params[:id])
    +    # ...
    +  end
    +end
    +
    +

    Four instances of the exact same line of code doesn’t seem very DRY. Rails provides filters as a way to address this sort of repeated code. In this case, you can DRY things up by using a before_filter:

    +
    +
    +
    class PostsController < ApplicationController
    +  before_filter :find_post, :only => [:show, :edit, :update, :destroy]
    +  # ...
    +  def show
    +        # ...
    +  end
    +
    +  def edit
    +  end
    +
    +  def update
    +    # ...
    +  end
    +
    +  def destroy
    +    # ...
    +  end
    +
    +  private
    +    def find_post
    +      @post = Post.find(params[:id])
    +    end
    +end
    +
    +

    Rails runs before filters before any action in the controller. You can use the :only clause to limit a before filter to only certain actions, or an :except clause to specifically skip a before filter for certain actions. Rails also allows you to define after filters that run after processing an action, as well as around filters that surround the processing of actions. Filters can also be defined in external classes to make it easy to share them between controllers.

    +

    For more information on filters, see the Action Controller Basics guide.

    +
    +

    8. Adding a Second Model

    Now that you've seen what's in a model built with scaffolding, it's time to add a second model to the application. The second model will handle comments on blog posts.

    -

    8.1. Generating a Model

    +

    8.1. Generating a Model

    Models in Rails use a singular name, and their corresponding database tables use a plural name. For the model to hold comments, the convention is to use the name Comment. Even if you don't want to use the entire apparatus set up by scaffolding, most Rails developers still use generators to make things like models and controllers. To create the new model, run this command in your terminal:

    $ rake db:migrate
     

    Rails is smart enough to only execute the migrations that have not already been run against this particular database.

    -

    8.2. Associating Models

    -

    Active Record associations let you easily declare the relationship between two models. In the case of comments and posts, you could write out the relationships this way:

    +

    8.2. Associating Models

    +

    Active Record associations let you easily declare the relationship between two models. In the case of comments and posts, you could write out the relationships this way:

    • @@ -1680,10 +1680,10 @@ http://www.gnu.org/software/src-highlite --> Tip -For more information on Active Record associations, see the Active Record Associations guide. +For more information on Active Record associations, see the Active Record Associations guide.

    -

    8.3. Adding a Route

    +

    8.3. Adding a Route

    Routes are entries in the config/routes.rb file that tell Rails how to match incoming HTTP requests to controller actions. Open up that file and find the existing line referring to posts. Then edit it as follows:

    For more information on routing, see the Rails Routing from the Outside In guide.
    -

    8.4. Generating a Controller

    +

    8.4. Generating a Controller

    With the model in hand, you can turn your attention to creating a matching controller. Again, there's a generator for this:

    @comment = @post.comments.build
     

    This creates a new Comment object and sets up the post_id field to have the id from the specified Post object in a single operation.

    -

    8.5. Building Views

    +

    8.5. Building Views

    Because you skipped scaffolding, you'll need to build views for comments "by hand." Invoking script/generate controller will give you skeleton views, but they'll be devoid of actual content. Here's a first pass at fleshing out the comment views.

    The index.html.erb view:

    @@ -1937,7 +1937,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', post_comments_path(@post) %>

    Again, the added complexity here (compared to the views you saw for managing comments) comes from the necessity of juggling a post and its comments at the same time.

    -

    8.6. Hooking Comments to Posts

    +

    8.6. Hooking Comments to Posts

    As a final step, I'll modify the show.html.erb view for a post to show the comments on that post, and to allow managing those comments:

    Note that each post has its own individual comments collection, accessible as @post.comments. That's a consequence of the declarative associations in the models. Path helpers such as post_comments_path come from the nested route declaration in config/routes.rb.

    -

    9. What's Next?

    +

    9. What's Next?

    Now that you've seen your first Rails application, you should feel free to update it and experiment on your own. But you don't have to do everything without help. As you need assistance getting up and running with Rails, feel free to consult these support resources:

    -

    10. Changelog

    +

    10. Changelog

      diff --git a/railties/doc/guides/html/layouts_and_rendering.html b/railties/doc/guides/html/layouts_and_rendering.html index 63d060049a..aeda0c5c5e 100644 --- a/railties/doc/guides/html/layouts_and_rendering.html +++ b/railties/doc/guides/html/layouts_and_rendering.html @@ -523,7 +523,7 @@ http://www.gnu.org/software/src-highlite -->
      render :file => filename, :content_type => 'application/rss'
       
    The :layout Option
    -

    With most of the options to render, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide.

    +

    With most of the options to render, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide.

    You can use the :layout option to tell Rails to use a specific file as the layout for the current action:

    render :xml => photo, :location => photo_url(photo)
     
    -

    2.2.11. Finding Layouts

    -

    To find the current layout, Rails first looks for a file in app/views/layouts with the same base name as the controller. For example, rendering actions from the PhotosController class will use /app/views/layouts/photos.html.erb. If there is no such controller-specific layout, Rails will use /app/views/layouts/application.html.erb. If there is no .erb layout, Rails will use a .builder layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions.

    -
    Specifying Layouts on a per-Controller Basis
    -

    You can override the automatic layout conventions in your controllers by using the layout declaration in the controller. For example:

    -
    -
    -
    class ProductsController < ApplicationController
    -  layout "inventory"
    -  #...
    -end
    -
    -

    With this declaration, all methods within ProductsController will use app/views/layouts/inventory.html.erb for their layout.

    -

    To assign a specific layout for the entire application, use a declaration in your ApplicationController class:

    -
    -
    -
    class ApplicationController < ActionController::Base
    -  layout "main"
    -  #...
    -end
    -
    -

    With this declaration, all views in the entire application will use app/views/layouts/main.html.erb for their layout.

    -
    Choosing Layouts at Runtime
    -

    You can use a symbol to defer the choice of layout until a request is processed:

    -
    -
    -
    class ProductsController < ApplicationController
    -  layout :products_layout
    -
    -  def show
    -    @product = Product.find(params[:id])
    -  end
    -
    -  private
    -    def products_layout
    -      @current_user.special? ? "special" : "products"
    -    end
    -
    -end
    -
    -

    Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout:

    -
    -
    -
    class ProductsController < ApplicationController
    -  layout proc{ |controller| controller.
    -  # ...
    -end
    -
    -
    Conditional Layouts
    -

    Layouts specified at the controller level support :only and :except options that take either a method name or an array of method names:

    -
    -
    -
    class ProductsController < ApplicationController
    -  layout "inventory", :only => :index
    -  layout "product", :except => [:index, :rss]
    -  #...
    -end
    -
    -

    With those declarations, the inventory layout would be used only for the index method, the product layout would be used for everything else except the rss method, and the rss method will have its layout determined by the automatic layout rules.

    -
    Layout Inheritance
    -

    Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example:

    -
    -
    -
    class ApplicationController < ActionController::Base
    -  layout "main"
    -  #...
    -end
    -
    -class PostsController < ApplicationController
    -  # ...
    -end
    -
    -class SpecialPostsController < PostsController
    -  layout "special"
    -  # ...
    -end
    -
    -class OldPostsController < SpecialPostsController
    -  layout nil
    -
    -  def show
    -    @post = Post.find(params[:id])
    -  end
    -
    -  def index
    -    @old_posts = Post.older
    -    render :layout => "old"
    -  end
    -  # ...
    -end
    -
    -

    In this application:

    -
      -
    • -

      -In general, views will be rendered in the main layout -

      -
    • -
    • -

      -PostsController#index will use the main layout -

      -
    • -
    • -

      -SpecialPostsController#index will use the special layout -

      -
    • -
    • -

      -OldPostsController#show will use no layout at all -

      -
    • -
    • -

      -OldPostsController#index will use the old layout -

      -
    • -
    -

    2.2.12. Avoiding Double Render Errors

    +

    2.2.11. Finding Layouts

    +

    To find the current layout, Rails first looks for a file in app/views/layouts with the same base name as the controller. For example, rendering actions from the PhotosController class will use /app/views/layouts/photos.html.erb. If there is no such controller-specific layout, Rails will use /app/views/layouts/application.html.erb. If there is no .erb layout, Rails will use a .builder layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions.

    +
    Specifying Layouts on a per-Controller Basis
    +

    You can override the automatic layout conventions in your controllers by using the layout declaration in the controller. For example:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout "inventory"
    +  #...
    +end
    +
    +

    With this declaration, all methods within ProductsController will use app/views/layouts/inventory.html.erb for their layout.

    +

    To assign a specific layout for the entire application, use a declaration in your ApplicationController class:

    +
    +
    +
    class ApplicationController < ActionController::Base
    +  layout "main"
    +  #...
    +end
    +
    +

    With this declaration, all views in the entire application will use app/views/layouts/main.html.erb for their layout.

    +
    Choosing Layouts at Runtime
    +

    You can use a symbol to defer the choice of layout until a request is processed:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout :products_layout
    +
    +  def show
    +    @product = Product.find(params[:id])
    +  end
    +
    +  private
    +    def products_layout
    +      @current_user.special? ? "special" : "products"
    +    end
    +
    +end
    +
    +

    Now, if the current user is a special user, they'll get a special layout when viewing a product. You can even use an inline method to determine the layout:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout proc{ |controller| controller.
    +  # ...
    +end
    +
    +
    Conditional Layouts
    +

    Layouts specified at the controller level support :only and :except options that take either a method name or an array of method names:

    +
    +
    +
    class ProductsController < ApplicationController
    +  layout "inventory", :only => :index
    +  layout "product", :except => [:index, :rss]
    +  #...
    +end
    +
    +

    With those declarations, the inventory layout would be used only for the index method, the product layout would be used for everything else except the rss method, and the rss method will have its layout determined by the automatic layout rules.

    +
    Layout Inheritance
    +

    Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example:

    +
    +
    +
    class ApplicationController < ActionController::Base
    +  layout "main"
    +  #...
    +end
    +
    +class PostsController < ApplicationController
    +  # ...
    +end
    +
    +class SpecialPostsController < PostsController
    +  layout "special"
    +  # ...
    +end
    +
    +class OldPostsController < SpecialPostsController
    +  layout nil
    +
    +  def show
    +    @post = Post.find(params[:id])
    +  end
    +
    +  def index
    +    @old_posts = Post.older
    +    render :layout => "old"
    +  end
    +  # ...
    +end
    +
    +

    In this application:

    +
      +
    • +

      +In general, views will be rendered in the main layout +

      +
    • +
    • +

      +PostsController#index will use the main layout +

      +
    • +
    • +

      +SpecialPostsController#index will use the special layout +

      +
    • +
    • +

      +OldPostsController#show will use no layout at all +

      +
    • +
    • +

      +OldPostsController#index will use the old layout +

      +
    • +
    +

    2.2.12. Avoiding Double Render Errors

    Sooner or later, most Rails developers will see the error message "Can only render or redirect once per action". While this is annoying, it's relatively easy to fix. Usually it happens because of a fundamental misunderstanding of the way that render works.

    For example, here's some code that will trigger this error:

    @@ -799,7 +799,7 @@ http://www.gnu.org/software/src-highlite -->

    3. Structuring Layouts

    -

    When Rails renders a view as a response, it does so by combining the view with the current layout (using the rules for finding the current layout that were covered earlier in this guide). Within a layout, you have access to three tools for combining different bits of output to form the overall response:

    +

    When Rails renders a view as a response, it does so by combining the view with the current layout (using the rules for finding the current layout that were covered earlier in this guide). Within a layout, you have access to three tools for combining different bits of output to form the overall response:

    • diff --git a/railties/doc/guides/html/security.html b/railties/doc/guides/html/security.html index 4ece0814d5..a135d9b486 100644 --- a/railties/doc/guides/html/security.html +++ b/railties/doc/guides/html/security.html @@ -303,6 +303,8 @@ ul#navMain {

    • Command Line Injection
    • +
    • Header Injection
    • +
  • @@ -316,7 +318,7 @@ ul#navMain {

    This manual describes common security problems in web applications and how to avoid them with Rails. If you have any questions or suggestions, please -mail me at 42 {et} rorsecurity.info. After reading it, you should be familiar with:

    +mail me, Heiko Webers, at 42 {et} rorsecurity.info. After reading it, you should be familiar with:

    • @@ -1206,7 +1208,10 @@ s = sanitize(user_input, :tags => tags, :attributes => %w(href title))

      This example, again, showed that a blacklist filter is never complete. However, as custom CSS in web applications is a quite rare feature, I am not aware of a whitelist CSS filter. If you want to allow custom colours or images, you can allow the user to choose them and build the CSS in the web application. Use Rails' sanitize() method as a model for a whitelist CSS filter, if you really need one.

    8.5. Textile Injection

    If you want to provide text formatting other than HTML (due to security), use a mark-up language which is converted to HTML on the server-side. RedCloth is such a language for Ruby, but without precautions, it is also vulnerable to XSS.

    -

    For example, RedCloth translates test to <em>test<em>, which makes the text italic. However, up to the current version 3.0.4, it is still vulnerable to XSS:

    +
    +
    +
    For example, RedCloth translates _test_ to <em>test<em>, which makes the text italic. However, up to the current version 3.0.4, it is still vulnerable to XSS. Get the http://www.redcloth.org[all-new version 4] that removed serious bugs. However, even that version has http://www.rorsecurity.info/journal/2008/10/13/new-redcloth-security.html[some security bugs], so the countermeasures still apply. Here is an example for version 3.0.4:
    +
    >> RedCloth.new('<script>alert(1)</script>').to_html
    @@ -1241,6 +1246,53 @@ s = sanitize(user_input, :tags => tags, :attributes => %w(href title))system("/bin/echo","hello; rm *")
     # prints "hello; rm *" and does not delete files
    +

    8.9. Header Injection

    +

    HTTP headers are dynamically generated and under certain circumstances user input may be injected. This can lead to false redirection, XSS or HTTP response splitting.

    +

    HTTP request headers have a Referer, User-Agent (client software) and Cookie field, among others. Response headers for example have a status code, Cookie and Location (redirection target URL) field. All of them are user-supplied and may be manipulated with more or less effort. Remember to escape these header fields, too. For example when you display the user agent in an administration area.

    +

    Besides that, it is important to know what you are doing when building response headers partly based on user input. For example you want to redirect the user back to a specific page. To do that you introduced a “referer“ field in a form to redirect to the given address:

    +
    +
    +
    redirect_to params[:referer]
    +
    +

    What happens is that Rails puts the string into the Location header field and sends a 302 (redirect) status to the browser. The first thing a malicious user would do, is this:

    +
    +
    +
    http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld
    +
    +

    And due to a bug in (Ruby and) Rails up to version 2.1.2 (excluding it), a hacker may inject arbitrary header fields; for example like this:

    +
    +
    +
    http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld%0d%0aX-Header:+Hi!
    +http://www.yourapplication.com/controller/action?referer=path/at/your/app%0d%0aLocation:+http://www.malicious.tld
    +
    +

    Note that "%0d%0a" is URL-encoded for "\r\n" which is a carriage-return and line-feed (CRLF) in Ruby. So the resulting HTTP header for the second example will be the following because the second Location header field overwrites the first.

    +
    +
    +
    HTTP/1.1 302 Moved Temporarily
    +(...)
    +Location: http://www.malicious.tld
    +
    +

    So attack vectors for Header Injection are based on the injection of CRLF characters in a header field. And what could an attacker do with a false redirection? He could redirect to a phishing site that looks the same as yours, but asks to login again (and sends the login credentials to the attacker). Or he could install malicious software through browser security holes on that site. Rails 2.1.2 escapes these characters for the Location field in the redirect_to method. Make sure you do it yourself when you build other header fields with user input.

    +

    8.9.1. Response Splitting

    +

    If Header Injection was possible, Response Splitting might be, too. In HTTP, the header block is followed by two CRLFs and the actual data (usually HTML). The idea of Response Splitting is to inject two CRLFs into a header field, followed by another response with malicious HTML. The response will be:

    +
    +
    +
    HTTP/1.1 302 Found [First standard 302 response]
    +Date: Tue, 12 Apr 2005 22:09:07 GMT
    +Location:
Content-Type: text/html
    +
    +
    +HTTP/1.1 200 OK [Second New response created by attacker begins]
    +Content-Type: text/html
    +
    +
    +<html><font color=red>hey</font></html> [Arbitary malicious input is
    +Keep-Alive: timeout=15, max=100         shown as the redirected page]
    +Connection: Keep-Alive
    +Transfer-Encoding: chunked
    +Content-Type: text/html
    +
    +

    Under certain circumstances this would present the malicious HTML to the victim. However, this seems to work with Keep-Alive connections, only (and many browsers are using one-time connections). But you can't rely on this. In any case this is a serious bug, and you should update your Rails to version 2.0.5 or 2.1.2 to eliminate Header Injection (and thus response splitting) risks.

    9. Additional resources

    -- cgit v1.2.3 From c0eb4d07ab4ca1bbae76829e95e66053a564c525 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Fri, 24 Oct 2008 16:28:35 -0500 Subject: 2.2 Relnotes: more info on association proxies --- railties/doc/guides/source/2_2_release_notes.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'railties') diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index d5eeefb16f..4543b5309c 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -196,6 +196,8 @@ User.find_by_name!('Moby') Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) +@user.account.private_method+ would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use +@user.account.send(:private_method)+ (or make the method public instead of private or protected). Please note that if you're overriding +method_missing+, you should also override +respond_to+ to match the behavior in order for associations to function normally. * Lead Contributor: Adam Milligan +* More information: + - link:http://afreshcup.com/2008/10/24/rails-22-change-private-methods-on-association-proxies-are-private/[Rails 2.2 Change: Private Methods on Association Proxies are Private] === Other ActiveRecord Changes -- cgit v1.2.3 From b62c164997924041d26cab802e238652307d3f9a Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 25 Oct 2008 03:10:00 +0530 Subject: And html too --- railties/doc/guides/html/2_2_release_notes.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index f458c0fa57..d21905f715 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -654,6 +654,18 @@ Lead Contributor: Josh Susser Lead Contributor: Adam Milligan

  • +
  • +

    +More information: +

    + +
  • 5.6. Other ActiveRecord Changes

      -- cgit v1.2.3 From 0ea10019f790ee42c6426f62622700107c2d53c6 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 25 Oct 2008 04:18:49 +0530 Subject: Enum#many? --- railties/doc/guides/html/2_2_release_notes.html | 2 +- railties/doc/guides/source/2_2_release_notes.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index d21905f715..7e975d35a6 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -935,7 +935,7 @@ The addition of ActiveSupport::Rescuable allows any class to mix in the
    • -Enumerable#several? to encapsulate collection.size > 1 +Enumerable#many? to encapsulate collection.size > 1

    • diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index 4543b5309c..8d627c9e63 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -349,7 +349,7 @@ Lead Contributor: link:http://workingwithrails.com/person/5830-daniel-schierbeck * The addition of +ActiveSupport::Rescuable+ allows any class to mix in the +rescue_from+ syntax. * +past?+, +today?+ and +future?+ for +Date+ and +Time+ classes to facilitate date/time comparisons. * +Array#second+ through +Array#tenth+ as aliases for +Array#[1]+ through +Array#[9]+ -* +Enumerable#several?+ to encapsulate +collection.size > 1+ +* +Enumerable#many?+ to encapsulate +collection.size > 1+ * +Inflector#parameterize+ produces a URL-ready version of its input, for use in +to_param+. * +Time#advance+ recognizes fractional days and weeks, so you can do +1.7.weeks.ago+, +1.5.hours.since+, and so on. * The included TzInfo library has been upgraded to version 0.3.11. -- cgit v1.2.3 From 164bdd674379dc2649124e1e4a343a6097e1e746 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Fri, 24 Oct 2008 17:52:28 -0500 Subject: Tiny cleanup in layouts & rendering guide --- railties/doc/guides/source/layouts_and_rendering.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/source/layouts_and_rendering.txt b/railties/doc/guides/source/layouts_and_rendering.txt index c4bb5b0591..3d970b60ce 100644 --- a/railties/doc/guides/source/layouts_and_rendering.txt +++ b/railties/doc/guides/source/layouts_and_rendering.txt @@ -768,7 +768,7 @@ You can also pass local variables into partials, making them even more powerful [source, html] ------------------------------------------------------- -new.rhtml.erb: +new.html.erb:

      New zone

      <%= error_messages_for :zone %> @@ -819,7 +819,7 @@ Partials are very useful in rendering collections. When you pass a collection to [source, html] ------------------------------------------------------- -index.rhtml.erb: +index.html.erb:

      Products

      <%= render :partial => "product", :collection => @products %> @@ -851,7 +851,7 @@ There's also a shorthand syntax available for rendering collections. For example [source, html] ------------------------------------------------------- -index.rhtml.erb: +index.html.erb:

      Products

      <%= render :partial => @products %> @@ -865,7 +865,7 @@ Rails determines the name of the partial to use by looking at the model name in [source, html] ------------------------------------------------------- -index.rhtml.erb: +index.html.erb:

      Contacts

      <%= render :partial => [customer1, employee1, customer2, employee2] %> -- cgit v1.2.3 From 14fb65ca16849cceaef4ac96b19cc485da612388 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 25 Oct 2008 04:27:34 +0530 Subject: Hey..generate html ;-) --- railties/doc/guides/html/layouts_and_rendering.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/layouts_and_rendering.html b/railties/doc/guides/html/layouts_and_rendering.html index aeda0c5c5e..a394da71df 100644 --- a/railties/doc/guides/html/layouts_and_rendering.html +++ b/railties/doc/guides/html/layouts_and_rendering.html @@ -1190,7 +1190,7 @@ http://www.gnu.org/software/src-highlite --> by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite --> -
      new.rhtml.erb:
      +
      new.html.erb:
       
       <h1>New zone</h1>
       <%= error_messages_for :zone %>
      @@ -1240,7 +1240,7 @@ http://www.gnu.org/software/src-highlite -->
       by Lorenzo Bettini
       http://www.lorenzobettini.it
       http://www.gnu.org/software/src-highlite -->
      -
      index.rhtml.erb:
      +
      index.html.erb:
       
       <h1>Products</h1>
       <%= render :partial => "product", :collection => @products %>
      @@ -1273,7 +1273,7 @@ http://www.gnu.org/software/src-highlite -->
       by Lorenzo Bettini
       http://www.lorenzobettini.it
       http://www.gnu.org/software/src-highlite -->
      -
      index.rhtml.erb:
      +
      index.html.erb:
       
       <h1>Products</h1>
       <%= render :partial => @products %>
      @@ -1288,7 +1288,7 @@ _product.html.erb:
       by Lorenzo Bettini
       http://www.lorenzobettini.it
       http://www.gnu.org/software/src-highlite -->
      -
      index.rhtml.erb:
      +
      index.html.erb:
       
       <h1>Contacts</h1>
       <%= render :partial => [customer1, employee1, customer2, employee2] %>
      -- 
      cgit v1.2.3
      
      
      From 8afe33b1475deb86714242769c2bc5db5e1ddc22 Mon Sep 17 00:00:00 2001
      From: Mike Gunderloy 
      Date: Fri, 24 Oct 2008 19:35:57 -0500
      Subject: Fix a few more typos in 2.2 release notes.
      
      ---
       railties/doc/guides/html/2_2_release_notes.html  | 598 +++++++++++------------
       railties/doc/guides/source/2_2_release_notes.txt |   8 +-
       2 files changed, 303 insertions(+), 303 deletions(-)
      
      (limited to 'railties')
      
      diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html
      index 7e975d35a6..f3fd549863 100644
      --- a/railties/doc/guides/html/2_2_release_notes.html
      +++ b/railties/doc/guides/html/2_2_release_notes.html
      @@ -1,293 +1,293 @@
      -
      -
      -
      -	
      -	Ruby on Rails 2.2 Release Notes
      -	
      -	
      -	
      -	
      -	
      -
      -
      -	
      -
      -	
      - - - -
      -

      Ruby on Rails 2.2 Release Notes

      + + + + + Ruby on Rails 2.2 Release Notes + + + + + + + + + +
      + + + +
      +

      Ruby on Rails 2.2 Release Notes

      Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the list of commits in the main Rails repository on GitHub.

      @@ -893,23 +893,23 @@ http://www.gnu.org/software/src-highlite --> by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite --> -
      class Vendor << ActiveRecord::Base
      +
      class Vendor < ActiveRecord::Base
         has_one :account
         delegate :email, :password, :to => :account, :prefix => true
       end
       
      -

      This will produce delegated methods vendor.account_email and vendor.account_password. You can also specify a custom prefix:

      +

      This will produce delegated methods vendor#account_email and vendor#account_password. You can also specify a custom prefix:

      -
      class Vendor << ActiveRecord::Base
      +
      class Vendor < ActiveRecord::Base
         has_one :account
         delegate :email, :password, :to => :account, :prefix => :owner
       end
       
      -

      This will produce delegated methods vendor.owner_email and vendor.owner_password.

      +

      This will produce delegated methods vendor#owner_email and vendor#owner_password.

      Lead Contributor: Daniel Schierbeck

      9.4. Other Active Support Changes

        @@ -1124,8 +1124,8 @@ Durations of fractional months or fractional years are deprecated. Use Ruby's co

        Release notes compiled by Mike Gunderloy

        - -
      -
      - - + +
      +
      + + diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt index 8d627c9e63..272fb5ec33 100644 --- a/railties/doc/guides/source/2_2_release_notes.txt +++ b/railties/doc/guides/source/2_2_release_notes.txt @@ -323,23 +323,23 @@ If you delegate behavior from one class to another, you can now specify a prefix [source, ruby] ------------------------------------------------------- -class Vendor << ActiveRecord::Base +class Vendor < ActiveRecord::Base has_one :account delegate :email, :password, :to => :account, :prefix => true end ------------------------------------------------------- -This will produce delegated methods +vendor.account_email+ and +vendor.account_password+. You can also specify a custom prefix: +This will produce delegated methods +vendor#account_email+ and +vendor#account_password+. You can also specify a custom prefix: [source, ruby] ------------------------------------------------------- -class Vendor << ActiveRecord::Base +class Vendor < ActiveRecord::Base has_one :account delegate :email, :password, :to => :account, :prefix => :owner end ------------------------------------------------------- -This will produce delegated methods +vendor.owner_email+ and +vendor.owner_password+. +This will produce delegated methods +vendor#owner_email+ and +vendor#owner_password+. Lead Contributor: link:http://workingwithrails.com/person/5830-daniel-schierbeck[Daniel Schierbeck] -- cgit v1.2.3 From b0caf6c54b38242a638653db1d50edc87d01225e Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Fri, 24 Oct 2008 20:17:15 -0500 Subject: Typo fixes in 2.2 release notes --- railties/doc/guides/html/2_2_release_notes.html | 36 ++++++++++++------------ railties/doc/guides/source/2_2_release_notes.txt | 36 ++++++++++++------------ 2 files changed, 36 insertions(+), 36 deletions(-) (limited to 'railties') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index f3fd549863..9d92223037 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -337,72 +337,72 @@ More information :
      @@ -612,7 +612,7 @@ More information:

    5.4. New Dynamic Finders

    Two new sets of methods have been added to Active Record's dynamic finders family.

    -

    5.4.1. find_last_by_<attributes>

    +

    5.4.1. find_last_by_<attribute>

    The find_last_by_<attribute> method is equivalent to Model.last(:conditions ⇒ {:attribute ⇒ value})

    - - - - - - - - -
    - - - -
    -

    Ruby on Rails 2.2 Release Notes

    + + + + + Ruby on Rails 2.2 Release Notes + + + + + + + + + +
    + + + +
    +

    Ruby on Rails 2.2 Release Notes

    Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the list of commits in the main Rails repository on GitHub.

    @@ -612,7 +612,7 @@ More information:

    5.4. New Dynamic Finders

    Two new sets of methods have been added to Active Record's dynamic finders family.

    -

    5.4.1. find_last_by_<attribute>

    +

    5.4.1. find_last_by_<attribute>

    The find_last_by_<attribute> method is equivalent to Model.last(:conditions ⇒ {:attribute ⇒ value})