aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/CHANGELOG3
-rw-r--r--actionmailer/Rakefile6
-rw-r--r--actionpack/CHANGELOG4
-rw-r--r--actionpack/Rakefile6
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/node.rb11
-rw-r--r--actionpack/test/controller/html-scanner/cdata_node_test.rb15
-rw-r--r--actionpack/test/controller/html-scanner/node_test.rb21
-rw-r--r--actionpack/test/controller/html-scanner/sanitizer_test.rb10
-rw-r--r--activerecord/CHANGELOG4
-rw-r--r--activerecord/Rakefile6
-rwxr-xr-xactiverecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb7
-rw-r--r--activeresource/CHANGELOG2
-rw-r--r--activeresource/Rakefile6
-rw-r--r--activeresource/lib/active_resource/version.rb2
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/Rakefile4
-rw-r--r--railties/CHANGELOG2
-rw-r--r--railties/Rakefile16
-rw-r--r--railties/doc/guides/html/2_2_release_notes.html108
-rw-r--r--railties/doc/guides/html/actioncontroller_basics.html2
-rw-r--r--railties/doc/guides/html/getting_started_with_rails.html166
-rw-r--r--railties/doc/guides/html/layouts_and_rendering.html148
-rw-r--r--railties/doc/guides/html/security.html56
-rw-r--r--railties/doc/guides/source/2_2_release_notes.txt79
-rw-r--r--railties/doc/guides/source/actioncontroller_basics/methods.txt2
-rw-r--r--railties/doc/guides/source/getting_started_with_rails.txt131
-rw-r--r--railties/doc/guides/source/layouts_and_rendering.txt132
-rw-r--r--railties/doc/guides/source/security.txt63
29 files changed, 890 insertions, 126 deletions
diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG
index fc02ae8ffc..d8636fd83d 100644
--- a/actionmailer/CHANGELOG
+++ b/actionmailer/CHANGELOG
@@ -1,8 +1,11 @@
+*2.2.0 [RC1] (October 24th, 2008)*
+
* Add layout functionality to mailers [Pratik]
Mailer layouts behaves just like controller layouts, except layout names need to
have '_mailer' postfix for them to be automatically picked up.
+
*2.1.0 (May 31st, 2008)*
* Fixed that a return-path header would be ignored #7572 [joost]
diff --git a/actionmailer/Rakefile b/actionmailer/Rakefile
index 612bd27774..9f4a387126 100644
--- a/actionmailer/Rakefile
+++ b/actionmailer/Rakefile
@@ -55,7 +55,7 @@ spec = Gem::Specification.new do |s|
s.rubyforge_project = "actionmailer"
s.homepage = "http://www.rubyonrails.org"
- s.add_dependency('actionpack', '= 2.1.0' + PKG_BUILD)
+ s.add_dependency('actionpack', '= 2.2.0' + PKG_BUILD)
s.has_rdoc = true
s.requirements << 'none'
@@ -76,8 +76,8 @@ end
desc "Publish the API documentation"
task :pgem => [:package] 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 '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index fdc9be2ff4..3c06c87bb2 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,4 +1,6 @@
-*Edge*
+*2.2.0 [RC1] (October 24th, 2008)*
+
+* Fix incorrect closing CDATA delimiter and that HTML::Node.parse would blow up on unclosed CDATA sections [packagethief]
* Added stale? and fresh_when methods to provide a layer of abstraction above request.fresh? and friends [DHH]. Example:
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index 0ee9382e89..73da8b1ce3 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -80,7 +80,7 @@ spec = Gem::Specification.new do |s|
s.has_rdoc = true
s.requirements << 'none'
- s.add_dependency('activesupport', '= 2.1.0' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.2.0' + PKG_BUILD)
s.require_path = 'lib'
s.autorequire = 'action_controller'
@@ -136,8 +136,8 @@ task :update_js => [ :update_scriptaculous ]
desc "Publish the API documentation"
task :pgem => [:package] 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 '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
index 472c5b2bae..6c0331636c 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
@@ -150,7 +150,14 @@ module HTML #:nodoc:
end
if scanner.skip(/!\[CDATA\[/)
- scanner.scan_until(/\]\]>/)
+ unless scanner.skip_until(/\]\]>/)
+ if strict
+ raise "expected ]]> (got #{scanner.rest.inspect} for #{content})"
+ else
+ scanner.skip_until(/\Z/)
+ end
+ end
+
return CDATA.new(parent, line, pos, scanner.pre_match.gsub(/<!\[CDATA\[/, ''))
end
@@ -265,7 +272,7 @@ module HTML #:nodoc:
# itself.
class CDATA < Text #:nodoc:
def to_s
- "<![CDATA[#{super}]>"
+ "<![CDATA[#{super}]]>"
end
end
diff --git a/actionpack/test/controller/html-scanner/cdata_node_test.rb b/actionpack/test/controller/html-scanner/cdata_node_test.rb
new file mode 100644
index 0000000000..1822cc565a
--- /dev/null
+++ b/actionpack/test/controller/html-scanner/cdata_node_test.rb
@@ -0,0 +1,15 @@
+require 'abstract_unit'
+
+class CDATANodeTest < Test::Unit::TestCase
+ def setup
+ @node = HTML::CDATA.new(nil, 0, 0, "<p>howdy</p>")
+ end
+
+ def test_to_s
+ assert_equal "<![CDATA[<p>howdy</p>]]>", @node.to_s
+ end
+
+ def test_content
+ assert_equal "<p>howdy</p>", @node.content
+ end
+end
diff --git a/actionpack/test/controller/html-scanner/node_test.rb b/actionpack/test/controller/html-scanner/node_test.rb
index 240f01ac8b..b0df36877e 100644
--- a/actionpack/test/controller/html-scanner/node_test.rb
+++ b/actionpack/test/controller/html-scanner/node_test.rb
@@ -65,4 +65,25 @@ class NodeTest < Test::Unit::TestCase
assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
assert node.attributes.has_key?("onmouseover")
end
+
+ def test_parse_with_valid_cdata_section
+ s = "<![CDATA[<span>contents</span>]]>"
+ node = nil
+ assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
+ assert_kind_of HTML::CDATA, node
+ assert_equal '<span>contents</span>', node.content
+ end
+
+ def test_parse_strict_with_unterminated_cdata_section
+ s = "<![CDATA[neverending..."
+ assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) }
+ end
+
+ def test_parse_relaxed_with_unterminated_cdata_section
+ s = "<![CDATA[neverending..."
+ node = nil
+ assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
+ assert_kind_of HTML::CDATA, node
+ assert_equal 'neverending...', node.content
+ end
end
diff --git a/actionpack/test/controller/html-scanner/sanitizer_test.rb b/actionpack/test/controller/html-scanner/sanitizer_test.rb
index db142f0bc6..a9e8447e32 100644
--- a/actionpack/test/controller/html-scanner/sanitizer_test.rb
+++ b/actionpack/test/controller/html-scanner/sanitizer_test.rb
@@ -17,6 +17,8 @@ class SanitizerTest < Test::Unit::TestCase
%{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize(
%{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.")
+ assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.")
+ assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...")
[nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
end
@@ -243,6 +245,14 @@ class SanitizerTest < Test::Unit::TestCase
assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />'
end
+ def test_should_sanitize_cdata_section
+ assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>"
+ end
+
+ def test_should_sanitize_unterminated_cdata_section
+ assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>"
+ end
+
protected
def assert_sanitized(input, expected = nil)
@sanitizer ||= HTML::WhiteListSanitizer.new
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 6479cc5a9b..fec110d569 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,4 +1,6 @@
-*Edge*
+*2.2.0 [RC1] (October 24th, 2008)*
+
+* Skip collection ids reader optimization if using :finder_sql [Jeremy Kemper]
* Add Model#delete instance method, similar to Model.delete class method. #1086 [Hongli Lai]
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index 983528aff7..f192646547 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -171,7 +171,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.1.0' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.2.0' + PKG_BUILD)
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
@@ -225,8 +225,8 @@ end
desc "Publish the beta gem"
task :pgem => [:package] 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 '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 187caa13d0..52f6a04da1 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1296,7 +1296,7 @@ module ActiveRecord
end
define_method("#{reflection.name.to_s.singularize}_ids") do
- if send(reflection.name).loaded?
+ if send(reflection.name).loaded? || reflection.options[:finder_sql]
send(reflection.name).map(&:id)
else
send(reflection.name).all(:select => "#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").map(&:id)
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 8d97b30c74..59784e1bcb 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -853,6 +853,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients.loaded?
end
+ def test_get_ids_for_unloaded_finder_sql_associations_loads_them
+ company = companies(:first_firm)
+ assert !company.clients_using_sql.loaded?
+ assert_equal [companies(:second_client).id], company.clients_using_sql_ids
+ assert company.clients_using_sql.loaded?
+ end
+
def test_assign_ids
firm = Firm.new("name" => "Apple")
firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG
index e93b3ec15b..74ca71f65a 100644
--- a/activeresource/CHANGELOG
+++ b/activeresource/CHANGELOG
@@ -1,4 +1,4 @@
-*Edge*
+*2.2.0 [RC1] (October 24th, 2008)*
* Add ActiveResource::Base#to_xml and ActiveResource::Base#to_json. #1011 [Rasik Pandey, Cody Fauser]
diff --git a/activeresource/Rakefile b/activeresource/Rakefile
index 8c3ad36a02..ef6efd4903 100644
--- a/activeresource/Rakefile
+++ b/activeresource/Rakefile
@@ -65,7 +65,7 @@ spec = Gem::Specification.new do |s|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
end
- s.add_dependency('activesupport', '= 2.1.0' + PKG_BUILD)
+ s.add_dependency('activesupport', '= 2.2.0' + PKG_BUILD)
s.require_path = 'lib'
s.autorequire = 'active_resource'
@@ -115,8 +115,8 @@ end
desc "Publish the beta gem"
task :pgem => [:package] 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 '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
diff --git a/activeresource/lib/active_resource/version.rb b/activeresource/lib/active_resource/version.rb
index 88798ea1c1..d56f4cf17e 100644
--- a/activeresource/lib/active_resource/version.rb
+++ b/activeresource/lib/active_resource/version.rb
@@ -1,7 +1,7 @@
module ActiveResource
module VERSION #:nodoc:
MAJOR = 2
- MINOR = 1
+ MINOR = 2
TINY = 0
STRING = [MAJOR, MINOR, TINY].join('.')
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 803f95d90e..819a67adfa 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,4 +1,4 @@
-*Edge*
+*2.2.0 [RC1] (October 24th, 2008)*
* TimeWithZone#freeze: preload instance variables so that we can actually freeze [Geoff Buesing]
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index f2885c69a4..1961fb43cf 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -65,8 +65,8 @@ end
desc "Publish the beta gem"
task :pgem => [:package] 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 '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index 51d66e4c01..390da3b890 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,4 +1,4 @@
-*Edge*
+*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]
diff --git a/railties/Rakefile b/railties/Rakefile
index 5100b4bd9b..adb6db0b64 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
@@ -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 '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the API documentation"
diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html
index e30145c90f..0ac5376cc8 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 {
<li><a href="#_new_dynamic_finders">New Dynamic Finders</a></li>
+ <li><a href="#_associations_respect_private_protected_scope">Associations Respect Private/Protected Scope</a></li>
+
<li><a href="#_other_activerecord_changes">Other ActiveRecord Changes</a></li>
</ul>
@@ -335,72 +337,72 @@ More information :
<div class="ilist"><ul>
<li>
<p>
-Getting Started with Rails
+<a href="http://guides.rubyonrails.org/getting_started_with_rails.html">Getting Started with Rails</a>
</p>
</li>
<li>
<p>
-Rails Database Migrations
+<a href="http://guides.rubyonrails.org/migrations.html">Rails Database Migrations</a>
</p>
</li>
<li>
<p>
-Active Record Associations
+<a href="http://guides.rubyonrails.org/association_basics.html">Active Record Associations</a>
</p>
</li>
<li>
<p>
-Active Record Finders
+<a href="http://guides.rubyonrails.org/finders.html">Active Record Finders</a>
</p>
</li>
<li>
<p>
-Layouts and Rendering in Rails
+<a href="http://guides.rubyonrails.org/layouts_and_rendering.html">Layouts and Rendering in Rails</a>
</p>
</li>
<li>
<p>
-Action View Form Helpers
+<a href="http://guides.rubyonrails.org/form_helpers.html">Action View Form Helpers</a>
</p>
</li>
<li>
<p>
-Rails Routing from the Outside In
+<a href="http://guides.rubyonrails.org/routing_outside_in.html">Rails Routing from the Outside In</a>
</p>
</li>
<li>
<p>
-Basics of Action Controller
+<a href="http://guides.rubyonrails.org/actioncontroller_basics.html">Basics of Action Controller</a>
</p>
</li>
<li>
<p>
-Rails Caching
+<a href="http://guides.rubyonrails.org/caching_with_rails.html">Rails Caching</a>
</p>
</li>
<li>
<p>
-Testing Rails Applications
+<a href="http://guides.rubyonrails.org/testing_rails_applications.html">Testing Rails Applications</a>
</p>
</li>
<li>
<p>
-Securing Rails Applications
+<a href="http://guides.rubyonrails.org/security.html">Securing Rails Applications</a>
</p>
</li>
<li>
<p>
-Debugging Rails Applications
+<a href="http://guides.rubyonrails.org/debugging_rails_applications.html">Debugging Rails Applications</a>
</p>
</li>
<li>
<p>
-Benchmarking and Profiling Rails Applications
+<a href="http://guides.rubyonrails.org/benchmarking_and_profiling.html">Benchmarking and Profiling Rails Applications</a>
</p>
</li>
<li>
<p>
-The Basics of Creating Rails Plugins
+<a href="http://guides.rubyonrails.org/creating_plugins.html">The Basics of Creating Rails Plugins</a>
</p>
</li>
</ul></div>
@@ -422,7 +424,7 @@ Lead Contributors: <a href="http://guides.rails.info/authors.html">Rails Documen
</li>
<li>
<p>
-Major contributions from <a href="http://advogato.org/person/fxn/diary.html">Xavier Nora</a> and <a href="http://izumi.plan99.net/blog/">Hongli Lai</a>.
+Major contributions from <a href="http://advogato.org/person/fxn/diary.html">Xavier Noria</a> and <a href="http://izumi.plan99.net/blog/">Hongli Lai</a>.
</p>
</li>
<li>
@@ -502,6 +504,11 @@ More information :
<div class="ilist"><ul>
<li>
<p>
+<a href="http://m.onkey.org/2008/10/23/thread-safety-for-your-rails">Thread safety for your Rails</a>
+</p>
+</li>
+<li>
+<p>
<a href="http://weblog.rubyonrails.org/2008/8/16/josh-peek-officially-joins-the-rails-core">Thread safety project announcement</a>
</p>
</li>
@@ -579,16 +586,15 @@ by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Photo <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
- belongs_to <span style="color: #990000">:</span>Product
+ belongs_to <span style="color: #990000">:</span>product
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Product <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
- has_many <span style="color: #990000">:</span>products
+ has_many <span style="color: #990000">:</span>photos
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
<span style="font-style: italic"><span style="color: #9A1900"># Get all products with copyright-free photos:</span></span>
-Product<span style="color: #990000">.</span>find<span style="color: #990000">(:</span>all<span style="color: #990000">,</span> <span style="color: #990000">:</span>joins <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>photo<span style="color: #990000">,</span>
- <span style="color: #990000">:</span>conditions <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">{</span> <span style="color: #990000">:</span>photos <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">{</span> <span style="color: #990000">:</span>copyright <span style="color: #990000">=&gt;</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span> <span style="color: #FF0000">}}</span><span style="color: #990000">)</span>
+Product<span style="color: #990000">.</span>all<span style="color: #990000">(:</span>joins <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>photos<span style="color: #990000">,</span> <span style="color: #990000">:</span>conditions <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">{</span> <span style="color: #990000">:</span>photos <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">{</span> <span style="color: #990000">:</span>copyright <span style="color: #990000">=&gt;</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span> <span style="color: #FF0000">}}</span><span style="color: #990000">)</span>
</tt></pre></div></div>
<div class="ilist"><ul>
<li>
@@ -606,7 +612,7 @@ More information:
</ul></div>
<h3 id="_new_dynamic_finders">5.4. New Dynamic Finders</h3>
<div class="para"><p>Two new sets of methods have been added to Active Record's dynamic finders family.</p></div>
-<h4 id="_find_last_by_lt_attributes_gt">5.4.1. find_last_by_&lt;attributes&gt;</h4>
+<h4 id="_tt_find_last_by_lt_attribute_gt_tt">5.4.1. <tt>find_last_by_&lt;attribute&gt;</tt></h4>
<div class="para"><p>The <tt>find_last_by_&lt;attribute&gt;</tt> method is equivalent to <tt>Model.last(:conditions &#8658; {:attribute &#8658; value})</tt></p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
@@ -623,8 +629,8 @@ Lead Contributor: <a href="http://www.workingwithrails.com/person/9147-emilio-ta
</p>
</li>
</ul></div>
-<h4 id="_find_by_lt_attributes_gt">5.4.2. find_by_&lt;attributes&gt;!</h4>
-<div class="para"><p>The new bang! version of <tt>find_by_&lt;attribute&gt;! is equivalent to +Model.first(:conditions &#8658; {:attribute &#8658; value}) || raise ActiveRecord::RecordNotFound</tt> Instead of returning <tt>nil</tt> if it can't find a matching record, this method will raise an exception if it cannot find a match.</p></div>
+<h4 id="_tt_find_by_lt_attribute_gt_tt">5.4.2. <tt>find_by_&lt;attribute&gt;!</tt></h4>
+<div class="para"><p>The new bang! version of <tt>find_by_&lt;attribute&gt;!</tt> is equivalent to <tt>Model.first(:conditions &#8658; {:attribute &#8658; value}) || raise ActiveRecord::RecordNotFound</tt> Instead of returning <tt>nil</tt> if it can't find a matching record, this method will raise an exception if it cannot find a match.</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
by Lorenzo Bettini
@@ -640,7 +646,28 @@ Lead Contributor: <a href="http://blog.hasmanythrough.com">Josh Susser</a>
</p>
</li>
</ul></div>
-<h3 id="_other_activerecord_changes">5.5. Other ActiveRecord Changes</h3>
+<h3 id="_associations_respect_private_protected_scope">5.5. Associations Respect Private/Protected Scope</h3>
+<div class="para"><p>Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) <tt>@user.account.private_method</tt> would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use <tt>@user.account.send(:private_method)</tt> (or make the method public instead of private or protected). Please note that if you're overriding <tt>method_missing</tt>, you should also override <tt>respond_to</tt> to match the behavior in order for associations to function normally.</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
+Lead Contributor: Adam Milligan
+</p>
+</li>
+<li>
+<p>
+More information:
+</p>
+<div class="ilist"><ul>
+<li>
+<p>
+<a href="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</a>
+</p>
+</li>
+</ul></div>
+</li>
+</ul></div>
+<h3 id="_other_activerecord_changes">5.6. Other ActiveRecord Changes</h3>
<div class="ilist"><ul>
<li>
<p>
@@ -866,23 +893,23 @@ http://www.gnu.org/software/src-highlite -->
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Vendor <span style="color: #990000">&lt;&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Vendor <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
has_one <span style="color: #990000">:</span>account
delegate <span style="color: #990000">:</span>email<span style="color: #990000">,</span> <span style="color: #990000">:</span>password<span style="color: #990000">,</span> <span style="color: #990000">:</span>to <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>account<span style="color: #990000">,</span> <span style="color: #990000">:</span>prefix <span style="color: #990000">=&gt;</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
</tt></pre></div></div>
-<div class="para"><p>This will produce delegated methods <tt>vendor.account_email</tt> and <tt>vendor.account_password</tt>. You can also specify a custom prefix:</p></div>
+<div class="para"><p>This will produce delegated methods <tt>vendor#account_email</tt> and <tt>vendor#account_password</tt>. You can also specify a custom prefix:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Vendor <span style="color: #990000">&lt;&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Vendor <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
has_one <span style="color: #990000">:</span>account
delegate <span style="color: #990000">:</span>email<span style="color: #990000">,</span> <span style="color: #990000">:</span>password<span style="color: #990000">,</span> <span style="color: #990000">:</span>to <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>account<span style="color: #990000">,</span> <span style="color: #990000">:</span>prefix <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>owner
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
</tt></pre></div></div>
-<div class="para"><p>This will produce delegated methods <tt>vendor.owner_email</tt> and <tt>vendor.owner_password</tt>.</p></div>
+<div class="para"><p>This will produce delegated methods <tt>vendor#owner_email</tt> and <tt>vendor#owner_password</tt>.</p></div>
<div class="para"><p>Lead Contributor: <a href="http://workingwithrails.com/person/5830-daniel-schierbeck">Daniel Schierbeck</a></p></div>
<h3 id="_other_active_support_changes">9.4. Other Active Support Changes</h3>
<div class="ilist"><ul>
@@ -908,7 +935,7 @@ The addition of <tt>ActiveSupport::Rescuable</tt> allows any class to mix in the
</li>
<li>
<p>
-<tt>Enumerable#several?</tt> to encapsulate <tt>collection.size &gt; 1</tt>
+<tt>Enumerable#many?</tt> to encapsulate <tt>collection.size &gt; 1</tt>
</p>
</li>
<li>
@@ -970,7 +997,7 @@ The included TzInfo library has been upgraded to version 0.3.11.
</p>
</li>
</ul></div>
-<div class="para"><p>You can unpack or install a single gem by specifying <tt>GEM=_gem_name</tt> on the command line.</p></div>
+<div class="para"><p>You can unpack or install a single gem by specifying <tt>GEM=<em>gem_name</em></tt> on the command line.</p></div>
<div class="ilist"><ul>
<li>
<p>
@@ -987,6 +1014,11 @@ More information:
<a href="http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies">What's New in Edge Rails: Gem Dependencies</a>
</p>
</li>
+<li>
+<p>
+<a href="http://afreshcup.com/2008/10/25/rails-212-and-22rc1-update-your-rubygems/">Rails 2.1.2 and 2.2RC1: Update Your RubyGems</a>
+</p>
+</li>
</ul></div>
</li>
</ul></div>
@@ -1045,6 +1077,24 @@ Wrapped <tt>Rails.env</tt> in <tt>StringQuestioneer</tt> so you can do <tt>Rails
</li>
<li>
<p>
+Implicit local assignments when rendering partials has been deprecated.
+</p>
+</li>
+</ul></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">def</span></span> partial_with_implicit_local_assignment
+ <span style="color: #009900">@customer</span> <span style="color: #990000">=</span> Customer<span style="color: #990000">.</span>new<span style="color: #990000">(</span><span style="color: #FF0000">"Marcel"</span><span style="color: #990000">)</span>
+ render <span style="color: #990000">:</span>partial <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">"customer"</span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>Previously the above code made available a local variable called <tt>customer</tt> inside the partial <em>customer</em>. You should explicitly pass all the variables via :locals hash now.</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
<tt>country_select</tt> has been removed. See the <a href="http://www.rubyonrails.org/deprecation/list-of-countries">deprecation page</a> for more information and a plugin replacement.
</p>
</li>
diff --git a/railties/doc/guides/html/actioncontroller_basics.html b/railties/doc/guides/html/actioncontroller_basics.html
index 9bba0d301a..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 -->
<span style="color: #009900">@client</span> <span style="color: #990000">=</span> Client<span style="color: #990000">.</span>new
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
</tt></pre></div></div>
-<div class="para"><p>The Layouts &amp; rendering guide explains this in more detail.</p></div>
+<div class="para"><p>The <a href="../layouts_and_rendering.html">Layouts &amp; rendering guide</a> explains this in more detail.</p></div>
</div>
<h2 id="_parameters">3. Parameters</h2>
<div class="sectionbody">
diff --git a/railties/doc/guides/html/getting_started_with_rails.html b/railties/doc/guides/html/getting_started_with_rails.html
index e7be98d34a..d9a1779d56 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 {
</ul>
</li>
<li>
+ <a href="#_drying_up_the_code">DRYing up the Code</a>
+ <ul>
+
+ <li><a href="#_using_partials_to_eliminate_view_duplication">Using Partials to Eliminate View Duplication</a></li>
+
+ <li><a href="#_using_filters_to_eliminate_controller_duplication">Using Filters to Eliminate Controller Duplication</a></li>
+
+ </ul>
+ </li>
+ <li>
<a href="#_adding_a_second_model">Adding a Second Model</a>
<ul>
@@ -480,6 +490,24 @@ Transferring representations of the state of that resource between system compon
<div class="para"><p>For example, to a Rails application a request such as this:</p></div>
<div class="para"><p><tt>DELETE /photos/17</tt></p></div>
<div class="para"><p>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.</p></div>
+<div class="para"><p>If you’d like more details on REST as an architectural style, these resources are more approachable than Fielding’s thesis:</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
+<a href="http://www.infoq.com/articles/rest-introduction">A Brief Introduction to REST</a> by Stefan Tilkov
+</p>
+</li>
+<li>
+<p>
+<a href="http://bitworking.org/news/373/An-Introduction-to-REST">An Introduction to REST</a> (video tutorial) by Joe Gregorio
+</p>
+</li>
+<li>
+<p>
+<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Representational State Transfer</a> article in Wikipedia
+</p>
+</li>
+</ul></div>
</div>
<h2 id="_creating_a_new_rails_project">3. Creating a New Rails Project</h2>
<div class="sectionbody">
@@ -1402,7 +1430,7 @@ http://www.gnu.org/software/src-highlite -->
<td class="icon">
<img src="./images/icons/note.png" alt="Note" />
</td>
-<td class="content">Sharp-eyed readers will have noticed that the <tt>form_for</tt> declaration is identical for the <tt>create</tt> and <tt>edit</tt> 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 <em>partial template</em>, 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 <tt>create</tt> and <tt>edit</tt>.</td>
+<td class="content">Sharp-eyed readers will have noticed that the <tt>form_for</tt> declaration is identical for the <tt>new</tt> and <tt>edit</tt> 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 <em>partial template</em>, 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 <tt>create</tt> and <tt>edit</tt>.</td>
</tr></table>
</div>
<h3 id="_destroying_a_post">6.12. Destroying a Post</h3>
@@ -1424,10 +1452,124 @@ http://www.gnu.org/software/src-highlite -->
</tt></pre></div></div>
<div class="para"><p>The <tt>destroy</tt> 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.</p></div>
</div>
-<h2 id="_adding_a_second_model">7. Adding a Second Model</h2>
+<h2 id="_drying_up_the_code">7. DRYing up the Code</h2>
+<div class="sectionbody">
+<div class="para"><p>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 <em>partials</em> to clean up duplication in views and <em>filters</em> to help with duplication in controllers.</p></div>
+<h3 id="_using_partials_to_eliminate_view_duplication">7.1. Using Partials to Eliminate View Duplication</h3>
+<div class="para"><p>As you saw earlier, the scaffold-generated views for the <tt>new</tt> and <tt>edit</tt> actions are largely identical. You can pull the shared code out into a <tt>partial</tt> template. This requires editing the new and edit views, and adding a new template:</p></div>
+<div class="para"><p><tt>new.html.erb</tt>:
+[source, ruby]</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><tt>&lt;h1&gt;New post&lt;/h1&gt;
+
+&lt;%= render :partial =&gt; "form" %&gt;
+
+&lt;%= link_to 'Back', posts_path %&gt;</tt></pre>
+</div></div>
+<div class="para"><p><tt>edit.html.erb</tt>:
+[source, ruby]</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><tt>&lt;h1&gt;Editing post&lt;/h1&gt;
+
+&lt;%= render :partial =&gt; "form" %&gt;
+
+&lt;%= link_to 'Show', @post %&gt; |
+&lt;%= link_to 'Back', posts_path %&gt;</tt></pre>
+</div></div>
+<div class="para"><p><tt>_form.html.erb</tt>:
+[source, ruby]</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><tt>&lt;% form_for(@post) do |f| %&gt;
+ &lt;%= f.error_messages %&gt;
+
+ &lt;p&gt;
+ &lt;%= f.label :name %&gt;&lt;br /&gt;
+ &lt;%= f.text_field :name %&gt;
+ &lt;/p&gt;
+ &lt;p&gt;
+ &lt;%= f.label :title, "title" %&gt;&lt;br /&gt;
+ &lt;%= f.text_field :title %&gt;
+ &lt;/p&gt;
+ &lt;p&gt;
+ &lt;%= f.label :content %&gt;&lt;br /&gt;
+ &lt;%= f.text_area :content %&gt;
+ &lt;/p&gt;
+ &lt;p&gt;
+ &lt;%= f.submit "Save" %&gt;
+ &lt;/p&gt;
+&lt;% end %&gt;</tt></pre>
+</div></div>
+<div class="para"><p>Now, when Rails renders the <tt>new</tt> or <tt>edit</tt> view, it will insert the <tt>_form</tt> partial at the indicated point. Note the naming convention for partials: if you refer to a partial named <tt>form</tt> inside of a view, the corresponding file is <tt>_form.html.erb</tt>, with a leading underscore.</p></div>
+<div class="para"><p>For more information on partials, refer to the <a href="../layouts_and_rendering.html">Layouts and Rending in Rails</a> guide.</p></div>
+<h3 id="_using_filters_to_eliminate_controller_duplication">7.2. Using Filters to Eliminate Controller Duplication</h3>
+<div class="para"><p>At this point, if you look at the controller for posts, you’ll see some duplication:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> PostsController <span style="color: #990000">&lt;</span> ApplicationController
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> show
+ <span style="color: #009900">@post</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> edit
+ <span style="color: #009900">@post</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> update
+ <span style="color: #009900">@post</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> destroy
+ <span style="color: #009900">@post</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>Four instances of the exact same line of code doesn’t seem very DRY. Rails provides <em>filters</em> as a way to address this sort of repeated code. In this case, you can DRY things up by using a <tt>before_filter</tt>:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> PostsController <span style="color: #990000">&lt;</span> ApplicationController
+ before_filter <span style="color: #990000">:</span>find_post<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=&gt;</span> <span style="color: #990000">[:</span>show<span style="color: #990000">,</span> <span style="color: #990000">:</span>edit<span style="color: #990000">,</span> <span style="color: #990000">:</span>update<span style="color: #990000">,</span> <span style="color: #990000">:</span>destroy<span style="color: #990000">]</span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> show
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> edit
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> update
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> destroy
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ private
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> find_post
+ <span style="color: #009900">@post</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>Rails runs <em>before filters</em> before any action in the controller. You can use the <tt>:only</tt> clause to limit a before filter to only certain actions, or an <tt>:except</tt> clause to specifically skip a before filter for certain actions. Rails also allows you to define <em>after filters</em> that run after processing an action, as well as <em>around filters</em> that surround the processing of actions. Filters can also be defined in external classes to make it easy to share them between controllers.</p></div>
+<div class="para"><p>For more information on filters, see the <a href="actioncontroller_basics.html">Action Controller Basics</a> guide.</p></div>
+</div>
+<h2 id="_adding_a_second_model">8. Adding a Second Model</h2>
<div class="sectionbody">
<div class="para"><p>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.</p></div>
-<h3 id="_generating_a_model">7.1. Generating a Model</h3>
+<h3 id="_generating_a_model">8.1. Generating a Model</h3>
<div class="para"><p>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:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
@@ -1496,8 +1638,8 @@ http://www.gnu.org/software/src-highlite -->
<pre><tt>$ rake db<span style="color: #990000">:</span>migrate
</tt></pre></div></div>
<div class="para"><p>Rails is smart enough to only execute the migrations that have not already been run against this particular database.</p></div>
-<h3 id="_associating_models">7.2. Associating Models</h3>
-<div class="para"><p>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:</p></div>
+<h3 id="_associating_models">8.2. Associating Models</h3>
+<div class="para"><p>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:</p></div>
<div class="ilist"><ul>
<li>
<p>
@@ -1538,10 +1680,10 @@ http://www.gnu.org/software/src-highlite -->
<td class="icon">
<img src="./images/icons/tip.png" alt="Tip" />
</td>
-<td class="content">For more information on Active Record associations, see the <a href="../association_basics.html+">Active Record Associations</a> guide.</td>
+<td class="content">For more information on Active Record associations, see the <a href="../association_basics.html">Active Record Associations</a> guide.</td>
</tr></table>
</div>
-<h3 id="_adding_a_route">7.3. Adding a Route</h3>
+<h3 id="_adding_a_route">8.3. Adding a Route</h3>
<div class="para"><p><em>Routes</em> are entries in the <tt>config/routes.rb</tt> file that tell Rails how to match incoming HTTP requests to controller actions. Open up that file and find the existing line referring to <tt>posts</tt>. Then edit it as follows:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
@@ -1561,7 +1703,7 @@ http://www.gnu.org/software/src-highlite -->
<td class="content">For more information on routing, see the <a href="../routing_outside_in">Rails Routing from the Outside In</a> guide.</td>
</tr></table>
</div>
-<h3 id="_generating_a_controller">7.4. Generating a Controller</h3>
+<h3 id="_generating_a_controller">8.4. Generating a Controller</h3>
<div class="para"><p>With the model in hand, you can turn your attention to creating a matching controller. Again, there's a generator for this:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
@@ -1688,7 +1830,7 @@ http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #009900">@comment</span> <span style="color: #990000">=</span> <span style="color: #009900">@post</span><span style="color: #990000">.</span>comments<span style="color: #990000">.</span>build
</tt></pre></div></div>
<div class="para"><p>This creates a new <tt>Comment</tt> object <em>and</em> sets up the <tt>post_id</tt> field to have the <tt>id</tt> from the specified <tt>Post</tt> object in a single operation.</p></div>
-<h3 id="_building_views">7.5. Building Views</h3>
+<h3 id="_building_views">8.5. Building Views</h3>
<div class="para"><p>Because you skipped scaffolding, you'll need to build views for comments "by hand." Invoking <tt>script/generate controller</tt> will give you skeleton views, but they'll be devoid of actual content. Here's a first pass at fleshing out the comment views.</p></div>
<div class="para"><p>The <tt>index.html.erb</tt> view:</p></div>
<div class="listingblock">
@@ -1795,7 +1937,7 @@ http://www.gnu.org/software/src-highlite -->
<span style="color: #FF0000">&lt;%= link_to 'Back', post_comments_path(@post) %&gt;</span>
</tt></pre></div></div>
<div class="para"><p>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.</p></div>
-<h3 id="_hooking_comments_to_posts">7.6. Hooking Comments to Posts</h3>
+<h3 id="_hooking_comments_to_posts">8.6. Hooking Comments to Posts</h3>
<div class="para"><p>As a final step, I'll modify the <tt>show.html.erb</tt> view for a post to show the comments on that post, and to allow managing those comments:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
@@ -1836,7 +1978,7 @@ http://www.gnu.org/software/src-highlite -->
</tt></pre></div></div>
<div class="para"><p>Note that each post has its own individual comments collection, accessible as <tt>@post.comments</tt>. That's a consequence of the declarative associations in the models. Path helpers such as <tt>post_comments_path</tt> come from the nested route declaration in <tt>config/routes.rb</tt>.</p></div>
</div>
-<h2 id="_what_s_next">8. What's Next?</h2>
+<h2 id="_what_s_next">9. What's Next?</h2>
<div class="sectionbody">
<div class="para"><p>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:</p></div>
<div class="ilist"><ul>
@@ -1862,7 +2004,7 @@ The <a href="http://wiki.rubyonrails.org/rails">Rails wiki</a>
</li>
</ul></div>
</div>
-<h2 id="_changelog">9. Changelog</h2>
+<h2 id="_changelog">10. Changelog</h2>
<div class="sectionbody">
<div class="para"><p><a href="http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/2">Lighthouse ticket</a></p></div>
<div class="ilist"><ul>
diff --git a/railties/doc/guides/html/layouts_and_rendering.html b/railties/doc/guides/html/layouts_and_rendering.html
index 916cdd2053..a394da71df 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 -->
<pre><tt>render <span style="color: #990000">:</span>file <span style="color: #990000">=&gt;</span> filename<span style="color: #990000">,</span> <span style="color: #990000">:</span>content_type <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'application/rss'</span>
</tt></pre></div></div>
<h5 id="_the_tt_layout_tt_option">The <tt>:layout</tt> Option</h5>
-<div class="para"><p>With most of the options to <tt>render</tt>, 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 <tt>app/views/layouts</tt> with the same base name as the controller. For example, rendering actions from the <tt>PhotosController</tt> class will use <tt>/app/views/layouts/photos.html.erb</tt>. If there is no such controller-specific layout, Rails will use <tt>/app/views/layouts/application.html.erb</tt>.</p></div>
+<div class="para"><p>With most of the options to <tt>render</tt>, 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.</p></div>
<div class="para"><p>You can use the <tt>:layout</tt> option to tell Rails to use a specific file as the layout for the current action:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
@@ -560,7 +560,140 @@ http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>render <span style="color: #990000">:</span>xml <span style="color: #990000">=&gt;</span> photo<span style="color: #990000">,</span> <span style="color: #990000">:</span>location <span style="color: #990000">=&gt;</span> photo_url<span style="color: #990000">(</span>photo<span style="color: #990000">)</span>
</tt></pre></div></div>
-<h4 id="_avoiding_double_render_errors">2.2.11. Avoiding Double Render Errors</h4>
+<h4 id="_finding_layouts">2.2.11. Finding Layouts</h4>
+<div class="para"><p>To find the current layout, Rails first looks for a file in <tt>app/views/layouts</tt> with the same base name as the controller. For example, rendering actions from the <tt>PhotosController</tt> class will use <tt>/app/views/layouts/photos.html.erb</tt>. If there is no such controller-specific layout, Rails will use <tt>/app/views/layouts/application.html.erb</tt>. If there is no <tt>.erb</tt> layout, Rails will use a <tt>.builder</tt> layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions.</p></div>
+<h5 id="_specifying_layouts_on_a_per_controller_basis">Specifying Layouts on a per-Controller Basis</h5>
+<div class="para"><p>You can override the automatic layout conventions in your controllers by using the <tt>layout</tt> declaration in the controller. For example:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000">&lt;</span> ApplicationController
+ layout <span style="color: #FF0000">"inventory"</span>
+ <span style="font-style: italic"><span style="color: #9A1900">#...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>With this declaration, all methods within <tt>ProductsController</tt> will use <tt>app/views/layouts/inventory.html.erb</tt> for their layout.</p></div>
+<div class="para"><p>To assign a specific layout for the entire application, use a declaration in your <tt>ApplicationController</tt> class:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ApplicationController <span style="color: #990000">&lt;</span> ActionController<span style="color: #990000">::</span>Base
+ layout <span style="color: #FF0000">"main"</span>
+ <span style="font-style: italic"><span style="color: #9A1900">#...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>With this declaration, all views in the entire application will use <tt>app/views/layouts/main.html.erb</tt> for their layout.</p></div>
+<h5 id="_choosing_layouts_at_runtime">Choosing Layouts at Runtime</h5>
+<div class="para"><p>You can use a symbol to defer the choice of layout until a request is processed:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000">&lt;</span> ApplicationController
+ layout <span style="color: #990000">:</span>products_layout
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> show
+ <span style="color: #009900">@product</span> <span style="color: #990000">=</span> Product<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ private
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> products_layout
+ <span style="color: #009900">@current_user</span><span style="color: #990000">.</span>special? <span style="color: #990000">?</span> <span style="color: #FF0000">"special"</span> <span style="color: #990000">:</span> <span style="color: #FF0000">"products"</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>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:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000">&lt;</span> ApplicationController
+ layout proc<span style="color: #FF0000">{</span> <span style="color: #990000">|</span>controller<span style="color: #990000">|</span> controller<span style="color: #990000">.</span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<h5 id="_conditional_layouts">Conditional Layouts</h5>
+<div class="para"><p>Layouts specified at the controller level support <tt>:only</tt> and <tt>:except</tt> options that take either a method name or an array of method names:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><tt>class ProductsController &lt; ApplicationController
+ layout "inventory", :only =&gt; :index
+ layout "product", :except =&gt; [:index, :rss]
+ #...
+end</tt></pre>
+</div></div>
+<div class="para"><p>With those declarations, the <tt>inventory</tt> layout would be used only for the <tt>index</tt> method, the <tt>product</tt> layout would be used for everything else except the <tt>rss</tt> method, and the <tt>rss</tt> method will have its layout determined by the automatic layout rules.</p></div>
+<h5 id="_layout_inheritance">Layout Inheritance</h5>
+<div class="para"><p>Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ApplicationController <span style="color: #990000">&lt;</span> ActionController<span style="color: #990000">::</span>Base
+ layout <span style="color: #FF0000">"main"</span>
+ <span style="font-style: italic"><span style="color: #9A1900">#...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> PostsController <span style="color: #990000">&lt;</span> ApplicationController
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> SpecialPostsController <span style="color: #990000">&lt;</span> PostsController
+ layout <span style="color: #FF0000">"special"</span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> OldPostsController <span style="color: #990000">&lt;</span> SpecialPostsController
+ layout <span style="font-weight: bold"><span style="color: #0000FF">nil</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> show
+ <span style="color: #009900">@post</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>find<span style="color: #990000">(</span>params<span style="color: #990000">[:</span>id<span style="color: #990000">])</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
+ <span style="color: #009900">@old_posts</span> <span style="color: #990000">=</span> Post<span style="color: #990000">.</span>older
+ render <span style="color: #990000">:</span>layout <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">"old"</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>In this application:</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
+In general, views will be rendered in the <tt>main</tt> layout
+</p>
+</li>
+<li>
+<p>
+<tt>PostsController#index</tt> will use the <tt>main</tt> layout
+</p>
+</li>
+<li>
+<p>
+<tt>SpecialPostsController#index</tt> will use the <tt>special</tt> layout
+</p>
+</li>
+<li>
+<p>
+<tt>OldPostsController#show</tt> will use no layout at all
+</p>
+</li>
+<li>
+<p>
+<tt>OldPostsController#index</tt> will use the <tt>old</tt> layout
+</p>
+</li>
+</ul></div>
+<h4 id="_avoiding_double_render_errors">2.2.12. Avoiding Double Render Errors</h4>
<div class="para"><p>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 <tt>render</tt> works.</p></div>
<div class="para"><p>For example, here's some code that will trigger this error:</p></div>
<div class="listingblock">
@@ -666,8 +799,7 @@ http://www.gnu.org/software/src-highlite -->
</div>
<h2 id="_structuring_layouts">3. Structuring Layouts</h2>
<div class="sectionbody">
-<div class="para"><p>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 <tt>app/views/layouts</tt> with the same base name as the controller. For example, rendering actions from the <tt>PhotosController</tt> class will use <tt>/app/views/layouts/photos.html.erb</tt>. If there is no such controller-specific layout, Rails will use <tt>/app/views/layouts/application.html.erb</tt>. You can also specify a particular layout by using the <tt>:layout</tt> option to <tt>render</tt>.</p></div>
-<div class="para"><p>Within a layout, you have access to three tools for combining different bits of output to form the overall response:</p></div>
+<div class="para"><p>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:</p></div>
<div class="ilist"><ul>
<li>
<p>
@@ -1058,7 +1190,7 @@ http://www.gnu.org/software/src-highlite -->
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt>new.rhtml.erb:
+<pre><tt>new.html.erb:
<span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>New zone<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
&lt;%= error_messages_for :zone %&gt;
@@ -1108,7 +1240,7 @@ http://www.gnu.org/software/src-highlite -->
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt>index.rhtml.erb:
+<pre><tt>index.html.erb:
<span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>Products<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
&lt;%= render :partial =&gt; "product", :collection =&gt; @products %&gt;
@@ -1141,7 +1273,7 @@ http://www.gnu.org/software/src-highlite -->
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt>index.rhtml.erb:
+<pre><tt>index.html.erb:
<span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>Products<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
&lt;%= render :partial =&gt; @products %&gt;
@@ -1156,7 +1288,7 @@ _product.html.erb:
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt>index.rhtml.erb:
+<pre><tt>index.html.erb:
<span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>Contacts<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
&lt;%= render :partial =&gt; [customer1, employee1, customer2, employee2] %&gt;
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 {
<li><a href="#_command_line_injection">Command Line Injection</a></li>
+ <li><a href="#_header_injection">Header Injection</a></li>
+
</ul>
</li>
<li>
@@ -316,7 +318,7 @@ ul#navMain {
<div id="preamble">
<div class="sectionbody">
<div class="para"><p>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 {<em>et</em>} rorsecurity.info. After reading it, you should be familiar with:</p></div>
+mail me, Heiko Webers, at 42 {<em>et</em>} rorsecurity.info. After reading it, you should be familiar with:</p></div>
<div class="ilist"><ul>
<li>
<p>
@@ -1206,7 +1208,10 @@ s = sanitize(user_input, :tags =&gt; tags, :attributes =&gt; %w(href title))</tt
<div class="para"><p>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. <span style="background-color: #fffcdb;">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</span>. Use Rails' <tt>sanitize()</tt> method as a model for a whitelist CSS filter, if you really need one.</p></div>
<h3 id="_textile_injection">8.5. Textile Injection</h3>
<div class="para"><p>&#8212; <em>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. <a href="http://whytheluckystiff.net/ruby/redcloth/">RedCloth</a> is such a language for Ruby, but without precautions, it is also vulnerable to XSS.</em></p></div>
-<div class="para"><p>For example, RedCloth translates <em>test</em> to &lt;em&gt;test&lt;em&gt;, which makes the text italic. However, up to the current version 3.0.4, it is still vulnerable to XSS:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>For example, RedCloth translates _test_ to &lt;em&gt;test&lt;em&gt;, 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:</tt></pre>
+</div></div>
<div class="literalblock">
<div class="content">
<pre><tt>&gt;&gt; RedCloth.new('&lt;script&gt;alert(1)&lt;/script&gt;').to_html
@@ -1241,6 +1246,53 @@ s = sanitize(user_input, :tags =&gt; tags, :attributes =&gt; %w(href title))</tt
<pre><tt>system("/bin/echo","hello; rm *")
# prints "hello; rm *" and does not delete files</tt></pre>
</div></div>
+<h3 id="_header_injection">8.9. Header Injection</h3>
+<div class="para"><p>&#8212; <em>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.</em></p></div>
+<div class="para"><p>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. <span style="background-color: #fffcdb;">Remember to escape these header fields, too.</span> For example when you display the user agent in an administration area.</p></div>
+<div class="para"><p>Besides that, it is <span style="background-color: #fffcdb;">important to know what you are doing when building response headers partly based on user input.</span> 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:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>redirect_to params[:referer]</tt></pre>
+</div></div>
+<div class="para"><p>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:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>http://www.yourapplication.com/controller/action?referer=http://www.malicious.tld</tt></pre>
+</div></div>
+<div class="para"><p>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:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>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</tt></pre>
+</div></div>
+<div class="para"><p>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.</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>HTTP/1.1 302 Moved Temporarily
+(...)
+Location: http://www.malicious.tld</tt></pre>
+</div></div>
+<div class="para"><p>So <span style="background-color: #fffcdb;">attack vectors for Header Injection are based on the injection of CRLF characters in a header field.</span> 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. <span style="background-color: #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.</span></p></div>
+<h4 id="_response_splitting">8.9.1. Response Splitting</h4>
+<div class="para"><p>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:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>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
+
+
+&lt;html&gt;&lt;font color=red&gt;hey&lt;/font&gt;&lt;/html&gt; [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</tt></pre>
+</div></div>
+<div class="para"><p>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. <span style="background-color: #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.</span></p></div>
</div>
<h2 id="_additional_resources">9. Additional resources</h2>
<div class="sectionbody">
diff --git a/railties/doc/guides/source/2_2_release_notes.txt b/railties/doc/guides/source/2_2_release_notes.txt
index 57037e04e9..275cb095fd 100644
--- a/railties/doc/guides/source/2_2_release_notes.txt
+++ b/railties/doc/guides/source/2_2_release_notes.txt
@@ -27,20 +27,20 @@ Along with thread safety, a lot of work has been done to make Rails work well wi
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
+* link:http://guides.rubyonrails.org/getting_started_with_rails.html[Getting Started with Rails]
+* link:http://guides.rubyonrails.org/migrations.html[Rails Database Migrations]
+* link:http://guides.rubyonrails.org/association_basics.html[Active Record Associations]
+* link:http://guides.rubyonrails.org/finders.html[Active Record Finders]
+* link:http://guides.rubyonrails.org/layouts_and_rendering.html[Layouts and Rendering in Rails]
+* link:http://guides.rubyonrails.org/form_helpers.html[Action View Form Helpers]
+* link:http://guides.rubyonrails.org/routing_outside_in.html[Rails Routing from the Outside In]
+* link:http://guides.rubyonrails.org/actioncontroller_basics.html[Basics of Action Controller]
+* link:http://guides.rubyonrails.org/caching_with_rails.html[Rails Caching]
+* link:http://guides.rubyonrails.org/testing_rails_applications.html[Testing Rails Applications]
+* link:http://guides.rubyonrails.org/security.html[Securing Rails Applications]
+* link:http://guides.rubyonrails.org/debugging_rails_applications.html[Debugging Rails Applications]
+* link:http://guides.rubyonrails.org/benchmarking_and_profiling.html[Benchmarking and Profiling Rails Applications]
+* link:http://guides.rubyonrails.org/creating_plugins.html[The Basics of Creating Rails Plugins]
All told, the Guides provide tens of thousands of words of guidance for beginning and intermediate Rails developers.
@@ -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]
@@ -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]
@@ -148,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:
@@ -167,7 +167,7 @@ Product.find(:all, :joins => :photo,
Two new sets of methods have been added to Active Record's dynamic finders family.
-==== find_last_by_<attributes>
+==== +find_last_by_<attribute>+
The +find_last_by_<attribute>+ method is equivalent to +Model.last(:conditions => {:attribute => value})+
@@ -179,9 +179,9 @@ User.find_last_by_city('London')
* Lead Contributor: link:http://www.workingwithrails.com/person/9147-emilio-tagua[Emilio Tagua]
-==== find_by_<attributes>!
+==== +find_by_<attribute>!+
-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.
+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.
[source, ruby]
-------------------------------------------------------
@@ -191,6 +191,14 @@ 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
+* 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
* +rake db:migrate:redo+ now accepts an optional VERSION to target that specific migration to redo
@@ -315,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]
@@ -341,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.
@@ -362,11 +370,12 @@ To avoid deployment issues and make Rails applications more self-contained, it's
* +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.
+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]
+ - link:http://afreshcup.com/2008/10/25/rails-212-and-22rc1-update-your-rubygems/[Rails 2.1.2 and 2.2RC1: Update Your RubyGems]
=== Other Railties Changes
@@ -384,6 +393,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+ 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')+
@@ -393,4 +414,4 @@ A few pieces of older code are deprecated in this release:
== Credits
-Release notes compiled by link:http://afreshcup.com[Mike Gunderloy] \ No newline at end of file
+Release notes compiled by link:http://afreshcup.com[Mike Gunderloy]
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.
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]
+-------------------------------------------------------
+<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 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
diff --git a/railties/doc/guides/source/layouts_and_rendering.txt b/railties/doc/guides/source/layouts_and_rendering.txt
index ed56b82ffd..3d970b60ce 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+
@@ -652,7 +768,7 @@ You can also pass local variables into partials, making them even more powerful
[source, html]
-------------------------------------------------------
-new.rhtml.erb:
+new.html.erb:
<h1>New zone</h1>
<%= error_messages_for :zone %>
@@ -703,7 +819,7 @@ Partials are very useful in rendering collections. When you pass a collection to
[source, html]
-------------------------------------------------------
-index.rhtml.erb:
+index.html.erb:
<h1>Products</h1>
<%= render :partial => "product", :collection => @products %>
@@ -735,7 +851,7 @@ There's also a shorthand syntax available for rendering collections. For example
[source, html]
-------------------------------------------------------
-index.rhtml.erb:
+index.html.erb:
<h1>Products</h1>
<%= render :partial => @products %>
@@ -749,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:
<h1>Contacts</h1>
<%= render :partial => [customer1, employee1, customer2, employee2] %>
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 <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
@@ -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
+
+
+<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. [,#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: