From 993e8c55ca24f0d41364614a0ae3a7d42e216e94 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Fri, 20 May 2011 13:09:32 +0900 Subject: No "t." for the migration DSL! Now you can omit |t| block parameter and all the t. from your migration code, that means, the syntax looks more Rails-3-ish, like the routes DSL and ActionMailer DSL. Also, this change won't break any of your existing migration files, since the traditional syntax is still available. --- .../connection_adapters/abstract/schema_statements.rb | 4 ++-- .../connection_adapters/sqlite_adapter.rb | 18 ++++++++++-------- activerecord/lib/active_record/session_store.rb | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 9f9c2c42cb..21612dd15b 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -154,11 +154,11 @@ module ActiveRecord # ) # # See also TableDefinition#column for details on how to create columns. - def create_table(table_name, options = {}) + def create_table(table_name, options = {}, &blk) td = table_definition td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false - yield td if block_given? + td.instance_eval(&blk) if blk if options[:force] && table_exists?(table_name) drop_table(table_name, options) diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index d2785b234a..4b25384664 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -394,27 +394,29 @@ module ActiveRecord drop_table(from) end - def copy_table(from, to, options = {}) #:nodoc: - options = options.merge(:id => (!columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s)) + def copy_table(from, to, options = {}, &block) #:nodoc: + from_columns, from_primary_key = columns(from), primary_key(from) + options = options.merge(:id => (!from_columns.detect {|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s)) + table_definition = nil create_table(to, options) do |definition| - @definition = definition - columns(from).each do |column| + table_definition = definition + from_columns.each do |column| column_name = options[:rename] ? (options[:rename][column.name] || options[:rename][column.name.to_sym] || column.name) : column.name - @definition.column(column_name, column.type, + table_definition.column(column_name, column.type, :limit => column.limit, :default => column.default, :null => column.null) end - @definition.primary_key(primary_key(from)) if primary_key(from) - yield @definition if block_given? + table_definition.primary_key from_primary_key if from_primary_key + table_definition.instance_eval(&block) if block end copy_table_indexes(from, to, options[:rename] || {}) copy_table_contents(from, to, - @definition.columns.map {|column| column.name}, + table_definition.columns.map {|column| column.name}, options[:rename] || {}) end diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index c3e976002e..7bbac1505e 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -64,12 +64,13 @@ module ActiveRecord end def create_table! + id_col_name, data_col_name = session_id_column, data_column_name connection_pool.clear_table_cache!(table_name) connection.create_table(table_name) do |t| - t.string session_id_column, :limit => 255 - t.text data_column_name + t.string id_col_name, :limit => 255 + t.text data_col_name end - connection.add_index table_name, session_id_column, :unique => true + connection.add_index table_name, id_col_name, :unique => true end end -- cgit v1.2.3 From 696c2ea68d7cdbf7eb15f7dce2d83498ef659eb7 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Fri, 20 May 2011 13:17:16 +0900 Subject: Tests for new create_table DSL --- activerecord/test/cases/migration_test.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index bf7565a0d0..111dd01f2b 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1653,6 +1653,26 @@ if ActiveRecord::Base.connection.supports_migrations? end # SexyMigrationsTest + class SexierMigrationsTest < ActiveRecord::TestCase + def test_create_table_with_column_without_block_parameter + Person.connection.create_table :testings, :force => true do + column :foo, :string + end + assert Person.connection.column_exists?(:testings, :foo, :string) + ensure + Person.connection.drop_table :testings rescue nil + end + + def test_create_table_with_sexy_column_without_block_parameter + Person.connection.create_table :testings, :force => true do + integer :bar + end + assert Person.connection.column_exists?(:testings, :bar, :integer) + ensure + Person.connection.drop_table :testings rescue nil + end + end # SexierMigrationsTest + class MigrationLoggerTest < ActiveRecord::TestCase def test_migration_should_be_run_without_logger previous_logger = ActiveRecord::Base.logger -- cgit v1.2.3 From 325fdfc92833cd2a0ccc97f4e168f11a406edc76 Mon Sep 17 00:00:00 2001 From: Franck Verrot Date: Sun, 31 Jul 2011 20:05:58 +0200 Subject: Remove warnings by calling remove_method --- activemodel/test/cases/serializers/xml_serialization_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb index a38ef8e223..85f2085675 100644 --- a/activemodel/test/cases/serializers/xml_serialization_test.rb +++ b/activemodel/test/cases/serializers/xml_serialization_test.rb @@ -9,6 +9,7 @@ class Contact attr_accessor :address, :friends + remove_method :attributes def attributes instance_values.except("address", "friends") end -- cgit v1.2.3 From 4535191c61b496b1a5e9dc57624581753fa71497 Mon Sep 17 00:00:00 2001 From: Ryan Oblak Date: Tue, 27 Sep 2011 22:39:31 -0700 Subject: Modified String#pluralize to take an optional count parameter. --- .../lib/active_support/core_ext/string/inflections.rb | 17 ++++++++++++++--- activesupport/test/core_ext/string_ext_test.rb | 12 ++++++++---- .../source/active_support_core_extensions.textile | 8 ++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index c7ceeb9de4..fd91b3cacb 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -9,14 +9,25 @@ require 'active_support/inflector/transliterate' class String # Returns the plural form of the word in the string. # + # If the optional parameter +count+ is specified, + # the singular form will be returned if count == 1. + # For any other value of +count+ the plural will be returned. + # + # ==== Examples # "post".pluralize # => "posts" # "octopus".pluralize # => "octopi" # "sheep".pluralize # => "sheep" # "words".pluralize # => "words" # "the blue mailman".pluralize # => "the blue mailmen" # "CamelOctopus".pluralize # => "CamelOctopi" - def pluralize - ActiveSupport::Inflector.pluralize(self) + # "apple".pluralize(1) # => "apple" + # "apple".pluralize(2) # => "apples" + def pluralize(count = nil) + if count == 1 + self + else + ActiveSupport::Inflector.pluralize(self) + end end # The reverse of +pluralize+, returns the singular form of a word in a string. @@ -42,7 +53,7 @@ class String def constantize ActiveSupport::Inflector.constantize(self) end - + # +safe_constantize+ tries to find a declared constant with the name specified # in the string. It returns nil when the name is not in CamelCase # or is not initialized. See ActiveSupport::Inflector.safe_constantize diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 5c1dddaf96..4d876954cf 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -20,7 +20,7 @@ end class StringInflectionsTest < Test::Unit::TestCase include InflectorTestCases include ConstantizeTestCases - + def test_erb_escape string = [192, 60].pack('CC') expected = 192.chr + "<" @@ -64,6 +64,10 @@ class StringInflectionsTest < Test::Unit::TestCase end assert_equal("plurals", "plurals".pluralize) + + assert_equal("blargles", "blargle".pluralize(0)) + assert_equal("blargle", "blargle".pluralize(1)) + assert_equal("blargles", "blargle".pluralize(2)) end def test_singularize @@ -301,13 +305,13 @@ class StringInflectionsTest < Test::Unit::TestCase "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10) end end - + def test_constantize run_constantize_tests_on do |string| string.constantize end end - + def test_safe_constantize run_safe_constantize_tests_on do |string| string.safe_constantize @@ -381,7 +385,7 @@ class OutputSafetyTest < ActiveSupport::TestCase test "A fixnum is safe by default" do assert 5.html_safe? end - + test "a float is safe by default" do assert 5.7.html_safe? end diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 5aee001545..153a897b1c 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1426,6 +1426,14 @@ The method +pluralize+ returns the plural of its receiver: As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Built-in rules can be extended in +config/initializers/inflections.rb+. That file is generated by the +rails+ command and has instructions in comments. ++pluralize+ can also take an optional +count+ parameter. If count == 1 the singular form will be returned. For any other value of +count+ the plural form will be returned: + + +"dude".pluralize(0) # => "dudes" +"dude".pluralize(1) # => "dude" +"dude".pluralize(2) # => "dudes" + + Active Record uses this method to compute the default table name that corresponds to a model: -- cgit v1.2.3 From 78de4fcd050b5f2f67a1bf974ba6960b4b017443 Mon Sep 17 00:00:00 2001 From: Dmitriy Kiriyenko Date: Thu, 4 Aug 2011 15:44:08 +0300 Subject: When running "rake db:drop" also drop test database in development environment. --- .../lib/active_record/railties/databases.rake | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index b3316fd1a2..1009af850c 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -37,11 +37,7 @@ db_namespace = namespace :db do desc 'Create the database from config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)' task :create => :load_config do - # Make the test database at the same time as the development one, if it exists - if Rails.env.development? && ActiveRecord::Base.configurations['test'] - create_database(ActiveRecord::Base.configurations['test']) - end - create_database(ActiveRecord::Base.configurations[Rails.env]) + configs_for_environment.each { |config| create_database(config) } end def mysql_creation_options(config) @@ -138,12 +134,7 @@ db_namespace = namespace :db do desc 'Drops the database for the current Rails.env (use db:drop:all to drop all databases)' task :drop => :load_config do - config = ActiveRecord::Base.configurations[Rails.env || 'development'] - begin - drop_database(config) - rescue Exception => e - $stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}" - end + configs_for_environment.each { |config| drop_database_and_rescue(config) } end def local_database?(config, &block) @@ -548,6 +539,19 @@ def drop_database(config) end end +def drop_database_and_rescue(config) + begin + drop_database(config) + rescue Exception => e + $stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}" + end +end + +def configs_for_environment + environments = [Rails.env, ("test" if Rails.env.development?)] + ActiveRecord::Base.configurations.values_at(*environments).compact +end + def session_table_name ActiveRecord::SessionStore::Session.table_name end -- cgit v1.2.3 From 3dbedd2823ff6c8a1f2f078ae9df9c6ceb275e1b Mon Sep 17 00:00:00 2001 From: Mike Perham Date: Fri, 14 Oct 2011 21:09:53 -0700 Subject: Default timestamps to non-null --- .../connection_adapters/abstract/schema_definitions.rb | 2 +- .../connection_adapters/abstract/schema_statements.rb | 4 ++-- activerecord/test/cases/migration_test.rb | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 82f564e41d..989a4fcbca 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -252,7 +252,7 @@ module ActiveRecord # Appends :datetime columns :created_at and # :updated_at to the table. def timestamps(*args) - options = args.extract_options! + options = { :null => false }.merge(args.extract_options!) column(:created_at, :datetime, options) column(:updated_at, :datetime, options) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 8e3ba1297e..b4a9e29ef1 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -507,8 +507,8 @@ module ActiveRecord # ===== Examples # add_timestamps(:suppliers) def add_timestamps(table_name) - add_column table_name, :created_at, :datetime - add_column table_name, :updated_at, :datetime + add_column table_name, :created_at, :datetime, :null => false + add_column table_name, :updated_at, :datetime, :null => false end # Removes the timestamp columns (created_at and updated_at) from the table definition. diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 93a1249e43..4b5dd18be8 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -389,8 +389,8 @@ if ActiveRecord::Base.connection.supports_migrations? created_at_column = created_columns.detect {|c| c.name == 'created_at' } updated_at_column = created_columns.detect {|c| c.name == 'updated_at' } - assert created_at_column.null - assert updated_at_column.null + assert !created_at_column.null + assert !updated_at_column.null ensure Person.connection.drop_table table_name rescue nil end @@ -471,11 +471,11 @@ if ActiveRecord::Base.connection.supports_migrations? # Do a manual insertion if current_adapter?(:OracleAdapter) - Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)" + Person.connection.execute "insert into people (id, wealth, created_at, updated_at) values (people_seq.nextval, 12345678901234567890.0123456789, 0, 0)" elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings - Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')" + Person.connection.execute "insert into people (wealth, created_at, updated_at) values ('12345678901234567890.0123456789', 0, 0)" else - Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)" + Person.connection.execute "insert into people (wealth, created_at, updated_at) values (12345678901234567890.0123456789, 0, 0)" end # SELECT -- cgit v1.2.3 From f247c5f81175fc160de6be906ef87316f0528f38 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Sat, 15 Oct 2011 11:34:33 +0400 Subject: Update AC::RecordIdentifier example --- actionpack/lib/action_controller/record_identifier.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 2036442cfe..9c38ff44d8 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -14,9 +14,9 @@ module ActionController # <% end %> # # # controller - # def destroy + # def update # post = Post.find(params[:id]) - # post.destroy + # post.update_attributes(params[:post]) # # redirect_to(post) # Calls polymorphic_url(post) which in turn calls post_url(post) # end -- cgit v1.2.3 From 26204def8f28f190b9fef1144720288f87bd4fb4 Mon Sep 17 00:00:00 2001 From: mhutchin Date: Sat, 15 Oct 2011 05:32:13 -0700 Subject: [layouts and rendering] Copy editing to improve readability --- .../guides/source/layouts_and_rendering.textile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 69ef05104c..6f0dc57090 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -348,9 +348,9 @@ h5. 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+ (or +app/views/layouts/photos.builder+). If there is no such controller-specific layout, Rails will use +app/views/layouts/application.html.erb+ or +app/views/layouts/application.builder+. 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. -h6. Specifying Layouts on a per-Controller Basis +h6. Specifying Layouts for Controllers -You can override the automatic layout conventions in your controllers by using the +layout+ declaration in the controller. For example: +You can override the default layout conventions in your controllers by using the +layout+ declaration. For example: class ProductsController < ApplicationController @@ -359,9 +359,9 @@ class ProductsController < ApplicationController end -With this declaration, all methods within +ProductsController+ will use +app/views/layouts/inventory.html.erb+ for their layout. +With this declaration, all of the 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: +To assign a specific layout for the entire application, use a +layout+ declaration in your +ApplicationController+ class: class ApplicationController < ActionController::Base @@ -370,7 +370,7 @@ class ApplicationController < ActionController::Base end -With this declaration, all views in the entire application will use +app/views/layouts/main.html.erb+ for their layout. +With this declaration, all of the views in the entire application will use +app/views/layouts/main.html.erb+ for their layout. h6. Choosing Layouts at Runtime @@ -392,9 +392,9 @@ class ProductsController < ApplicationController 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: +Now, if the current user is a special user, they'll get a special layout when viewing a product. -You can also decide the layout by passing a Proc object, the block you give the Proc will be given the +controller+ instance, so you can make decisions based on the current request. For example: +You can even use an inline method, such as a Proc, to determine the layout. For example, if you pass a Proc object, the block you give the Proc will be given the +controller+ instance, so the layout can be determined based on the current request: class ProductsController < ApplicationController @@ -404,7 +404,7 @@ end h6. 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 which correspond to method names within the controller: +Layouts specified at the controller level support the +:only+ and +:except+ options. These options take either a method name, or an array of method names, corresponding to method names within the controller: class ProductsController < ApplicationController @@ -416,7 +416,7 @@ With this declaration, the +product+ layout would be used for everything but the h6. Layout Inheritance -Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example: +Layout declarations cascade downward in the hierarchy, and more specific layout declarations always override more general ones. For example: * +application_controller.rb+ @@ -495,9 +495,9 @@ def show end -Make sure you use +and return+ and not +&& return+ because while the former will work, the latter will not due to operator precedence in the Ruby Language. +Make sure to use +and return+ and not +&& return+, since +&& return+ will not work due to the operator precedence in the Ruby Language. -Note that the implicit render done by ActionController detects if +render+ has been called, and thus avoids this error. Therefore, the following will work without errors: +Note that the implicit render done by ActionController detects if +render+ has been called, so the following will work without errors: def show -- cgit v1.2.3 From 018e84af200859e72cc5b895c4a843f81c6b5931 Mon Sep 17 00:00:00 2001 From: "Karunakar (Ruby)" Date: Sun, 16 Oct 2011 01:00:57 +0530 Subject: railties README change to make consistent like others eg:activerecord --- railties/README.rdoc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/railties/README.rdoc b/railties/README.rdoc index 95c43045b0..b77304fc3b 100644 --- a/railties/README.rdoc +++ b/railties/README.rdoc @@ -15,12 +15,18 @@ The latest version of Railties can be installed with RubyGems: * gem install railties -Documentation can be found at +== License -* http://api.rubyonrails.org +Railties is released under the MIT license. +== Support -== License +API documentation is at -Railties is released under the MIT license. +* http://api.rubyonrails.org + +Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues +You can find more usage information in the ActiveResource::Base documentation. -- cgit v1.2.3 From 4867bfabaa03b4c936dd766c7f2edf0919e05ca4 Mon Sep 17 00:00:00 2001 From: "Karunakar (Ruby)" Date: Sun, 16 Oct 2011 01:12:00 +0530 Subject: more doc changes on railties README --- railties/README.rdoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/railties/README.rdoc b/railties/README.rdoc index b77304fc3b..ae40600401 100644 --- a/railties/README.rdoc +++ b/railties/README.rdoc @@ -15,6 +15,10 @@ The latest version of Railties can be installed with RubyGems: * gem install railties +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/master/railties + == License Railties is released under the MIT license. @@ -29,4 +33,3 @@ Bug reports and feature requests can be filed with the rest for the Ruby on Rail * https://github.com/rails/rails/issues -You can find more usage information in the ActiveResource::Base documentation. -- cgit v1.2.3 From 8f473dc9aea2099e6e7e47c929c6a9cec02c7902 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Sat, 15 Oct 2011 23:54:26 +0400 Subject: HTMl -> HTML: html scanner comment fix --- actionpack/lib/action_controller/vendor/html-scanner/html/document.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb index 7fa3aead82..386820300a 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb @@ -4,7 +4,7 @@ require 'html/selector' require 'html/sanitizer' module HTML #:nodoc: - # A top-level HTMl document. You give it a body of text, and it will parse that + # A top-level HTML document. You give it a body of text, and it will parse that # text into a tree of nodes. class Document #:nodoc: -- cgit v1.2.3 From abf4f096e56a941ac4f908cb34c83bc82770ed56 Mon Sep 17 00:00:00 2001 From: mhutchin Date: Sat, 15 Oct 2011 15:59:26 -0700 Subject: [layouts and rendering] Copy editing --- .../guides/source/layouts_and_rendering.textile | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 6f0dc57090..df7b9b364c 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -334,7 +334,7 @@ render :status => 500 render :status => :forbidden -Rails understands both numeric status codes and symbols for status codes. +Rails understands both numeric and symbolic status codes. h6. The +:location+ Option @@ -518,7 +518,7 @@ Another way to handle returning responses to an HTTP request is with +redirect_t redirect_to photos_url -You can use +redirect_to+ with any arguments that you could use with +link_to+ or +url_for+. In addition, there's a special redirect that sends the user back to the page they just came from: +You can use +redirect_to+ with any arguments that you could use with +link_to+ or +url_for+. There's also a special redirect that sends the user back to the page they just came from: redirect_to :back @@ -526,7 +526,7 @@ redirect_to :back h5. Getting a Different Redirect Status Code -Rails uses HTTP status code 302 (temporary redirect) when you call +redirect_to+. If you'd like to use a different status code (perhaps 301, permanent redirect), you can do so by using the +:status+ option: +Rails uses HTTP status code 302, a temporary redirect, when you call +redirect_to+. If you'd like to use a different status code, perhaps 301, a permanent redirect, you can use the +:status+ option: redirect_to photos_path, :status => 301 @@ -536,7 +536,7 @@ Just like the +:status+ option for +render+, +:status+ for +redirect_to+ accepts h5. The Difference Between +render+ and +redirect_to+ -Sometimes inexperienced developers conceive of +redirect_to+ as a sort of +goto+ command, moving execution from one place to another in your Rails code. This is _not_ correct. Your code stops running and waits for a new request for the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code. +Sometimes inexperienced developers think of +redirect_to+ as a sort of +goto+ command, moving execution from one place to another in your Rails code. This is _not_ correct. Your code stops running and waits for a new request for the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code. Consider these actions to see the difference: @@ -553,7 +553,7 @@ def show end -With the code in this form, there will likely be a problem if the +@book+ variable is +nil+. Remember, a +render :action+ doesn't run any code in the target action, so nothing will set up the +@books+ variable that the +index+ view is presumably depending on. One way to fix this is to redirect instead of rendering: +With the code in this form, there will likely be a problem if the +@book+ variable is +nil+. Remember, a +render :action+ doesn't run any code in the target action, so nothing will set up the +@books+ variable that the +index+ view will probably require. One way to fix this is to redirect instead of rendering: def index @@ -570,9 +570,9 @@ end With this code, the browser will make a fresh request for the index page, the code in the +index+ method will run, and all will be well. -The only downside to this code, is that it requires a round trip to the browser, the browser requested the show action with +/books/1+ and the controller finds that there are no books, so the controller sends out a 302 redirect response to the browser telling it to go to +/books/+, the browser complies and sends a new request back to the controller asking now for the +index+ action, the controller then gets all the books in the database and renders the index template, sending it back down to the browser which then shows it on your screen. +The only downside to this code is that it requires a round trip to the browser: the browser requested the show action with +/books/1+ and the controller finds that there are no books, so the controller sends out a 302 redirect response to the browser telling it to go to +/books/+, the browser complies and sends a new request back to the controller asking now for the +index+ action, the controller then gets all the books in the database and renders the index template, sending it back down to the browser which then shows it on your screen. -While in a small app, this added latency might not be a problem, it is something to think about when speed of response is of the essence. One way to handle this double request (though a contrived example) could be: +While in a small application, this added latency might not be a problem, it is something to think about if response time is a concern. We can demonstrate one way to handle this with a contrived example: def index @@ -588,7 +588,7 @@ def show end -Which would detect that there are no books, populate the +@books+ instance variable with all the books in the database and then directly render the +index.html.erb+ template returning it to the browser with a flash alert message telling the user what happened. +This would detect that there are no books with the specified ID, populate the +@books+ instance variable with all the books in the model, and then directly render the +index.html.erb+ template, returning it to the browser with a flash alert message to tell the user what happened. h4. Using +head+ To Build Header-Only Responses @@ -598,7 +598,7 @@ The +head+ method can be used to send responses with only headers to the browser head :bad_request -Which would produce the following header: +This would produce the following header: HTTP/1.1 400 Bad Request @@ -611,7 +611,7 @@ Set-Cookie: _blog_session=...snip...; path=/; HttpOnly Cache-Control: no-cache -Or you can use other HTTP headers to convey additional information: +Or you can use other HTTP headers to convey other information: head :created, :location => photo_path(@photo) @@ -633,15 +633,15 @@ Cache-Control: no-cache h3. Structuring Layouts -When Rails renders a view as a response, it does so by combining the view with the current layout (using the rules for finding the current layout that were covered earlier in this guide). Within a layout, you have access to three tools for combining different bits of output to form the overall response: +When Rails renders a view as a response, it does so by combining the view with the current layout, using the rules for finding the current layout that were covered earlier in this guide. Within a layout, you have access to three tools for combining different bits of output to form the overall response: * Asset tags * +yield+ and +content_for+ * Partials -h4. Asset Tags +h4. Asset Tag Helpers -Asset tags provide methods for generating HTML that links views to feeds, JavaScript, stylesheets, images, videos and audios. These are the six asset tags available in Rails: +Asset tag helpers provide methods for generating HTML that link views to feeds, JavaScript, stylesheets, images, videos and audios. There are six asset tag helpers available in Rails: * +auto_discovery_link_tag+ * +javascript_include_tag+ @@ -650,11 +650,11 @@ Asset tags provide methods for generating HTML that links views to feeds, JavaSc * +video_tag+ * +audio_tag+ -You can use these tags in layouts or other views, although the tags other than +image_tag+ are most commonly used in the +<head>+ section of a layout. +You can use these tags in layouts or other views, although the +auto_discovery_link_tag+, +javascript_include_tag+, and +stylesheet_link_tag+, are most commonly used in the +<head>+ section of a layout. -WARNING: The asset tags do _not_ verify the existence of the assets at the specified locations; they simply assume that you know what you're doing and generate the link. +WARNING: The asset tag helpers do _not_ verify the existence of the assets at the specified locations; they simply assume that you know what you're doing and generate the link. -h5. Linking to Feeds with +auto_discovery_link_tag+ +h5. Linking to Feeds with the +auto_discovery_link_tag+ The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsreaders can use to detect the presences of RSS or ATOM feeds. It takes the type of the link (+:rss+ or +:atom+), a hash of options that are passed through to url_for, and a hash of options for the tag: @@ -663,13 +663,13 @@ The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsread {:title => "RSS Feed"}) %> -There are three tag options available for +auto_discovery_link_tag+: +There are three tag options available for the +auto_discovery_link_tag+: -* +:rel+ specifies the +rel+ value in the link (defaults to "alternate") +* +:rel+ specifies the +rel+ value in the link. The default value is "alternate". * +:type+ specifies an explicit MIME type. Rails will generate an appropriate MIME type automatically. -* +:title+ specifies the title of the link +* +:title+ specifies the title of the link. The default value is the upshifted +:type+ value, for example, "ATOM" or "RSS". -h5. Linking to JavaScript Files with +javascript_include_tag+ +h5. Linking to JavaScript Files with the +javascript_include_tag+ The +javascript_include_tag+ helper returns an HTML +script+ tag for each source provided. Rails looks in +public/javascripts+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/javascripts/main.js+: @@ -738,7 +738,7 @@ By default, the combined file will be delivered as +javascripts/all.js+. You can You can even use dynamic paths such as +cache/#{current_site}/main/display+. -h5. Linking to CSS Files with +stylesheet_link_tag+ +h5. Linking to CSS Files with the +stylesheet_link_tag+ The +stylesheet_link_tag+ helper returns an HTML +<link>+ tag for each source provided. Rails looks in +public/stylesheets+ for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include +public/stylesheets/main.css+: @@ -764,7 +764,7 @@ To include +http://example.com/main.css+: <%= stylesheet_link_tag "http://example.com/main.css" %> -By default, +stylesheet_link_tag+ creates links with +media="screen" rel="stylesheet" type="text/css"+. You can override any of these defaults by specifying an appropriate option (+:media+, +:rel+, or +:type+): +By default, the +stylesheet_link_tag+ creates links with +media="screen" rel="stylesheet" type="text/css"+. You can override any of these defaults by specifying an appropriate option (+:media+, +:rel+, or +:type+): <%= stylesheet_link_tag "main_print", :media => "print" %> @@ -797,7 +797,7 @@ By default, the combined file will be delivered as +stylesheets/all.css+. You ca You can even use dynamic paths such as +cache/#{current_site}/main/display+. -h5. Linking to Images with +image_tag+ +h5. Linking to Images with the +image_tag+ The +image_tag+ helper builds an HTML +<img />+ tag to the specified file. By default, files are loaded from +public/images+. @@ -846,7 +846,7 @@ In addition to the above special tags, you can supply a final hash of standard H :class => 'nav_bar' %> -h5. Linking to Videos with +video_tag+ +h5. Linking to Videos with the +video_tag+ The +video_tag+ helper builds an HTML 5 +<video>+ tag to the specified file. By default, files are loaded from +public/videos+. @@ -882,7 +882,7 @@ This will produce: -h5. Linking to Audio files with +audio_tag+ +h5. Linking to Audio Files with the +audio_tag+ The +audio_tag+ helper builds an HTML 5 +<audio>+ tag to the specified file. By default, files are loaded from +public/audios+. @@ -933,7 +933,7 @@ You can also create a layout with multiple yielding regions: The main body of the view will always render into the unnamed +yield+. To render content into a named +yield+, you use the +content_for+ method. -h4. Using +content_for+ +h4. Using the +content_for+ Method The +content_for+ method allows you to insert content into a named +yield+ block in your layout. For example, this view would work with the layout that you just saw: -- cgit v1.2.3 From 9210458547bbf5e79aa650e15226a0d5c58ea6c7 Mon Sep 17 00:00:00 2001 From: Vishnu Atrai Date: Sun, 16 Oct 2011 14:29:06 +0530 Subject: fix to remove warning in test cases --- activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb b/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb index 5ffd886dab..97adb6b297 100644 --- a/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb +++ b/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb @@ -21,7 +21,7 @@ class MysqlCaseSensitivityTest < ActiveRecord::TestCase CollationTest.create!(:string_ci_column => 'A') invalid = CollationTest.new(:string_ci_column => 'a') queries = assert_sql { invalid.save } - ci_uniqueness_query = queries.detect { |q| q.match /string_ci_column/ } + ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) } assert_no_match(/lower/i, ci_uniqueness_query) end @@ -29,7 +29,7 @@ class MysqlCaseSensitivityTest < ActiveRecord::TestCase CollationTest.create!(:string_cs_column => 'A') invalid = CollationTest.new(:string_cs_column => 'a') queries = assert_sql { invalid.save } - cs_uniqueness_query = queries.detect { |q| q.match /string_cs_column/ } + cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) } assert_match(/lower/i, cs_uniqueness_query) end end -- cgit v1.2.3 From bb8ee9264f8302ea9f669c96f46d9c3812d6f350 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Sat, 15 Oct 2011 09:51:30 +1100 Subject: [engines guide] improve intro to 'Hooking into an application' section --- railties/guides/source/engines.textile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 126d09ab87..4f77852c40 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -343,9 +343,13 @@ The +comment_counter+ local variable is given to us by the +<%= render @post.com That completes the comment function of the blogging engine. Now it's time to use it within an application. -h3. Hooking into application +h3. Hooking into an application -Using an engine within an application is very easy. First, the engine needs to be specified inside the application's +Gemfile+. If there isn't an application handy to test this out in, generate one using the +rails new+ command outside of the engine directory like this: +Using an engine within an application is very easy. This section covers how to mount the engine into an application and the initial setup required for it, as well as linking the engine to a +User+ class provided by the application to provide ownership for posts and comments within the engine. + +h4. Mounting the engine + +First, the engine needs to be specified inside the application's +Gemfile+. If there isn't an application handy to test this out in, generate one using the +rails new+ command outside of the engine directory like this: $ rails new unicorn -- cgit v1.2.3 From 0f87cc1486e2b7f95fff69ead9e6c74344c89496 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Sat, 15 Oct 2011 09:52:07 +1100 Subject: [engines guide] Add 'Engine setup' section in 'Hooking into an application' section --- railties/guides/source/engines.textile | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 4f77852c40..8d5c231124 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -378,14 +378,32 @@ As described earlier, by placing the gem in the +Gemfile+ it will be loaded when To make the engine's functionality accessible from within an application, it needs to be mounted in that application's +config/routes.rb+ file: - mount Blorgh::Engine, :at => "blog" +mount Blorgh::Engine, :at => "blog" +This line will mount the engine at +blog+ in the application. Making it accessible at +http://localhost:3000/blog+ when the application runs with +rails s+. + NOTE: Other engines, such as Devise, handle this a little differently by making you specify custom helpers such as +devise_for+ in the routes. These helpers do exactly the same thing, mounting pieces of the engines's functionality at a pre-defined path which may be customizable. +h4. Engine setup + +The engine contains migrations for the +blorgh_posts+ and +blorgh_comments+ table which need to be created in the application's database so that the engine's models can query them correctly. To copy these migrations into the application use this command: + + +$ rake blorgh:install:migrations + + +This command, when run for the first time will copy over all the migrations from the engine. When run the next time, it will only copy over migrations that haven't been copied over already. The first run for this command will output something such as this: + + +Copied migration [timestamp_1]_create_blorgh_posts.rb from blorgh +Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh + + +The first timestamp (+\[timestamp_1\]+) will be the current time and the second timestamp (+\[timestamp_2\]+) will be the current time plus a second. The reason for this is so that the migrations for the engine are run after any existing migrations in the application. +To run these migrations within the context of the application, simply run +rake db:migrate+. When accessing the engine through +http://localhost:3000/blog+, the posts will be empty. This is because the table created inside the application is different from the one created within the engine. Go ahead, play around with the newly mounted engine. You'll find that it's the same as when it was only an engine. -This line will mount the engine TODO: Application will provide a User foundation class which the engine hooks into through a configuration setting, configurable in the application's initializers. The engine will be mounted at the +/blog+ path in the application. h3. Overriding engine functionality -- cgit v1.2.3 From 434148024d742ec50662bf72c5cbb8e5664985e5 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Sun, 16 Oct 2011 09:53:26 +1100 Subject: [engines guide] beginning to cover using application's classes --- railties/guides/source/engines.textile | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 8d5c231124..9cdca25329 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -404,7 +404,29 @@ The first timestamp (+\[timestamp_1\]+) will be the current time and the second To run these migrations within the context of the application, simply run +rake db:migrate+. When accessing the engine through +http://localhost:3000/blog+, the posts will be empty. This is because the table created inside the application is different from the one created within the engine. Go ahead, play around with the newly mounted engine. You'll find that it's the same as when it was only an engine. -TODO: Application will provide a User foundation class which the engine hooks into through a configuration setting, configurable in the application's initializers. The engine will be mounted at the +/blog+ path in the application. +h4. Using an application's classes + +When an engine is created, it may want to use specific classes from an application to provide links between the pieces of the engine and the pieces of the application. In the case of the +blorgh+ engine, making posts and comments have authors would make a lot of sense. + +Usually, an application would have a +User+ class that would provide the objects that would represent the posts' and comments' authors, but there could be a case where the application calls this class something different, such as +Person+. It's because of this reason that the engine should not hardcode the associations to be exactly for a +User+ class, but should allow for some flexibility around what the class is called. + +To keep it simple in this case, the application will have a class called +User+ which will represent the users of the application. It can be generated using this command: + + +rails g model user name:string + + +Also to keep it simple, the posts form will have a new text field called +author+ where users can elect to put their name. The engine will then take this name and create a new +User+ object from it or find one that already has that name, and then associate the post with it. + +First, the +author+ text field needs to be added to the +app/views/blorgh/posts/_form.html.erb+ partial inside the engine. This can be added above the +title+ field with this code: + + +
+ <%= f.label :author %>
+ <%= f.text_field :author %> +
+
+ h3. Overriding engine functionality -- cgit v1.2.3 From 5bf0ea6830f9148f6b45d2774bfd7f54eec4a267 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Mon, 17 Oct 2011 08:55:32 +1100 Subject: [engines guide] Complete section about using an application's class --- railties/guides/source/engines.textile | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 9cdca25329..bc5fe7640a 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -404,7 +404,7 @@ The first timestamp (+\[timestamp_1\]+) will be the current time and the second To run these migrations within the context of the application, simply run +rake db:migrate+. When accessing the engine through +http://localhost:3000/blog+, the posts will be empty. This is because the table created inside the application is different from the one created within the engine. Go ahead, play around with the newly mounted engine. You'll find that it's the same as when it was only an engine. -h4. Using an application's classes +h4. Using a class provided by the application When an engine is created, it may want to use specific classes from an application to provide links between the pieces of the engine and the pieces of the application. In the case of the +blorgh+ engine, making posts and comments have authors would make a lot of sense. @@ -416,17 +416,38 @@ To keep it simple in this case, the application will have a class called +User+ rails g model user name:string
-Also to keep it simple, the posts form will have a new text field called +author+ where users can elect to put their name. The engine will then take this name and create a new +User+ object from it or find one that already has that name, and then associate the post with it. +Also to keep it simple, the posts form will have a new text field called +author_name_+ where users can elect to put their name. The engine will then take this name and create a new +User+ object from it or find one that already has that name, and then associate the post with it. -First, the +author+ text field needs to be added to the +app/views/blorgh/posts/_form.html.erb+ partial inside the engine. This can be added above the +title+ field with this code: +First, the +author_name+ text field needs to be added to the +app/views/blorgh/posts/_form.html.erb+ partial inside the engine. This can be added above the +title+ field with this code:
- <%= f.label :author %>
- <%= f.text_field :author %> + <%= f.label :author_name %>
+ <%= f.text_field :author_name %>
+The +Blorgh::Post+ model should then have some code to convert the +author_name+ field into an actual +User+ object and associate it as that post's +author+ before the post is saved. It will also need to have an +attr_accessor+ setup for this field so that the setter and getter methods are defined for it. + +To do all this, you'll need to add the +attr_accessor+ for +author_name+, the association for the author and the +before_save+ call into +app/models/blorgh/post.rb+. The +author+ association will be hard-coded to the +User+ class for the time being. + + +attr_accessor :author_name +belongs_to :author, :class_name => "User" + +before_save :set_author + +private + def set_author + self.author = User.find_or_create_by_name(author_name) + end + + +By defining that the +author+ association's object is represented by the +User+ class a link is established between the engine and the application. Now just before a post is saved it will be associated with a record from the +users+ table of the application. + +h4. Configuring an engine + +The next step is to make the class that represents a +User+ in the application customizable for the engine. This is because, as explained before, that class may not always be +User+. h3. Overriding engine functionality -- cgit v1.2.3 From 7d8c650e8663e0af722225e66f72a82dcb518b55 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Mon, 17 Oct 2011 17:12:31 +1100 Subject: [engines guide] [reviewing] remove excessive 'Now' --- railties/guides/source/engines.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index bc5fe7640a..d191fe07b6 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -443,7 +443,7 @@ private end
-By defining that the +author+ association's object is represented by the +User+ class a link is established between the engine and the application. Now just before a post is saved it will be associated with a record from the +users+ table of the application. +By defining that the +author+ association's object is represented by the +User+ class a link is established between the engine and the application. Just before a post is saved it will be associated with a record from the +users+ table of the application. h4. Configuring an engine -- cgit v1.2.3 From 180d4137ca8222cb90a285bfd60265ae93c56968 Mon Sep 17 00:00:00 2001 From: Martin Svalin Date: Tue, 11 Oct 2011 21:44:22 +0200 Subject: ActiveModel::Errors#generate_message without i18n_scope, and more test cases for #add --- activemodel/lib/active_model/errors.rb | 12 ++++++++---- activemodel/test/cases/errors_test.rb | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index d91e4a2b6a..f90030641d 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -300,13 +300,17 @@ module ActiveModel def generate_message(attribute, type = :invalid, options = {}) type = options.delete(:message) if options[:message].is_a?(Symbol) - defaults = @base.class.lookup_ancestors.map do |klass| - [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", - :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ] + if @base.class.respond_to?(:i18n_scope) + defaults = @base.class.lookup_ancestors.map do |klass| + [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", + :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ] + end + else + defaults = [] end defaults << options.delete(:message) - defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" + defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" if @base.class.respond_to?(:i18n_scope) defaults << :"errors.attributes.#{attribute}.#{type}" defaults << :"errors.messages.#{type}" diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 4c76bb43a8..784a2b2709 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -66,6 +66,20 @@ class ErrorsTest < ActiveModel::TestCase assert_equal ["can not be blank"], person.errors[:name] end + test "should be able to add an error with a symbol" do + person = Person.new + person.errors.add(:name, :blank) + message = person.errors.generate_message(:name, :blank) + assert_equal [message], person.errors[:name] + end + + test "should be able to add an error with a proc" do + person = Person.new + message = Proc.new { "can not be blank" } + person.errors.add(:name, message) + assert_equal ["can not be blank"], person.errors[:name] + end + test 'should respond to size' do person = Person.new person.errors.add(:name, "can not be blank") @@ -112,5 +126,12 @@ class ErrorsTest < ActiveModel::TestCase assert_equal ["is invalid"], hash[:email] end + test "generate_message should work without i18n_scope" do + person = Person.new + assert !Person.respond_to?(:i18n_scope) + assert_nothing_raised { + person.errors.generate_message(:name, :blank) + } + end end -- cgit v1.2.3 From 518b30cf486164c59b7120b7b5039aa85c962630 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Mon, 17 Oct 2011 20:25:45 +1100 Subject: [engines guide] Point out that we need to run rake db:migrate after creating user model --- railties/guides/source/engines.textile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index d191fe07b6..42c99d3405 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -416,6 +416,8 @@ To keep it simple in this case, the application will have a class called +User+ rails g model user name:string +The +rake db:migrate+ command needs to be run here to ensure that our application has the +users+ table for future use. + Also to keep it simple, the posts form will have a new text field called +author_name_+ where users can elect to put their name. The engine will then take this name and create a new +User+ object from it or find one that already has that name, and then associate the post with it. First, the +author_name+ text field needs to be added to the +app/views/blorgh/posts/_form.html.erb+ partial inside the engine. This can be added above the +title+ field with this code: -- cgit v1.2.3 From cb95cca02674acf1f52d4c8f1a70fa22617e35d9 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Mon, 17 Oct 2011 20:26:37 +1100 Subject: [engines guide] missed a spot in the 'Using a class section' + further text for 'Configuring an engine' section --- railties/guides/source/engines.textile | 71 +++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 42c99d3405..6e27d823a7 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -445,11 +445,78 @@ private end
-By defining that the +author+ association's object is represented by the +User+ class a link is established between the engine and the application. Just before a post is saved it will be associated with a record from the +users+ table of the application. +By defining that the +author+ association's object is represented by the +User+ class a link is established between the engine and the application. There needs to be a way of associating the records in the +blorgh_posts+ table with the records in the +users+ table. Because the association is called +author+, there should be an +author_id+ column added to the +blorgh_posts+ table. + +To generate this new column, run this command within the engine: + + +$ rails g migration add_author_to_blorgh_posts author:references + + +NOTE: Due to the migration's name, Rails will automatically know that you want to add a column to a specific table and write that into the migration for you. You don't need to tell it any more than this. + +This migration will need to be run on the application. To do that, it must first be copied using this command: + + +$ rake blorgh:install:migrations + + +NOTE: Notice here that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. + +And then migrated using this command: + + +$ rake db:migrate + + +Now with all the pieces in place, an action will take place that will associate an author -- represented by a record in the +users+ table -- with a post, represented by the +blorgh_posts+ table from the engine. + +Finally, the author's name should be displayed on the post's page. Add this code above the "Title" output inside +app/views/blorgh/posts/show.html.erb+: + + +

+ Author: + <%= @post.author.name %> +

+
+ +NOTE: For posts created previously, this will break the +show+ page for them. We recommend deleting these posts and starting again, or manually assigning an author using +rails c+. h4. Configuring an engine -The next step is to make the class that represents a +User+ in the application customizable for the engine. This is because, as explained before, that class may not always be +User+. +The next step is to make the class that represents a +User+ in the application customizable for the engine. This is because, as explained before, that class may not always be +User+. To make this customizable, the engine will have a configuration setting called +user_class+ that will be used to specify what the class representing users is inside the application. + +To define this configuration setting, you should use a +mattr_accessor+ inside the +Blorgh+ module for the engine, located at +lib/blorgh.rb+ inside the engine. Inside this module, put this line: + + +mattr_accessor :user_class + + +This method works like its brothers +attr_accessor+ and +cattr_accessor+, but provides a setter and getter method on the module with the specified name. To use it, it must be referenced using +Blorgh.user_class+. + +The next step is switching the +Blorgh::Post+ model over to this new setting. For the +belongs_to+ association inside this model (+app/models/blorgh/post.rb+), it will now become this: + + +belongs_to :author, :class_name => Blorgh.user_class + + +The +set_author+ method also located in this class should also use this class: + + +self.author = Blorgh.user_class.constantize.find_or_create_by_name(author_name) + + +To set this configuration setting within the application, an initializer should be used. By using an initializer, the configuration will be set up before the application starts and makes references to the classes of the engine which may depend on this configuration setting existing. + +Create a new initializer at +config/initializers/blorgh.rb+ inside the application where the +blorgh+ engine is installed and put this content in it: + + +Blorgh.user_class = "User" + + +WARNING: It's very important here to use the +String+ version of the class, rather than the class itself. If you were to use the class, Rails would attempt to load that class and then reference the related table, which could lead to problems if the table wasn't already existing. Therefore, a +String+ should be used and then converted to a class using +constantize+ in the engine later on. + + h3. Overriding engine functionality -- cgit v1.2.3 From 86919a6da17e164e6bb9e1f355052e552929141e Mon Sep 17 00:00:00 2001 From: Pascal Lindelauf Date: Mon, 17 Oct 2011 14:45:45 +0200 Subject: Clarified that the config.assets.initialize_on_precompile directive needs to be set in application.rb --- railties/guides/source/asset_pipeline.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index afaf0f6fe3..6eb4ae49e3 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -349,7 +349,7 @@ bundle exec rake assets:precompile For faster asset precompiles, you can partially load your application by setting -+config.assets.initialize_on_precompile+ to false, though in that case templates ++config.assets.initialize_on_precompile+ to false in +config/application.rb+, though in that case templates cannot see application objects or methods. *Heroku requires this to be false.* WARNING: If you set +config.assets.initialize_on_precompile+ to false, be sure to -- cgit v1.2.3 From 826a85069627060c11baf932423702b1228dd4df Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Mon, 17 Oct 2011 19:14:29 +0530 Subject: fix a typo and slightly reword has_secure_password comment --- activemodel/lib/active_model/secure_password.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb index 7a109d9a52..db78864c67 100644 --- a/activemodel/lib/active_model/secure_password.rb +++ b/activemodel/lib/active_model/secure_password.rb @@ -32,8 +32,8 @@ module ActiveModel # User.find_by_name("david").try(:authenticate, "notright") # => nil # User.find_by_name("david").try(:authenticate, "mUc3m00RsqyRe") # => user def has_secure_password - # Load bcrypt-ruby only when has_secured_password is used to avoid make ActiveModel - # (and by extension the entire framework) dependent on a binary library. + # Load bcrypt-ruby only when has_secure_password is used. + # This is to avoid ActiveModel (and by extension the entire framework) being dependent on a binary library. gem 'bcrypt-ruby', '~> 3.0.0' require 'bcrypt' -- cgit v1.2.3 From 8dffc62a9b957c91575f7c014f50806e86d64505 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Mon, 17 Oct 2011 19:15:24 +0530 Subject: use variables from test setup --- activemodel/test/cases/secure_password_test.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/activemodel/test/cases/secure_password_test.rb b/activemodel/test/cases/secure_password_test.rb index 6950c3be1f..4338a3fc53 100644 --- a/activemodel/test/cases/secure_password_test.rb +++ b/activemodel/test/cases/secure_password_test.rb @@ -10,15 +10,13 @@ class SecurePasswordTest < ActiveModel::TestCase end test "blank password" do - user = User.new - user.password = '' - assert !user.valid?, 'user should be invalid' + @user.password = '' + assert !@user.valid?, 'user should be invalid' end test "nil password" do - user = User.new - user.password = nil - assert !user.valid?, 'user should be invalid' + @user.password = nil + assert !@user.valid?, 'user should be invalid' end test "password must be present" do -- cgit v1.2.3 From 8510a0bb5a8a65e4bc067ee5a7d98aae965b47a5 Mon Sep 17 00:00:00 2001 From: Aaron Christy Date: Sat, 15 Oct 2011 19:53:36 -0400 Subject: Exclude _destroy parameter in :all_blank check (issue #2937) --- activerecord/CHANGELOG | 5 +++++ activerecord/lib/active_record/nested_attributes.rb | 5 +++-- activerecord/test/cases/nested_attributes_test.rb | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 0f6a31d679..46076dac61 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -29,6 +29,11 @@ [Andrés Mejía] +* Fix nested attributes bug where _destroy parameter is taken into account + during :reject_if => :all_blank (fixes #2937) + + [Aaron Christy] + *Rails 3.1.1 (October 7, 2011)* * Add deprecation for the preload_associations method. Fixes #3022. diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index 2dbebfcaf8..d2065d701f 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -220,7 +220,7 @@ module ActiveRecord # validates_presence_of :member # end module ClassMethods - REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |_, value| value.blank? } } + REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == '_destroy' || value.blank? } } # Defines an attributes writer for the specified association(s). If you # are using attr_protected or attr_accessible, then you @@ -239,7 +239,8 @@ module ActiveRecord # is specified, a record will be built for all attribute hashes that # do not have a _destroy value that evaluates to true. # Passing :all_blank instead of a Proc will create a proc - # that will reject a record where all the attributes are blank. + # that will reject a record where all the attributes are blank excluding + # any value for _destroy. # [:limit] # Allows you to specify the maximum number of the associated records that # can be processed with the nested attributes. If the size of the diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 67a9ed6cd8..2ae9cb4888 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -45,6 +45,14 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end end + def test_should_not_build_a_new_record_using_reject_all_even_if_destroy_is_given + pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{:name => '', :color => '', :_destroy => '0'}] + pirate.save! + + assert pirate.birds_with_reject_all_blank.empty? + end + def test_should_not_build_a_new_record_if_reject_all_blank_returns_false pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") pirate.birds_with_reject_all_blank_attributes = [{:name => '', :color => ''}] -- cgit v1.2.3 From 91be318120654ad698cfb24c63194e3dfe754b4c Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Mon, 17 Oct 2011 23:13:42 +0530 Subject: Bump sprockets --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 96d583730a..062ebed4c2 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency('rack', '~> 1.3.2') s.add_dependency('rack-test', '~> 0.6.1') s.add_dependency('journey', '~> 1.0.0') - s.add_dependency('sprockets', '~> 2.0.2') + s.add_dependency('sprockets', '~> 2.0.3') s.add_dependency('erubis', '~> 2.7.0') s.add_development_dependency('tzinfo', '~> 0.3.29') -- cgit v1.2.3 From 124bb176380387b65c8643208fa50c475d8f2a49 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Tue, 18 Oct 2011 11:09:59 +0530 Subject: Bump Rack to 1.3.5 --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 96d583730a..78b9a4d5a8 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.add_dependency('rack-cache', '~> 1.1') s.add_dependency('builder', '~> 3.0.0') s.add_dependency('i18n', '~> 0.6') - s.add_dependency('rack', '~> 1.3.2') + s.add_dependency('rack', '~> 1.3.5') s.add_dependency('rack-test', '~> 0.6.1') s.add_dependency('journey', '~> 1.0.0') s.add_dependency('sprockets', '~> 2.0.2') -- cgit v1.2.3 From d21405a07ce9264ed92b9c7385141e05ccea565c Mon Sep 17 00:00:00 2001 From: "Rahul P. Chaudhari" Date: Mon, 17 Oct 2011 00:30:07 +0530 Subject: Added test case for postgresql database --- railties/test/generators/app_generator_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 133efb872f..2dcce4e884 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -143,6 +143,16 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def test_config_postgresql_database + run_generator([destination_root, "-d", "postgresql"]) + assert_file "config/database.yml", /postgresql/ + unless defined?(JRUBY_VERSION) + assert_file "Gemfile", /^gem\s+["']pg["']$/ + else + assert_file "Gemfile", /^gem\s+["']activerecord-jdbcpostgresql-adapter["']$/ + end + end + def test_config_jdbcmysql_database run_generator([destination_root, "-d", "jdbcmysql"]) assert_file "config/database.yml", /mysql/ -- cgit v1.2.3 From c547e968f5709f174ee13818b35429cbe585b5dd Mon Sep 17 00:00:00 2001 From: Steven Anderson Date: Mon, 17 Oct 2011 16:28:00 +0100 Subject: Added environment rake task to engines --- railties/lib/rails/tasks/engine.rake | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/lib/rails/tasks/engine.rake b/railties/lib/rails/tasks/engine.rake index 2152e811f5..eea8abe7d2 100644 --- a/railties/lib/rails/tasks/engine.rake +++ b/railties/lib/rails/tasks/engine.rake @@ -2,6 +2,7 @@ task "load_app" do namespace :app do load APP_RAKEFILE end + task :environment => "app:environment" if !defined?(ENGINE_PATH) || !ENGINE_PATH ENGINE_PATH = find_engine_path(APP_RAKEFILE) -- cgit v1.2.3 From 40d1555091433d827e23e92e9f816e11a2db679b Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 18 Oct 2011 17:06:32 +0100 Subject: Added test for rake environment in an engine --- railties/test/railties/shared_tests.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb index 21fde49ff7..7653e52d26 100644 --- a/railties/test/railties/shared_tests.rb +++ b/railties/test/railties/shared_tests.rb @@ -21,6 +21,23 @@ module RailtiesTest assert_match "alert()", last_response.body end + def test_rake_environment_can_be_called_in_the_engine_or_plugin + boot_rails + + @plugin.write "Rakefile", <<-RUBY + APP_RAKEFILE = '#{app_path}/Rakefile' + load 'rails/tasks/engine.rake' + task :foo => :environment do + puts "Task ran" + end + RUBY + + Dir.chdir(@plugin.path) do + output = `bundle exec rake foo` + assert_match "Task ran", output + end + end + def test_copying_migrations @plugin.write "db/migrate/1_create_users.rb", <<-RUBY class CreateUsers < ActiveRecord::Migration -- cgit v1.2.3 From 76af2818a6b729955ad799b5346da7ed115440ea Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 18 Oct 2011 10:07:40 -0700 Subject: use now() for dates in pg --- activerecord/test/cases/migration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 4b5dd18be8..6ce7ae7877 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -475,7 +475,7 @@ if ActiveRecord::Base.connection.supports_migrations? elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings Person.connection.execute "insert into people (wealth, created_at, updated_at) values ('12345678901234567890.0123456789', 0, 0)" else - Person.connection.execute "insert into people (wealth, created_at, updated_at) values (12345678901234567890.0123456789, 0, 0)" + Person.connection.execute "insert into people (wealth, created_at, updated_at) values (12345678901234567890.0123456789, now(), now())" end # SELECT -- cgit v1.2.3 From 7f184aaf4352140c7e3bd33761058bb05737e11b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 18 Oct 2011 16:03:58 -0200 Subject: Use again Rack's ContentLength middleware --- railties/lib/rails/commands/server.rb | 1 - railties/lib/rails/rack.rb | 1 - railties/lib/rails/rack/content_length.rb | 38 ------------------------------- 3 files changed, 40 deletions(-) delete mode 100644 railties/lib/rails/rack/content_length.rb diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 23392276d5..71e3711ba1 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -78,7 +78,6 @@ module Rails middlewares = [] middlewares << [Rails::Rack::LogTailer, log_path] unless options[:daemonize] middlewares << [Rails::Rack::Debugger] if options[:debugger] - middlewares << [Rails::Rack::ContentLength] Hash.new(middlewares) end diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb index d4a41b217e..d1ee96f7fd 100644 --- a/railties/lib/rails/rack.rb +++ b/railties/lib/rails/rack.rb @@ -1,6 +1,5 @@ module Rails module Rack - autoload :ContentLength, "rails/rack/content_length" autoload :Debugger, "rails/rack/debugger" autoload :Logger, "rails/rack/logger" autoload :LogTailer, "rails/rack/log_tailer" diff --git a/railties/lib/rails/rack/content_length.rb b/railties/lib/rails/rack/content_length.rb deleted file mode 100644 index 6839af4152..0000000000 --- a/railties/lib/rails/rack/content_length.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'action_dispatch' -require 'rack/utils' - -module Rails - module Rack - # Sets the Content-Length header on responses with fixed-length bodies. - class ContentLength - include ::Rack::Utils - - def initialize(app, sendfile=nil) - @app = app - @sendfile = sendfile - end - - def call(env) - status, headers, body = @app.call(env) - headers = HeaderHash.new(headers) - - if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) && - !headers['Content-Length'] && - !headers['Transfer-Encoding'] && - !(@sendfile && headers[@sendfile]) - - old_body = body - body, length = [], 0 - old_body.each do |part| - body << part - length += bytesize(part) - end - old_body.close if old_body.respond_to?(:close) - headers['Content-Length'] = length.to_s - end - - [status, headers, body] - end - end - end -end \ No newline at end of file -- cgit v1.2.3 From d44702c830669e2647c073133bd6b09d7016424d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 18 Oct 2011 16:14:38 -0200 Subject: Use again Rack's ContentLength middleware part 2 --- railties/lib/rails/commands/server.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 71e3711ba1..33f9ac017c 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -78,6 +78,7 @@ module Rails middlewares = [] middlewares << [Rails::Rack::LogTailer, log_path] unless options[:daemonize] middlewares << [Rails::Rack::Debugger] if options[:debugger] + middlewares << [Rack::ContentLength] Hash.new(middlewares) end -- cgit v1.2.3 From 6a28c512e358a95bbabd24af9d2b0608df787158 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 18 Oct 2011 11:12:18 -0700 Subject: reset prepared statement when schema changes imapact statement results. fixes #3335 --- .../connection_adapters/postgresql_adapter.rb | 54 +++++++++++++++++----- .../test/cases/adapters/postgresql/schema_test.rb | 8 ++++ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index d859843260..b7f346e050 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -278,6 +278,11 @@ module ActiveRecord cache.clear end + def delete(sql_key) + dealloc cache[sql_key] + cache.delete sql_key + end + private def cache @cache[$$] @@ -1030,27 +1035,54 @@ module ActiveRecord end private + FEATURE_NOT_SUPPORTED = "0A000" # :nodoc: + def exec_no_cache(sql, binds) @connection.async_exec(sql) end def exec_cache(sql, binds) - sql_key = "#{schema_search_path}-#{sql}" + begin + stmt_key = prepare_statement sql + + # Clear the queue + @connection.get_last_result + @connection.send_query_prepared(stmt_key, binds.map { |col, val| + type_cast(val, col) + }) + @connection.block + @connection.get_last_result + rescue PGError => e + # Get the PG code for the failure. Annoyingly, the code for + # prepared statements whose return value may have changed is + # FEATURE_NOT_SUPPORTED. Check here for more details: + # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573 + code = e.result.result_error_field(PGresult::PG_DIAG_SQLSTATE) + if FEATURE_NOT_SUPPORTED == code + @statements.delete sql_key(sql) + retry + else + raise e + end + end + end + + # Returns the statement identifier for the client side cache + # of statements + def sql_key(sql) + "#{schema_search_path}-#{sql}" + end + + # Prepare the statement if it hasn't been prepared, return + # the statement key. + def prepare_statement(sql) + sql_key = sql_key(sql) unless @statements.key? sql_key nextkey = @statements.next_key @connection.prepare nextkey, sql @statements[sql_key] = nextkey end - - key = @statements[sql_key] - - # Clear the queue - @connection.get_last_result - @connection.send_query_prepared(key, binds.map { |col, val| - type_cast(val, col) - }) - @connection.block - @connection.get_last_result + @statements[sql_key] end # The internal PostgreSQL identifier of the money data type. diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index b01eabc840..c8f8714f66 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -62,6 +62,14 @@ class SchemaTest < ActiveRecord::TestCase @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" end + def test_schema_change_with_prepared_stmt + @connection.exec_query "select * from developers where id = $1", 'sql', [[nil, 1]] + @connection.exec_query "alter table developers add column zomg int", 'sql', [] + @connection.exec_query "select * from developers where id = $1", 'sql', [[nil, 1]] + ensure + @connection.exec_query "alter table developers drop column if exists zomg", 'sql', [] + end + def test_table_exists? [Thing1, Thing2, Thing3, Thing4].each do |klass| name = klass.table_name -- cgit v1.2.3 From bed5825f775bdf2a1af6eec9dc1f4071dbde5ead Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Tue, 18 Oct 2011 22:57:55 +0400 Subject: Remove superfluous assignment in cookies --- actionpack/lib/action_dispatch/middleware/cookies.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 8c4615c0c1..a4ffd40a66 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -174,7 +174,7 @@ module ActionDispatch options = { :value => value } end - value = @cookies[key.to_s] = value + @cookies[key.to_s] = value handle_options(options) -- cgit v1.2.3 From c2f3c9bf56534f8f50b4e47a7e18e822f6600bbe Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 18 Oct 2011 13:30:01 -0700 Subject: only use now() on pg! --- activerecord/test/cases/migration_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 6ce7ae7877..b3f1785f44 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -474,8 +474,10 @@ if ActiveRecord::Base.connection.supports_migrations? Person.connection.execute "insert into people (id, wealth, created_at, updated_at) values (people_seq.nextval, 12345678901234567890.0123456789, 0, 0)" elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings Person.connection.execute "insert into people (wealth, created_at, updated_at) values ('12345678901234567890.0123456789', 0, 0)" - else + elsif current_adapter?(:PostgreSQLAdapter) Person.connection.execute "insert into people (wealth, created_at, updated_at) values (12345678901234567890.0123456789, now(), now())" + else + Person.connection.execute "insert into people (wealth, created_at, updated_at) values (12345678901234567890.0123456789, 0, 0)" end # SELECT -- cgit v1.2.3 From 044e6ac245c24b91f7f815e2155bb7ac030ce831 Mon Sep 17 00:00:00 2001 From: Andy Lindeman Date: Tue, 18 Oct 2011 23:45:56 -0300 Subject: Fixes the defaults for config.cache_classes --- railties/guides/source/configuring.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index baf944cf8d..58b92e7f9e 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -64,7 +64,7 @@ NOTE. The +config.asset_path+ configuration is ignored if the asset pipeline is * +config.autoload_paths+ accepts an array of paths from which Rails will autoload constants. Default is all directories under +app+. -* +config.cache_classes+ controls whether or not application classes and modules should be reloaded on each request. Defaults to true in development mode, and false in test and production modes. Can also be enabled with +threadsafe!+. +* +config.cache_classes+ controls whether or not application classes and modules should be reloaded on each request. Defaults to false in development mode, and true in test and production modes. Can also be enabled with +threadsafe!+. * +config.action_view.cache_template_loading+ controls whether or not templates should be reloaded on each request. Defaults to whatever is set for +config.cache_classes+. -- cgit v1.2.3 From 3a746f7c48936bac1c08dcf229c7c8fc74fdfc13 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 19 Oct 2011 12:31:06 -0500 Subject: Use toplevel Rack::ContentLength --- railties/lib/rails/commands/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 33f9ac017c..20484a10c8 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -78,7 +78,7 @@ module Rails middlewares = [] middlewares << [Rails::Rack::LogTailer, log_path] unless options[:daemonize] middlewares << [Rails::Rack::Debugger] if options[:debugger] - middlewares << [Rack::ContentLength] + middlewares << [::Rack::ContentLength] Hash.new(middlewares) end -- cgit v1.2.3 From afde6fdd5ef3e6b0693a7e330777e85ef4cffddb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 12:59:33 -0500 Subject: Added X-Request-Id tracking and TaggedLogging to easily log that and other production concerns --- actionpack/CHANGELOG | 2 + actionpack/lib/action_dispatch.rb | 1 + actionpack/lib/action_dispatch/http/request.rb | 10 ++++ .../lib/action_dispatch/middleware/request_id.rb | 38 ++++++++++++ actionpack/test/dispatch/request_id_test.rb | 59 +++++++++++++++++++ activesupport/CHANGELOG | 7 +++ activesupport/lib/active_support.rb | 1 + activesupport/lib/active_support/tagged_logging.rb | 68 ++++++++++++++++++++++ activesupport/test/tagged_logging_test.rb | 34 +++++++++++ railties/CHANGELOG | 2 + .../config/environments/production.rb | 3 + railties/lib/rails/application.rb | 2 + railties/lib/rails/application/bootstrap.rb | 4 +- railties/lib/rails/application/configuration.rb | 2 +- railties/lib/rails/rack.rb | 1 + railties/lib/rails/rack/logger.rb | 4 +- railties/lib/rails/rack/tagged_logging.rb | 39 +++++++++++++ 17 files changed, 272 insertions(+), 5 deletions(-) create mode 100644 actionpack/lib/action_dispatch/middleware/request_id.rb create mode 100644 actionpack/test/dispatch/request_id_test.rb create mode 100644 activesupport/lib/active_support/tagged_logging.rb create mode 100644 activesupport/test/tagged_logging_test.rb create mode 100644 railties/lib/rails/rack/tagged_logging.rb diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 29992a36b1..e7886facb9 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.2.0 (unreleased)* +* Added ActionDispatch::RequestId middleware that'll make a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog [DHH] + * Limit the number of options for select_year to 1000. Pass the :max_years_allowed option to set your own limit. diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 7f972fc281..c13850f378 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -47,6 +47,7 @@ module ActionDispatch end autoload_under 'middleware' do + autoload :RequestId autoload :BestStandardsSupport autoload :Callbacks autoload :Cookies diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 37d0a3e0b8..7a5237dcf3 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -177,6 +177,16 @@ module ActionDispatch @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s end + # Returns the unique request id, which is based off either the X-Request-Id header that can + # be generated by a firewall, load balancer, or web server or by the RequestId middleware + # (which sets the action_dispatch.request_id environment variable). + # + # This unique ID is useful for tracing a request from end-to-end as part of logging or debugging. + # This relies on the rack variable set by the ActionDispatch::RequestId middleware. + def uuid + @uuid ||= env["action_dispatch.request_id"] + end + # Returns the lowercase name of the HTTP server software. def server_software (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb new file mode 100644 index 0000000000..968ad6c28d --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -0,0 +1,38 @@ +require 'digest/md5' + +module ActionDispatch + # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through + # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header. + # + # The unique request id is either based off the X-Request-Id header in the request, which would typically be generated + # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the + # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only. + # + # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files + # from multiple pieces of the stack. + class RequestId + def initialize(app) + @app = app + end + + def call(env) + env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id + + status, headers, body = @app.call(env) + + headers["X-Request-Id"] = env["action_dispatch.request_id"] + [ status, headers, body ] + end + + private + def external_request_id(env) + if env["HTTP_X_REQUEST_ID"].present? + env["HTTP_X_REQUEST_ID"].gsub(/[^\w\d\-]/, "").first(255) + end + end + + def internal_request_id + SecureRandom.uuid + end + end +end diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb new file mode 100644 index 0000000000..bdadbf6644 --- /dev/null +++ b/actionpack/test/dispatch/request_id_test.rb @@ -0,0 +1,59 @@ +require 'abstract_unit' + +class RequestIdTest < ActiveSupport::TestCase + test "passing on the request id from the outside" do + assert_equal "external-uu-rid", stub_request('HTTP_X_REQUEST_ID' => 'external-uu-rid').uuid + end + + test "ensure that only alphanumeric uurids are accepted" do + assert_equal "X-Hacked-HeaderStuff", stub_request('HTTP_X_REQUEST_ID' => '; X-Hacked-Header: Stuff').uuid + end + + test "ensure that 255 char limit on the request id is being enforced" do + assert_equal "X" * 255, stub_request('HTTP_X_REQUEST_ID' => 'X' * 500).uuid + end + + test "generating a request id when none is supplied" do + assert_match /\w+-\w+-\w+-\w+-\w+/, stub_request.uuid + end + + private + def stub_request(env = {}) + ActionDispatch::RequestId.new(->(env) { [ 200, env, [] ] }).call(env) + ActionDispatch::Request.new(env) + end +end + +# FIXME: Testing end-to-end doesn't seem to work +# +# class RequestIdResponseTest < ActionDispatch::IntegrationTest +# class TestController < ActionController::Base +# def index +# head :ok +# end +# end +# +# test "request id is passed all the way to the response" do +# with_test_route_set do +# get '/' +# puts @response.headers.inspect +# assert_equal "internal-uu-rid", @response.headers["X-Request-Id"] +# end +# end +# +# +# private +# def with_test_route_set +# with_routing do |set| +# set.draw do +# match ':action', to: ::RequestIdResponseTest::TestController +# end +# +# @app = self.class.build_app(set) do |middleware| +# middleware.use ActionDispatch::RequestId +# end +# +# yield +# end +# end +# end \ No newline at end of file diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 63f406cd9f..d3a838cff0 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,12 @@ *Rails 3.2.0 (unreleased)* +* Added ActiveSupport:TaggedLogging that can wrap any standard Logger class to provide tagging capabilities [DHH] + + Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) + Logger.tagged("BCX") { Logger.info "Stuff" } # Logs "[BCX] Stuff" + Logger.tagged("BCX", "Jason") { Logger.info "Stuff" } # Logs "[BCX] [Jason] Stuff" + Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff" + * Added safe_constantize that constantizes a string but returns nil instead of an exception if the constant (or part of it) does not exist [Ryan Oblak] * ActiveSupport::OrderedHash is now marked as extractable when using Array#extract_options! [Prem Sichanugrist] diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index cc9ea5cffa..ff78e718f2 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -71,6 +71,7 @@ module ActiveSupport autoload :OrderedOptions autoload :Rescuable autoload :StringInquirer + autoload :TaggedLogging autoload :XmlMini end diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb new file mode 100644 index 0000000000..0d8504bc1f --- /dev/null +++ b/activesupport/lib/active_support/tagged_logging.rb @@ -0,0 +1,68 @@ +module ActiveSupport + # Wraps any standard Logger class to provide tagging capabilities. Examples: + # + # Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) + # Logger.tagged("BCX") { Logger.info "Stuff" } # Logs "[BCX] Stuff" + # Logger.tagged("BCX", "Jason") { Logger.info "Stuff" } # Logs "[BCX] [Jason] Stuff" + # Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff" + # + # This is used by the default Rails.logger as configured by Railties to make it easy to stamp log lines + # with subdomains, request ids, and anything else to aid debugging of multi-user production applications. + class TaggedLogging + def initialize(logger) + @logger = logger + @tags = [] + end + + def tagged(*tags) + new_tags = Array.wrap(tags).flatten + @tags += new_tags + yield + ensure + new_tags.size.times { @tags.pop } + end + + + def add(severity, message = nil, progname = nil, &block) + @logger.add(severity, "#{tags}#{message}", progname, &block) + end + + + def fatal(progname = nil, &block) + add(@logger.class::FATAL, progname, &block) + end + + def error(progname = nil, &block) + add(@logger.class::ERROR, progname, &block) + end + + def warn(progname = nil, &block) + add(@logger.class::WARN, progname, &block) + end + + def info(progname = nil, &block) + add(@logger.class::INFO, progname, &block) + end + + def debug(progname = nil, &block) + add(@logger.class::DEBUG, progname, &block) + end + + def unknown(progname = nil, &block) + add(@logger.class::UNKNOWN, progname, &block) + end + + + def method_missing(method, *args) + @logger.send(method, *args) + end + + + private + def tags + if @tags.any? + @tags.collect { |tag| "[#{tag}]" }.join(" ") + " " + end + end + end +end diff --git a/activesupport/test/tagged_logging_test.rb b/activesupport/test/tagged_logging_test.rb new file mode 100644 index 0000000000..a1504c6ce4 --- /dev/null +++ b/activesupport/test/tagged_logging_test.rb @@ -0,0 +1,34 @@ +require 'abstract_unit' +require 'active_support/core_ext/logger' +require 'active_support/tagged_logging' + +class TaggedLoggingTest < ActiveSupport::TestCase + setup do + @output = StringIO.new + @logger = ActiveSupport::TaggedLogging.new(Logger.new(@output)) + end + + test "tagged once" do + @logger.tagged("BCX") { @logger.info "Funky time" } + assert_equal "[BCX] Funky time\n", @output.string + end + + test "tagged twice" do + @logger.tagged("BCX") { @logger.tagged("Jason") { @logger.info "Funky time" } } + assert_equal "[BCX] [Jason] Funky time\n", @output.string + end + + test "tagged thrice at once" do + @logger.tagged("BCX", "Jason", "New") { @logger.info "Funky time" } + assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string + end + + test "mixed levels of tagging" do + @logger.tagged("BCX") do + @logger.tagged("Jason") { @logger.info "Funky time" } + @logger.info "Junky time!" + end + + assert_equal "[BCX] [Jason] Funky time\n[BCX] Junky time!\n", @output.string + end +end diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 187dd2428f..181019f851 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.2.0 (unreleased)* +* Added Rails::Rack::TaggedLogging middleware by default that will apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications [DHH] + * Default options to `rails new` can be set in ~/.railsrc [Guillermo Iguaran] * Added destroy alias to Rails engines. [Guillermo Iguaran] diff --git a/railties/guides/code/getting_started/config/environments/production.rb b/railties/guides/code/getting_started/config/environments/production.rb index 6ab63d30a6..4618191d6b 100644 --- a/railties/guides/code/getting_started/config/environments/production.rb +++ b/railties/guides/code/getting_started/config/environments/production.rb @@ -33,6 +33,9 @@ Blog::Application.configure do # See everything in the log (default is :info) # config.log_level = :debug + # Prepend all log lines with the following tags + # config.log_tags = [ :subdomain, :uuid ] + # Use a different logger for distributed setups # config.logger = SyslogLogger.new diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index cbb2d23238..a097cfd1be 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -164,6 +164,8 @@ module Rails middleware.use ::Rack::Lock unless config.allow_concurrency middleware.use ::Rack::Runtime middleware.use ::Rack::MethodOverride + middleware.use ::ActionDispatch::RequestId + middleware.use ::Rails::Rack::TaggedLogging, config.log_tags middleware.use ::Rails::Rack::Logger # must come after Rack::MethodOverride to properly log overridden methods middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index 0aff05b681..c2cb121e42 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -24,12 +24,12 @@ module Rails initializer :initialize_logger, :group => :all do Rails.logger ||= config.logger || begin path = config.paths["log"].first - logger = ActiveSupport::BufferedLogger.new(path) + logger = ActiveSupport::TaggedLogging.new(ActiveSupport::BufferedLogger.new(path)) logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase) logger.auto_flushing = false if Rails.env.production? logger rescue StandardError - logger = ActiveSupport::BufferedLogger.new(STDERR) + logger = ActiveSupport::TaggedLogging.new(ActiveSupport::BufferedLogger.new(STDERR)) logger.level = ActiveSupport::BufferedLogger::WARN logger.warn( "Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " + diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 448521d2f0..8f5b28faf8 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -8,7 +8,7 @@ module Rails attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets, :cache_classes, :cache_store, :consider_all_requests_local, :dependency_loading, :filter_parameters, - :force_ssl, :helpers_paths, :logger, :preload_frameworks, + :force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :ssl_options, :static_cache_control, :session_options, :time_zone, :whiny_nils diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb index d1ee96f7fd..b78293e570 100644 --- a/railties/lib/rails/rack.rb +++ b/railties/lib/rails/rack.rb @@ -3,5 +3,6 @@ module Rails autoload :Debugger, "rails/rack/debugger" autoload :Logger, "rails/rack/logger" autoload :LogTailer, "rails/rack/log_tailer" + autoload :TaggedLogging, "rails/rack/tagged_logging" end end diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb index 3be262de08..4d388c4d10 100644 --- a/railties/lib/rails/rack/logger.rb +++ b/railties/lib/rails/rack/logger.rb @@ -21,8 +21,8 @@ module Rails request = ActionDispatch::Request.new(env) path = request.filtered_path - info "\n\nStarted #{request.request_method} \"#{path}\" " \ - "for #{request.ip} at #{Time.now.to_default_s}" + info "\n\n" + info "Started #{request.request_method} \"#{path}\" for #{request.ip} at #{Time.now.to_default_s}" end def after_dispatch(env) diff --git a/railties/lib/rails/rack/tagged_logging.rb b/railties/lib/rails/rack/tagged_logging.rb new file mode 100644 index 0000000000..7980319b37 --- /dev/null +++ b/railties/lib/rails/rack/tagged_logging.rb @@ -0,0 +1,39 @@ +module Rails + module Rack + # Enables easy tagging of any logging activity that occurs within the Rails request cycle. The tags are configured via the + # config.log_tags setting. The tags can either be strings, procs taking a request argument, or the symbols :uuid or :subdomain. + # The latter two are then automatically expanded to request.uuid and request.subdaomins.first -- the two most common tags + # desired in production logs. + class TaggedLogging + def initialize(app, tags = nil) + @app, @tags = app, tags + end + + def call(env) + if @tags + Rails.logger.tagged(compute_tags(env)) { @app.call(env) } + else + @app.call(env) + end + end + + private + def compute_tags(env) + request = ActionDispatch::Request.new(env) + + @tags.collect do |tag| + case tag + when Proc + tag.call(request) + when :uuid + request.uuid + when :subdomain + request.subdomains.first + else + tag + end + end + end + end + end +end -- cgit v1.2.3 From 4a4927f753d7f41c0903ab3adfb73be8490c382e Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 13:24:28 -0500 Subject: Simplify TaggedLogging symbol shortcuts (thanks Jose!) --- railties/lib/rails/rack/tagged_logging.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/railties/lib/rails/rack/tagged_logging.rb b/railties/lib/rails/rack/tagged_logging.rb index 7980319b37..c519d7c3e6 100644 --- a/railties/lib/rails/rack/tagged_logging.rb +++ b/railties/lib/rails/rack/tagged_logging.rb @@ -1,9 +1,8 @@ module Rails module Rack # Enables easy tagging of any logging activity that occurs within the Rails request cycle. The tags are configured via the - # config.log_tags setting. The tags can either be strings, procs taking a request argument, or the symbols :uuid or :subdomain. - # The latter two are then automatically expanded to request.uuid and request.subdaomins.first -- the two most common tags - # desired in production logs. + # config.log_tags setting. The tags can either be strings, procs taking a request argument, or symbols representing method + # names on request (so :uuid will result in request.uuid being added as a tag). class TaggedLogging def initialize(app, tags = nil) @app, @tags = app, tags @@ -25,10 +24,8 @@ module Rails case tag when Proc tag.call(request) - when :uuid - request.uuid - when :subdomain - request.subdomains.first + when Symbol + request.send(tag) else tag end -- cgit v1.2.3 From ddbb2cae3146fc125375a0aae61bbaca9328b797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:15:25 +0300 Subject: Require securerandom as it is the proper dependency. --- actionpack/lib/action_dispatch/middleware/request_id.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index 968ad6c28d..c515798d48 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -1,4 +1,4 @@ -require 'digest/md5' +require 'securerandom' module ActionDispatch # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through -- cgit v1.2.3 From 1b50207ed3a2f545763b8c0b3afcd35d9d36d4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:17:54 +0300 Subject: Require missing string access dependency. --- actionpack/lib/action_dispatch/middleware/request_id.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index c515798d48..cdddc55aae 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -1,4 +1,5 @@ require 'securerandom' +require 'active_support/core_ext/string/access' module ActionDispatch # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through -- cgit v1.2.3 From c9ca86c29d4f4d8e1181c20ac0da8e1027a14344 Mon Sep 17 00:00:00 2001 From: Martin Svalin Date: Wed, 19 Oct 2011 18:47:28 +0200 Subject: New #added? method on ActiveModel::Errors The #added? method makes it possible to check if a specific error has been added, using the same parameters as for #add. --- activemodel/CHANGELOG | 2 ++ activemodel/lib/active_model/errors.rb | 30 ++++++++++++++++++------ activemodel/test/cases/errors_test.rb | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/activemodel/CHANGELOG b/activemodel/CHANGELOG index 3d26d646b0..bf077bef35 100644 --- a/activemodel/CHANGELOG +++ b/activemodel/CHANGELOG @@ -1,3 +1,5 @@ +* Added ActiveModel::Errors#added? to check if a specific error has been added [Martin Svalin] + * Add ability to define strict validation(with :strict => true option) that always raises exception when fails [Bogdan Gusiev] * Deprecate "Model.model_name.partial_path" in favor of "model.to_partial_path" [Grant Hutchins, Peter Jaros] diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index f90030641d..6aa0d2a16f 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -213,13 +213,7 @@ module ActiveModel # If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_error+). # If +message+ is a proc, it will be called, allowing for things like Time.now to be used within an error. def add(attribute, message = nil, options = {}) - message ||= :invalid - - if message.is_a?(Symbol) - message = generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) - elsif message.is_a?(Proc) - message = message.call - end + message = normalize_message(attribute, message, options) if options[:strict] raise ActiveModel::StrictValidationFailed, message end @@ -244,6 +238,15 @@ module ActiveModel end end + # Returns true if an error on the attribute with the given message is present, false otherwise. + # +message+ is treated the same as for +add+. + # p.errors.add :name, :blank + # p.errors.added? :name, :blank # => true + def added?(attribute, message = nil, options = {}) + message = normalize_message(attribute, message, options) + self[attribute].include? message + end + # Returns all the full error messages in an array. # # class Company @@ -329,6 +332,19 @@ module ActiveModel I18n.translate(key, options) end + + private + def normalize_message(attribute, message, options) + message ||= :invalid + + if message.is_a?(Symbol) + generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS)) + elsif message.is_a?(Proc) + message.call + else + message + end + end end class StrictValidationFailed < StandardError diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 784a2b2709..8ddedb160a 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -80,6 +80,49 @@ class ErrorsTest < ActiveModel::TestCase assert_equal ["can not be blank"], person.errors[:name] end + test "added? should be true if that error was added" do + person = Person.new + person.errors.add(:name, "can not be blank") + assert person.errors.added?(:name, "can not be blank") + end + + test "added? should handle when message is a symbol" do + person = Person.new + person.errors.add(:name, :blank) + assert person.errors.added?(:name, :blank) + end + + test "added? should handle when message is a proc" do + person = Person.new + message = Proc.new { "can not be blank" } + person.errors.add(:name, message) + assert person.errors.added?(:name, message) + end + + test "added? should default message to :invalid" do + person = Person.new + person.errors.add(:name, :invalid) + assert person.errors.added?(:name) + end + + test "added? should be true when several errors are present, and we ask for one of them" do + person = Person.new + person.errors.add(:name, "can not be blank") + person.errors.add(:name, "is invalid") + assert person.errors.added?(:name, "can not be blank") + end + + test "added? should be false if no errors are present" do + person = Person.new + assert !person.errors.added?(:name) + end + + test "added? should be false when an error is present, but we check for another error" do + person = Person.new + person.errors.add(:name, "is invalid") + assert !person.errors.added?(:name, "can not be blank") + end + test 'should respond to size' do person = Person.new person.errors.add(:name, "can not be blank") -- cgit v1.2.3 From ada78066fdbccffb1da092a2470211fa252b3c99 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 14:45:42 -0500 Subject: Blah, SecureRandom#uuid is not supported in 1.8.7 -- cant wait for Rails 4.0 to drop compatibility with 1.8.x --- actionpack/lib/action_dispatch/middleware/request_id.rb | 2 +- actionpack/test/dispatch/request_id_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index cdddc55aae..4728e9f71e 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -33,7 +33,7 @@ module ActionDispatch end def internal_request_id - SecureRandom.uuid + SecureRandom.hex(16) end end end diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb index bdadbf6644..230ff54889 100644 --- a/actionpack/test/dispatch/request_id_test.rb +++ b/actionpack/test/dispatch/request_id_test.rb @@ -14,7 +14,7 @@ class RequestIdTest < ActiveSupport::TestCase end test "generating a request id when none is supplied" do - assert_match /\w+-\w+-\w+-\w+-\w+/, stub_request.uuid + assert_match /\w+/, stub_request.uuid end private -- cgit v1.2.3 From 18dbfcb36369ebb800a22325f689ff4cf27ef467 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 14:53:34 -0500 Subject: Programatically define the log level methods and use the Logger constants instead (SyslogLogger didnt define them as I expected) --- activesupport/lib/active_support/tagged_logging.rb | 31 ++++++---------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb index 0d8504bc1f..0cabb528ef 100644 --- a/activesupport/lib/active_support/tagged_logging.rb +++ b/activesupport/lib/active_support/tagged_logging.rb @@ -1,3 +1,5 @@ +require 'logger' + module ActiveSupport # Wraps any standard Logger class to provide tagging capabilities. Examples: # @@ -27,29 +29,12 @@ module ActiveSupport @logger.add(severity, "#{tags}#{message}", progname, &block) end - - def fatal(progname = nil, &block) - add(@logger.class::FATAL, progname, &block) - end - - def error(progname = nil, &block) - add(@logger.class::ERROR, progname, &block) - end - - def warn(progname = nil, &block) - add(@logger.class::WARN, progname, &block) - end - - def info(progname = nil, &block) - add(@logger.class::INFO, progname, &block) - end - - def debug(progname = nil, &block) - add(@logger.class::DEBUG, progname, &block) - end - - def unknown(progname = nil, &block) - add(@logger.class::UNKNOWN, progname, &block) + %w( fatal error warn info debug unkown ).each do |severity| + eval <<-EOM, nil, __FILE__, __LINE__ + 1 + def #{severity}(progname = nil, &block) + add(Logger::#{severity.upcase}, progname, &block) + end + EOM end -- cgit v1.2.3 From 5bc23e4fb503e038c8e24a3a58d4eb1c323e94c8 Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Wed, 19 Oct 2011 15:56:25 -0400 Subject: Fix ORA-00932 error when trying to insert 0 to DATE type columns. --- activerecord/test/cases/migration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index b3f1785f44..47ab5d5f9d 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -471,7 +471,7 @@ if ActiveRecord::Base.connection.supports_migrations? # Do a manual insertion if current_adapter?(:OracleAdapter) - Person.connection.execute "insert into people (id, wealth, created_at, updated_at) values (people_seq.nextval, 12345678901234567890.0123456789, 0, 0)" + Person.connection.execute "insert into people (id, wealth, created_at, updated_at) values (people_seq.nextval, 12345678901234567890.0123456789, sysdate, sysdate)" elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings Person.connection.execute "insert into people (wealth, created_at, updated_at) values ('12345678901234567890.0123456789', 0, 0)" elsif current_adapter?(:PostgreSQLAdapter) -- cgit v1.2.3 From f1fecd9b4e38c289b678bc2aadb406265963c528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:09:36 +0200 Subject: Make tests run on 1.8.x, add integration setup. --- .../lib/action_dispatch/middleware/request_id.rb | 5 +- actionpack/test/dispatch/request_id_test.rb | 84 ++++++++++++---------- 2 files changed, 47 insertions(+), 42 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index 4728e9f71e..f4d721f9bf 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -18,20 +18,19 @@ module ActionDispatch def call(env) env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id - status, headers, body = @app.call(env) headers["X-Request-Id"] = env["action_dispatch.request_id"] [ status, headers, body ] end - + private def external_request_id(env) if env["HTTP_X_REQUEST_ID"].present? env["HTTP_X_REQUEST_ID"].gsub(/[^\w\d\-]/, "").first(255) end end - + def internal_request_id SecureRandom.hex(16) end diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb index 230ff54889..ece8353810 100644 --- a/actionpack/test/dispatch/request_id_test.rb +++ b/actionpack/test/dispatch/request_id_test.rb @@ -8,52 +8,58 @@ class RequestIdTest < ActiveSupport::TestCase test "ensure that only alphanumeric uurids are accepted" do assert_equal "X-Hacked-HeaderStuff", stub_request('HTTP_X_REQUEST_ID' => '; X-Hacked-Header: Stuff').uuid end - + test "ensure that 255 char limit on the request id is being enforced" do assert_equal "X" * 255, stub_request('HTTP_X_REQUEST_ID' => 'X' * 500).uuid end - + test "generating a request id when none is supplied" do assert_match /\w+/, stub_request.uuid end private - def stub_request(env = {}) - ActionDispatch::RequestId.new(->(env) { [ 200, env, [] ] }).call(env) - ActionDispatch::Request.new(env) - end + + def stub_request(env = {}) + ActionDispatch::RequestId.new(lambda { |env| [ 200, env, [] ] }).call(env) + ActionDispatch::Request.new(env) + end end -# FIXME: Testing end-to-end doesn't seem to work -# -# class RequestIdResponseTest < ActionDispatch::IntegrationTest -# class TestController < ActionController::Base -# def index -# head :ok -# end -# end -# -# test "request id is passed all the way to the response" do -# with_test_route_set do -# get '/' -# puts @response.headers.inspect -# assert_equal "internal-uu-rid", @response.headers["X-Request-Id"] -# end -# end -# -# -# private -# def with_test_route_set -# with_routing do |set| -# set.draw do -# match ':action', to: ::RequestIdResponseTest::TestController -# end -# -# @app = self.class.build_app(set) do |middleware| -# middleware.use ActionDispatch::RequestId -# end -# -# yield -# end -# end -# end \ No newline at end of file +class RequestIdResponseTest < ActionDispatch::IntegrationTest + class TestController < ActionController::Base + def index + head :ok + end + end + + test "request id is passed all the way to the response" do + with_test_route_set do + get '/' + assert_match(/\w+/, @response.headers["X-Request-Id"]) + end + end + + test "request id given on request is passed all the way to the response" do + with_test_route_set do + get '/', {}, 'HTTP_X_REQUEST_ID' => 'X' * 500 + assert_equal "X" * 255, @response.headers["X-Request-Id"] + end + end + + + private + + def with_test_route_set + with_routing do |set| + set.draw do + match '/', :to => ::RequestIdResponseTest::TestController.action(:index) + end + + @app = self.class.build_app(set) do |middleware| + middleware.use ActionDispatch::RequestId + end + + yield + end + end +end \ No newline at end of file -- cgit v1.2.3 From 4ef74536940ea4c8c7f8c2cb0252bfe5f0db6fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:10:43 +0200 Subject: Load object/blank and make use of presence. --- actionpack/lib/action_dispatch/middleware/request_id.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index f4d721f9bf..d7bb9c58df 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -1,5 +1,6 @@ require 'securerandom' require 'active_support/core_ext/string/access' +require 'active_support/core_ext/object/blank' module ActionDispatch # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through @@ -26,8 +27,8 @@ module ActionDispatch private def external_request_id(env) - if env["HTTP_X_REQUEST_ID"].present? - env["HTTP_X_REQUEST_ID"].gsub(/[^\w\d\-]/, "").first(255) + if request_id = env["HTTP_X_REQUEST_ID"].presence + request_id.gsub(/[^\w\d\-]/, "").first(255) end end -- cgit v1.2.3 From 6c126015a676c376f1646713fbb739049a783238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:26:56 +0200 Subject: Ensure TaggegLogging is thread safe. --- activesupport/lib/active_support/tagged_logging.rb | 35 ++++++++++++++-------- activesupport/test/tagged_logging_test.rb | 30 ++++++++++++++++++- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb index 0cabb528ef..aff416a9eb 100644 --- a/activesupport/lib/active_support/tagged_logging.rb +++ b/activesupport/lib/active_support/tagged_logging.rb @@ -13,20 +13,20 @@ module ActiveSupport class TaggedLogging def initialize(logger) @logger = logger - @tags = [] + @tags = Hash.new { |h,k| h[k] = [] } end - def tagged(*tags) - new_tags = Array.wrap(tags).flatten - @tags += new_tags + def tagged(*new_tags) + tags = current_tags + new_tags = Array.wrap(new_tags).flatten + tags.concat new_tags yield ensure - new_tags.size.times { @tags.pop } + new_tags.size.times { tags.pop } end - def add(severity, message = nil, progname = nil, &block) - @logger.add(severity, "#{tags}#{message}", progname, &block) + @logger.add(severity, "#{tags_text}#{message}", progname, &block) end %w( fatal error warn info debug unkown ).each do |severity| @@ -37,17 +37,26 @@ module ActiveSupport EOM end + def flush(*args) + @tags.delete(Thread.current) + @logger.flush(*args) if @logger.respond_to?(:flush) + end def method_missing(method, *args) @logger.send(method, *args) end - - private - def tags - if @tags.any? - @tags.collect { |tag| "[#{tag}]" }.join(" ") + " " - end + protected + + def tags_text + tags = current_tags + if tags.any? + tags.collect { |tag| "[#{tag}]" }.join(" ") + " " end + end + + def current_tags + @tags[Thread.current] + end end end diff --git a/activesupport/test/tagged_logging_test.rb b/activesupport/test/tagged_logging_test.rb index a1504c6ce4..b12b12f32c 100644 --- a/activesupport/test/tagged_logging_test.rb +++ b/activesupport/test/tagged_logging_test.rb @@ -3,9 +3,15 @@ require 'active_support/core_ext/logger' require 'active_support/tagged_logging' class TaggedLoggingTest < ActiveSupport::TestCase + class MyLogger < ::Logger + def flush(*) + info "[FLUSHED]" + end + end + setup do @output = StringIO.new - @logger = ActiveSupport::TaggedLogging.new(Logger.new(@output)) + @logger = ActiveSupport::TaggedLogging.new(MyLogger.new(@output)) end test "tagged once" do @@ -23,6 +29,28 @@ class TaggedLoggingTest < ActiveSupport::TestCase assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string end + test "keeps each tag in their own thread" do + @logger.tagged("BCX") do + Thread.new do + @logger.tagged("OMG") { @logger.info "Cool story bro" } + end.join + @logger.info "Funky time" + end + assert_equal "[OMG] Cool story bro\n[BCX] Funky time\n", @output.string + end + + test "cleans up the taggings on flush" do + @logger.tagged("BCX") do + Thread.new do + @logger.tagged("OMG") do + @logger.flush + @logger.info "Cool story bro" + end + end.join + end + assert_equal "[FLUSHED]\nCool story bro\n", @output.string + end + test "mixed levels of tagging" do @logger.tagged("BCX") do @logger.tagged("Jason") { @logger.info "Funky time" } -- cgit v1.2.3 From c83d9a11c00bc13e1f8f0fa0e8fb6185cacd5fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 19 Oct 2011 22:39:11 +0200 Subject: Unify logger and taggedlogging middleware as both address logging concerns. --- railties/CHANGELOG | 2 +- railties/lib/rails/application.rb | 3 +-- railties/lib/rails/rack.rb | 1 - railties/lib/rails/rack/logger.rb | 38 +++++++++++++++++++++---------- railties/lib/rails/rack/tagged_logging.rb | 36 ----------------------------- 5 files changed, 28 insertions(+), 52 deletions(-) delete mode 100644 railties/lib/rails/rack/tagged_logging.rb diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 181019f851..7f7b24804d 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,6 +1,6 @@ *Rails 3.2.0 (unreleased)* -* Added Rails::Rack::TaggedLogging middleware by default that will apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications [DHH] +* Updated Rails::Rack::Logger middleware to apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications [DHH] * Default options to `rails new` can be set in ~/.railsrc [Guillermo Iguaran] diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index a097cfd1be..82fffe86bb 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -165,8 +165,7 @@ module Rails middleware.use ::Rack::Runtime middleware.use ::Rack::MethodOverride middleware.use ::ActionDispatch::RequestId - middleware.use ::Rails::Rack::TaggedLogging, config.log_tags - middleware.use ::Rails::Rack::Logger # must come after Rack::MethodOverride to properly log overridden methods + middleware.use ::Rails::Rack::Logger, config.log_tags # must come after Rack::MethodOverride to properly log overridden methods middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies if config.action_dispatch.x_sendfile_header.present? diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb index b78293e570..d1ee96f7fd 100644 --- a/railties/lib/rails/rack.rb +++ b/railties/lib/rails/rack.rb @@ -3,6 +3,5 @@ module Rails autoload :Debugger, "rails/rack/debugger" autoload :Logger, "rails/rack/logger" autoload :LogTailer, "rails/rack/log_tailer" - autoload :TaggedLogging, "rails/rack/tagged_logging" end end diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb index 4d388c4d10..89de10c83d 100644 --- a/railties/lib/rails/rack/logger.rb +++ b/railties/lib/rails/rack/logger.rb @@ -1,32 +1,46 @@ require 'active_support/core_ext/time/conversions' +require 'active_support/core_ext/object/blank' module Rails module Rack # Log the request started and flush all loggers after it. class Logger < ActiveSupport::LogSubscriber - def initialize(app) - @app = app + def initialize(app, tags=nil) + @app, @tags = app, tags.presence end def call(env) - before_dispatch(env) - @app.call(env) - ensure - after_dispatch(env) + if @tags + Rails.logger.tagged(compute_tags(env)) { call_app(env) } + else + call_app(env) + end end protected - def before_dispatch(env) + def call_app(env) request = ActionDispatch::Request.new(env) path = request.filtered_path - - info "\n\n" - info "Started #{request.request_method} \"#{path}\" for #{request.ip} at #{Time.now.to_default_s}" + Rails.logger.info "\n\nStarted #{request.request_method} \"#{path}\" for #{request.ip} at #{Time.now.to_default_s}" + @app.call(env) + ensure + ActiveSupport::LogSubscriber.flush_all! end - def after_dispatch(env) - ActiveSupport::LogSubscriber.flush_all! + def compute_tags(env) + request = ActionDispatch::Request.new(env) + + @tags.collect do |tag| + case tag + when Proc + tag.call(request) + when Symbol + request.send(tag) + else + tag + end + end end end end diff --git a/railties/lib/rails/rack/tagged_logging.rb b/railties/lib/rails/rack/tagged_logging.rb deleted file mode 100644 index c519d7c3e6..0000000000 --- a/railties/lib/rails/rack/tagged_logging.rb +++ /dev/null @@ -1,36 +0,0 @@ -module Rails - module Rack - # Enables easy tagging of any logging activity that occurs within the Rails request cycle. The tags are configured via the - # config.log_tags setting. The tags can either be strings, procs taking a request argument, or symbols representing method - # names on request (so :uuid will result in request.uuid being added as a tag). - class TaggedLogging - def initialize(app, tags = nil) - @app, @tags = app, tags - end - - def call(env) - if @tags - Rails.logger.tagged(compute_tags(env)) { @app.call(env) } - else - @app.call(env) - end - end - - private - def compute_tags(env) - request = ActionDispatch::Request.new(env) - - @tags.collect do |tag| - case tag - when Proc - tag.call(request) - when Symbol - request.send(tag) - else - tag - end - end - end - end - end -end -- cgit v1.2.3 From 930dc335d7067b17191257faf03fcecba3351caa Mon Sep 17 00:00:00 2001 From: Martin Svalin Date: Wed, 19 Oct 2011 23:06:08 +0200 Subject: Removed mention of deprecated ActiveModel::Errors#on --- activemodel/lib/active_model/errors.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index d91e4a2b6a..6db3ca7340 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -205,9 +205,8 @@ module ActiveModel messages.dup end - # Adds +message+ to the error messages on +attribute+, which will be returned on a call to - # on(attribute) for the same attribute. More than one error can be added to the same - # +attribute+ in which case an array will be returned on a call to on(attribute). + # Adds +message+ to the error messages on +attribute+. More than one error can be added to the same + # +attribute+. # If no +message+ is supplied, :invalid is assumed. # # If +message+ is a symbol, it will be translated using the appropriate scope (see +translate_error+). -- cgit v1.2.3 From 1359152345e84b951becf687ab6f26e30a9af3ce Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 16:16:44 -0500 Subject: Encourage use of tagged logging even when using a different logger --- railties/guides/code/getting_started/config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/code/getting_started/config/environments/production.rb b/railties/guides/code/getting_started/config/environments/production.rb index 4618191d6b..dee8acfdfe 100644 --- a/railties/guides/code/getting_started/config/environments/production.rb +++ b/railties/guides/code/getting_started/config/environments/production.rb @@ -37,7 +37,7 @@ Blog::Application.configure do # config.log_tags = [ :subdomain, :uuid ] # Use a different logger for distributed setups - # config.logger = SyslogLogger.new + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production # config.cache_store = :mem_cache_store -- cgit v1.2.3 From be27bf17e309fcb43fab45cfa1d31cea074a6a72 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 19 Oct 2011 16:24:00 -0500 Subject: Fix the proper production.rb --- .../rails/app/templates/config/environments/production.rb.tt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 64e2c09467..50f2df3d35 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -33,8 +33,11 @@ # See everything in the log (default is :info) # config.log_level = :debug + # Prepend all log lines with the following tags + # config.log_tags = [ :subdomain, :uuid ] + # Use a different logger for distributed setups - # config.logger = SyslogLogger.new + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production # config.cache_store = :mem_cache_store -- cgit v1.2.3 From 9694ca1a3bd070886802a6b9f7532adfe5b60cc4 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Wed, 19 Oct 2011 18:26:19 +1100 Subject: [engines guide] mention that we cover similar ground to the Getting Started Guide --- railties/guides/source/engines.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 6e27d823a7..73bbe486e5 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -98,7 +98,7 @@ Also in the test directory is the +test/integration+ directory, where integratio h3. Providing engine functionality -The engine that this guide covers will provide posting and commenting functionality. +The engine that this guide covers will provide posting and commenting functionality and follows a similar thread to the "Getting Started Guide":getting-started.html, with some new twists. h4. Generating a post resource -- cgit v1.2.3 From 8ede74e73a45b16a81064a175b3174848469498b Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 20 Oct 2011 08:46:20 +1100 Subject: [engines guide] Rather than calling name, require a to_s method to be defined on the 'User' class --- railties/guides/source/engines.textile | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 73bbe486e5..02054c972a 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -476,11 +476,26 @@ Finally, the author's name should be displayed on the post's page. Add this code

Author: - <%= @post.author.name %> + <%= @post.author %>

-NOTE: For posts created previously, this will break the +show+ page for them. We recommend deleting these posts and starting again, or manually assigning an author using +rails c+. +WARNING: For posts created previously, this will break the +show+ page for them. We recommend deleting these posts and starting again, or manually assigning an author using +rails c+. + +By outputting +@post.author+ using the +<%=+ tag the +to_s+ method will be called on the object. By default, this will look quite ugly: + + +# + + +This is undesirable and it would be much better to have the user's name there. To do this, add a +to_s+ method to the +User+ class within the application: + + +def to_s + name + + +Now instead of the ugly Ruby object output the author's name will be displayed. h4. Configuring an engine -- cgit v1.2.3 From 1cc6105d4dd088e3f2b8026e7e49f4e9d8d7d6ea Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 20 Oct 2011 08:46:41 +1100 Subject: [engines guide] wrap up 'Configuring an Engine' section --- railties/guides/source/engines.textile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 02054c972a..f0d8f1a165 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -531,7 +531,9 @@ Blorgh.user_class = "User" WARNING: It's very important here to use the +String+ version of the class, rather than the class itself. If you were to use the class, Rails would attempt to load that class and then reference the related table, which could lead to problems if the table wasn't already existing. Therefore, a +String+ should be used and then converted to a class using +constantize+ in the engine later on. +Go ahead and try to create a new post. You will see that it works exactly in the same way as before, except this time the engine is using the configuration setting in +config/initializers/blorgh.rb+ to learn what the class is. +There are now no strict dependencies on what the class is, only what the class's API must be. The engine simply requires this class to define a +find_or_create_by_name+ method which returns an object of that class to be associated with a post when it's created. h3. Overriding engine functionality -- cgit v1.2.3 From 4e9729df3f03ee16445082b7d386ee14b4370461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 20 Oct 2011 00:38:20 +0200 Subject: Don't use :path in Gemfile for --dev except for Rails. --- railties/lib/rails/generators/app_base.rb | 2 +- railties/lib/rails/generators/rails/app/app_generator.rb | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 134d86fab0..40961f0c3e 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -138,7 +138,7 @@ module Rails if options.dev? <<-GEMFILE.strip_heredoc gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}' - gem 'journey', :path => '#{Rails::Generators::JOURNEY_DEV_PATH}' + gem 'journey', :git => 'git://github.com/rails/journey.git' GEMFILE elsif options.edge? <<-GEMFILE.strip_heredoc diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index c8648d19f8..3e32f758a4 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -144,8 +144,6 @@ module Rails # We need to store the RAILS_DEV_PATH in a constant, otherwise the path # can change in Ruby 1.8.7 when we FileUtils.cd. RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__)) - JOURNEY_DEV_PATH = File.expand_path("../../../../../../../journey", File.dirname(__FILE__)) - RESERVED_NAMES = %w[application destroy benchmarker profiler plugin runner test] class AppGenerator < AppBase -- cgit v1.2.3 From 3e2d35b05006099163f6492019536bbfa1d82509 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 20 Oct 2011 17:10:46 +1100 Subject: [engines guide] add missing end for to_s method --- railties/guides/source/engines.textile | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index f0d8f1a165..5a12896b8e 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -493,6 +493,7 @@ This is undesirable and it would be much better to have the user's name there. T def to_s name +end Now instead of the ugly Ruby object output the author's name will be displayed. -- cgit v1.2.3 From 13e6f0cea83b2699e76b4f21ff87b267514d18d6 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 20 Oct 2011 17:32:34 +1100 Subject: [engines guide] some fixes for the author id migration including proof of not copying over other migrations again --- railties/guides/source/engines.textile | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 5a12896b8e..0688dc4c99 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -450,10 +450,10 @@ By defining that the +author+ association's object is represented by the +User+ To generate this new column, run this command within the engine: -$ rails g migration add_author_to_blorgh_posts author:references +$ rails g migration add_author_id_to_blorgh_posts author_id:integer -NOTE: Due to the migration's name, Rails will automatically know that you want to add a column to a specific table and write that into the migration for you. You don't need to tell it any more than this. +NOTE: Due to the migration's name and the column specification after it, Rails will automatically know that you want to add a column to a specific table and write that into the migration for you. You don't need to tell it any more than this. This migration will need to be run on the application. To do that, it must first be copied using this command: @@ -461,9 +461,15 @@ This migration will need to be run on the application. To do that, it must first $ rake blorgh:install:migrations -NOTE: Notice here that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. +Notice here that only _one_ migration was copied over here. This is because the first two migrations were copied over the first time this command was run. -And then migrated using this command: + + NOTE: Migration [timestamp]_create_blorgh_posts.rb from blorgh has been skipped. Migration with the same name already exists. + NOTE: Migration [timestamp]_create_blorgh_comments.rb from blorgh has been skipped. Migration with the same name already exists. + Copied migration [timestamp]_add_author_id_to_blorgh_posts.rb from blorgh + + +Run this migration using this command: $ rake db:migrate -- cgit v1.2.3 From 951a325c99ef2845f29ef95c85230ac2e835a31c Mon Sep 17 00:00:00 2001 From: Marc Bowes Date: Thu, 20 Oct 2011 10:00:42 +0300 Subject: Remove the unneeded `\d` when sanitizing `X-Request-Id`. --- actionpack/lib/action_dispatch/middleware/request_id.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index d7bb9c58df..bee446c8a5 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -28,7 +28,7 @@ module ActionDispatch private def external_request_id(env) if request_id = env["HTTP_X_REQUEST_ID"].presence - request_id.gsub(/[^\w\d\-]/, "").first(255) + request_id.gsub(/[^\w\-]/, "").first(255) end end -- cgit v1.2.3 From 5c5d5b3d2510d20998eafdd87a4458e0406e1690 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 20 Oct 2011 12:59:27 +0530 Subject: Adding ActionDispatch::RequestId in middleware test --- railties/test/application/middleware_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index 093cb6ca2a..4703a59326 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -30,6 +30,7 @@ module ApplicationTests "ActiveSupport::Cache::Strategy::LocalCache", "Rack::Runtime", "Rack::MethodOverride", + "ActionDispatch::RequestId", "Rails::Rack::Logger", # must come after Rack::MethodOverride to properly log overridden methods "ActionDispatch::ShowExceptions", "ActionDispatch::RemoteIp", -- cgit v1.2.3 From ee1223c1ee90899819a88c39db3e77b3692c68ee Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 20 Oct 2011 18:30:50 +1100 Subject: [engines guide] explanation of overriding views + referencing routes from an engine within an application --- railties/guides/source/engines.textile | 59 ++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index 0688dc4c99..da56f3d0ed 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -542,10 +542,65 @@ Go ahead and try to create a new post. You will see that it works exactly in the There are now no strict dependencies on what the class is, only what the class's API must be. The engine simply requires this class to define a +find_or_create_by_name+ method which returns an object of that class to be associated with a post when it's created. -h3. Overriding engine functionality +h3. Extending engine functionality -TODO: Cover how to override engine functionality in the engine, such as controllers and views. +This section looks at overriding or adding functionality to the views, controllers and models provided by an engine. +h4. Overriding views + +When Rails looks for a view to render, it will first look in the +app/views+ directory of the application. If it cannot find the view there, then it will check in the +app/views+ directories of all engines which have this directory. + +In the +blorgh+ engine, there is a currently a file at +app/views/blorgh/posts/index.html.erb+. When the engine is asked to render the view for +Blorgh::PostsController+'s +index+ action, it will first see if it can find it at +app/views/blorgh/posts/index.html.erb+ within the application and then if it cannot it will look inside the engine. + +By overriding this view in the application, by simply creating a new file at +app/views/blorgh/posts/index.html.erb+, you can completely change what this view would normally output. + +Try this now by creating a new file at +app/views/blorgh/posts/index.html.erb+ and put this content in it: + + +

Posts

+<%= link_to "New Post", new_post_path %> +<% @posts.each do |post| %> +

<%= post.title %>

+ By <%= post.author %> + <%= simple_format(post.text) %> +
+<% end %> +
+ +Rather than looking like the default scaffold, the page will now look like this: + +!images/engines_post_override.png(Engine scaffold overriden)! + +h4. Controllers + +TODO: Explain how to extend a controller. IDEA: I like Devise's +devise :controllers => { "sessions" => "sessions" }+ idea. Perhaps we could incorporate that into the guide? + +h4. Models + +TODO: Explain how to extend models provided by an engine. + +h4. Routes + +Within the application, you may wish to link to some area within the engine. Due to the fact that the engine's routes are isolated (by the +isolate_namespace+ call within the +lib/blorgh/engine.rb+ file), you will need to prefix these routes with the engine name. This means rather than having something such as: + + +<%= link_to "Blog posts", posts_path %> + + +It needs to be written as: + + +<%= link_to "Blog posts", blorgh.posts_path %> + + +This allows for the engine _and_ the application to both have a +posts_path+ routing helper and to not interfere with each other. You may also reference another engine's routes from inside an engine using this same syntax. + +If you wish to reference the application inside the engine in a similar way, use the +main_app+ helper: + + +<%= link_to "Home", main_app.root_path %> + + TODO: Mention how to use assets within an engine? TODO: Mention how to depend on external gems, like RedCarpet. -- cgit v1.2.3 From 66880cfe416b75f472762f2c6b485bad9759c751 Mon Sep 17 00:00:00 2001 From: Andrew France Date: Thu, 20 Oct 2011 12:32:11 +0200 Subject: Correct ActionMailer subject i18n lookup scope. The :actionmailer i18n scope part is not used and according to https://github.com/rails/rails/pull/2542 the implementation is correct. --- actionmailer/lib/action_mailer/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index ac49702ced..8f2c567e3e 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -524,7 +524,7 @@ module ActionMailer #:nodoc: # # * :subject - The subject of the message, if this is omitted, Action Mailer will # ask the Rails I18n class for a translated :subject in the scope of - # [:actionmailer, mailer_scope, action_name] or if this is missing, will translate the + # [mailer_scope, action_name] or if this is missing, will translate the # humanized version of the action_name # * :to - Who the message is destined for, can be a string of addresses, or an array # of addresses. -- cgit v1.2.3 From 274c3fad5087306a64ca91d044756221f5ff862c Mon Sep 17 00:00:00 2001 From: Martin Svalin Date: Thu, 20 Oct 2011 16:31:10 +0200 Subject: Fixed misleading docs for String#to_formatted_s(:db) --- activesupport/lib/active_support/core_ext/array/conversions.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb index 3b22e8b4f9..f3d06ecb2f 100644 --- a/activesupport/lib/active_support/core_ext/array/conversions.rb +++ b/activesupport/lib/active_support/core_ext/array/conversions.rb @@ -39,10 +39,10 @@ class Array # # Blog.all.to_formatted_s # => "First PostSecond PostThird Post" # - # Adding in the :db argument as the format yields a prettier - # output: + # Adding in the :db argument as the format yields a comma separated + # id list: # - # Blog.all.to_formatted_s(:db) # => "First Post,Second Post,Third Post" + # Blog.all.to_formatted_s(:db) # => "1,2,3" def to_formatted_s(format = :default) case format when :db -- cgit v1.2.3 From ee9d9fb5fab3cfaa5055e5fb4225b720d3818c94 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 20 Oct 2011 08:44:55 -0700 Subject: Merge pull request #3258 from ileitch/3-1-stable Postgres: Do not attempt to deallocate a statement if the connection is no longer active. --- .../connection_adapters/postgresql_adapter.rb | 8 +++++++- .../cases/adapters/postgresql/statement_pool_test.rb | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index b7f346e050..3d084bb178 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -289,7 +289,13 @@ module ActiveRecord end def dealloc(key) - @connection.query "DEALLOCATE #{key}" + @connection.query "DEALLOCATE #{key}" if connection_active? + end + + def connection_active? + @connection.status == PGconn::CONNECTION_OK + rescue PGError + false end end diff --git a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb index a82c6f67d6..f1c4b85126 100644 --- a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb +++ b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb @@ -2,6 +2,16 @@ require 'cases/helper' module ActiveRecord::ConnectionAdapters class PostgreSQLAdapter < AbstractAdapter + class InactivePGconn + def query(*args) + raise PGError + end + + def status + PGconn::CONNECTION_BAD + end + end + class StatementPoolTest < ActiveRecord::TestCase def test_cache_is_per_pid return skip('must support fork') unless Process.respond_to?(:fork) @@ -18,6 +28,12 @@ module ActiveRecord::ConnectionAdapters Process.waitpid pid assert $?.success?, 'process should exit successfully' end + + def test_dealloc_does_not_raise_on_inactive_connection + cache = StatementPool.new InactivePGconn.new, 10 + cache['foo'] = 'bar' + assert_nothing_raised { cache.clear } + end end end end -- cgit v1.2.3 From 48e1f8ba4c02ed81ba70fee459de8bc569197fc4 Mon Sep 17 00:00:00 2001 From: Pepe Hipolito Date: Thu, 20 Oct 2011 15:37:35 -0400 Subject: Fixed typo. a long the way => along the way --- railties/guides/source/initialization.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 32b41fdd2c..2299573a9f 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -7,7 +7,7 @@ This guide explains the internals of the initialization process in Rails as of R endprologue. -This guide goes through every single file, class and method call that is required to boot up the Ruby on Rails stack for a default Rails 3.1 application, explaining each part in detail a long the way. For this guide, we will be focusing on how the two most common methods (+rails server+ and Passenger) boot a Rails application. +This guide goes through every single file, class and method call that is required to boot up the Ruby on Rails stack for a default Rails 3.1 application, explaining each part in detail along the way. For this guide, we will be focusing on how the two most common methods (+rails server+ and Passenger) boot a Rails application. NOTE: Paths in this guide are relative to Rails or a Rails application unless otherwise specified. -- cgit v1.2.3 From 0cd93a6e2bbcdd2ead0d6e4b739dfd8def04d8d5 Mon Sep 17 00:00:00 2001 From: Pepe Hipolito Date: Thu, 20 Oct 2011 15:58:51 -0400 Subject: Fixed typo. Ruby will know to look for this file at => Ruby will know how to look for this file at --- railties/guides/source/initialization.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 2299573a9f..f88405a2fd 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -243,7 +243,7 @@ In this file there are a lot of lines such as this inside the +ActiveSupport+ mo autoload :Inflector -Due to the overriding of the +autoload+ method, Ruby will know to look for this file at +activesupport/lib/active_support/inflector.rb+ when the +Inflector+ class is first referenced. +Due to the overriding of the +autoload+ method, Ruby will know how to look for this file at +activesupport/lib/active_support/inflector.rb+ when the +Inflector+ class is first referenced. The +active_support/lib/active_support/version.rb+ that is also required here simply defines an +ActiveSupport::VERSION+ constant which defines a couple of constants inside this module, the main constant of this is +ActiveSupport::VERSION::STRING+ which returns the current version of ActiveSupport. -- cgit v1.2.3 From d64e0955d04a40355e312ca4ee57b2c9a8e248cc Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Thu, 20 Oct 2011 17:13:01 -0400 Subject: Use new migration style in HABTM join table Yes, we're on Rails 3.1 now. --- activerecord/lib/active_record/associations.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 0952ea2829..2449df079a 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1424,16 +1424,12 @@ module ActiveRecord # join table with a migration such as this: # # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration - # def self.up + # def change # create_table :developers_projects, :id => false do |t| # t.integer :developer_id # t.integer :project_id # end # end - # - # def self.down - # drop_table :developers_projects - # end # end # # Adds the following methods for retrieval and query: -- cgit v1.2.3 From f0be2cb19274bb6029f84ca274a72c4d7fbee2d3 Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Thu, 20 Oct 2011 17:15:28 -0400 Subject: Add some note on adding index to HABTM table --- activerecord/lib/active_record/associations.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 2449df079a..34684ad2f5 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1432,6 +1432,10 @@ module ActiveRecord # end # end # + # It's also a good idea to add indexes to each of those columns to speed up the joins process. + # However, in MySQL it is advised to add a compound index for both of the columns as MySQL only + # uses one index per table during the lookup. + # # Adds the following methods for retrieval and query: # # [collection(force_reload = false)] -- cgit v1.2.3 From c495cbcda94bec7a49a88631fc575cc04bde8e88 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Fri, 21 Oct 2011 15:12:00 +0530 Subject: Checking blank if tag might coming nil or blank In log it should not show the empty array. --- activesupport/lib/active_support/tagged_logging.rb | 3 ++- activesupport/test/tagged_logging_test.rb | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb index aff416a9eb..a59fc26d5d 100644 --- a/activesupport/lib/active_support/tagged_logging.rb +++ b/activesupport/lib/active_support/tagged_logging.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/object/blank' require 'logger' module ActiveSupport @@ -18,7 +19,7 @@ module ActiveSupport def tagged(*new_tags) tags = current_tags - new_tags = Array.wrap(new_tags).flatten + new_tags = Array.wrap(new_tags).flatten.reject(&:blank?) tags.concat new_tags yield ensure diff --git a/activesupport/test/tagged_logging_test.rb b/activesupport/test/tagged_logging_test.rb index b12b12f32c..17c4214dfc 100644 --- a/activesupport/test/tagged_logging_test.rb +++ b/activesupport/test/tagged_logging_test.rb @@ -29,6 +29,11 @@ class TaggedLoggingTest < ActiveSupport::TestCase assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string end + test "tagged once with blank and nil" do + @logger.tagged(nil, "", "New") { @logger.info "Funky time" } + assert_equal "[New] Funky time\n", @output.string + end + test "keeps each tag in their own thread" do @logger.tagged("BCX") do Thread.new do -- cgit v1.2.3 From d565fda5f27abf0097adf7b3e232a52f7ae5c1e9 Mon Sep 17 00:00:00 2001 From: Brian Durand Date: Fri, 21 Oct 2011 12:43:52 -0500 Subject: Fix threading issues with BufferedLogger. --- .../lib/active_support/buffered_logger.rb | 44 ++++++++++++++---- activesupport/test/buffered_logger_test.rb | 53 ++++++++++++++++++++++ 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb index 26412cd7f4..136e245859 100644 --- a/activesupport/lib/active_support/buffered_logger.rb +++ b/activesupport/lib/active_support/buffered_logger.rb @@ -25,22 +25,28 @@ module ActiveSupport # Silences the logger for the duration of the block. def silence(temporary_level = ERROR) if silencer + old_logger_level = @tmp_levels[Thread.current] begin - old_logger_level, self.level = level, temporary_level + @tmp_levels[Thread.current] = temporary_level yield self ensure - self.level = old_logger_level + if old_logger_level + @tmp_levels[Thread.current] = old_logger_level + else + @tmp_levels.delete(Thread.current) + end end else yield self end end - attr_accessor :level + attr_writer :level attr_reader :auto_flushing def initialize(log, level = DEBUG) @level = level + @tmp_levels = {} @buffer = Hash.new { |h,k| h[k] = [] } @auto_flushing = 1 @guard = Mutex.new @@ -62,8 +68,12 @@ module ActiveSupport end end + def level + @tmp_levels[Thread.current] || @level + end + def add(severity, message = nil, progname = nil, &block) - return if @level > severity + return if level > severity message = (message || (block && block.call) || progname).to_s # If a newline is necessary then create a new message ending with a newline. # Ensures that the original message is not mutated. @@ -84,7 +94,7 @@ module ActiveSupport end # end def #{severity.downcase}? # def debug? - #{severity} >= @level # DEBUG >= @level + #{severity} >= level # DEBUG >= @level end # end EOT end @@ -105,13 +115,15 @@ module ActiveSupport def flush @guard.synchronize do - buffer.each do |content| - @log.write(content) - end + write_buffer(buffer) # Important to do this even if buffer was empty or else @buffer will # accumulate empty arrays for each request where nothing was logged. clear_buffer + + # Clear buffers associated with dead threads or else spawned threads + # that don't call flush will result in a memory leak. + flush_dead_buffers end end @@ -133,5 +145,21 @@ module ActiveSupport def clear_buffer @buffer.delete(Thread.current) end + + # Find buffers created by threads that are no longer alive and flush them to the log + # in order to prevent memory leaks from spawned threads. + def flush_dead_buffers #:nodoc: + @buffer.keys.reject{|thread| thread.alive?}.each do |thread| + buffer = @buffer[thread] + write_buffer(buffer) + @buffer.delete(thread) + end + end + + def write_buffer(buffer) + buffer.each do |content| + @log.write(content) + end + end end end diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb index 21049d685b..8699862d9e 100644 --- a/activesupport/test/buffered_logger_test.rb +++ b/activesupport/test/buffered_logger_test.rb @@ -198,4 +198,57 @@ class BufferedLoggerTest < Test::Unit::TestCase end assert byte_string.include?(BYTE_STRING) end + + def test_silence_only_current_thread + @logger.auto_flushing = true + run_thread_a = false + + a = Thread.new do + while !run_thread_a do + sleep(0.001) + end + @logger.info("x") + run_thread_a = false + end + + @logger.silence do + run_thread_a = true + @logger.info("a") + while run_thread_a do + sleep(0.001) + end + end + + a.join + + assert @output.string.include?("x") + assert !@output.string.include?("a") + end + + def test_flush_dead_buffers + @logger.auto_flushing = false + + a = Thread.new do + @logger.info("a") + end + + keep_running = true + b = Thread.new do + @logger.info("b") + while keep_running + sleep(0.001) + end + end + + @logger.info("x") + a.join + @logger.flush + + + assert @output.string.include?("x") + assert @output.string.include?("a") + assert !@output.string.include?("b") + + keep_running = false + end end -- cgit v1.2.3 From 2b04c2f66e3cf5abbbf118eaa1e692b9e1380e4e Mon Sep 17 00:00:00 2001 From: Brian Durand Date: Fri, 21 Oct 2011 13:13:29 -0500 Subject: Add ActionDispatch::Session::CacheStore as a generic way of storing sessions in a cache. --- actionpack/lib/action_dispatch.rb | 1 + .../middleware/session/cache_store.rb | 50 ++++++ .../test/dispatch/session/cache_store_test.rb | 181 +++++++++++++++++++++ .../source/action_controller_overview.textile | 10 +- railties/guides/source/rails_on_rack.textile | 5 +- railties/guides/source/security.textile | 4 +- 6 files changed, 243 insertions(+), 8 deletions(-) create mode 100644 actionpack/lib/action_dispatch/middleware/session/cache_store.rb create mode 100644 actionpack/test/dispatch/session/cache_store_test.rb diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index c13850f378..1e92d14542 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -83,6 +83,7 @@ module ActionDispatch autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store' autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store' autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store' + autoload :CacheStore, 'action_dispatch/middleware/session/cache_store' end autoload_under 'testing' do diff --git a/actionpack/lib/action_dispatch/middleware/session/cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb new file mode 100644 index 0000000000..d3b6fd12fa --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb @@ -0,0 +1,50 @@ +require 'action_dispatch/middleware/session/abstract_store' +require 'rack/session/memcache' + +module ActionDispatch + module Session + # Session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful + # if you don't store critical data in your sessions and you don't need them to live for extended periods + # of time. + class CacheStore < AbstractStore + # Create a new store. The cache to use can be passed in the :cache option. If it is + # not specified, Rails.cache will be used. + def initialize(app, options = {}) + @cache = options[:cache] || Rails.cache + options[:expire_after] ||= @cache.options[:expires_in] + super + end + + # Get a session from the cache. + def get_session(env, sid) + sid ||= generate_sid + session = @cache.read(cache_key(sid)) + session ||= {} + [sid, session] + end + + # Set a session in the cache. + def set_session(env, sid, session, options) + key = cache_key(sid) + if session + @cache.write(key, session, :expires_in => options[:expire_after]) + else + @cache.delete(key) + end + sid + end + + # Remove a session from the cache. + def destroy_session(env, sid, options) + @cache.delete(cache_key(sid)) + generate_sid + end + + private + # Turn the session id into a cache key. + def cache_key(sid) + "_session_id:#{sid}" + end + end + end +end diff --git a/actionpack/test/dispatch/session/cache_store_test.rb b/actionpack/test/dispatch/session/cache_store_test.rb new file mode 100644 index 0000000000..73e056de23 --- /dev/null +++ b/actionpack/test/dispatch/session/cache_store_test.rb @@ -0,0 +1,181 @@ +require 'abstract_unit' + +class CacheStoreTest < ActionDispatch::IntegrationTest + class TestController < ActionController::Base + def no_session_access + head :ok + end + + def set_session_value + session[:foo] = "bar" + head :ok + end + + def set_serialized_session_value + session[:foo] = SessionAutoloadTest::Foo.new + head :ok + end + + def get_session_value + render :text => "foo: #{session[:foo].inspect}" + end + + def get_session_id + render :text => "#{request.session_options[:id]}" + end + + def call_reset_session + session[:bar] + reset_session + session[:bar] = "baz" + head :ok + end + + def rescue_action(e) raise end + end + + def test_setting_and_getting_session_value + with_test_route_set do + get '/set_session_value' + assert_response :success + assert cookies['_session_id'] + + get '/get_session_value' + assert_response :success + assert_equal 'foo: "bar"', response.body + end + end + + def test_getting_nil_session_value + with_test_route_set do + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body + end + end + + def test_getting_session_value_after_session_reset + with_test_route_set do + get '/set_session_value' + assert_response :success + assert cookies['_session_id'] + session_cookie = cookies.send(:hash_for)['_session_id'] + + get '/call_reset_session' + assert_response :success + assert_not_equal [], headers['Set-Cookie'] + + cookies << session_cookie # replace our new session_id with our old, pre-reset session_id + + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body, "data for this session should have been obliterated from cache" + end + end + + def test_getting_from_nonexistent_session + with_test_route_set do + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body + assert_nil cookies['_session_id'], "should only create session on write, not read" + end + end + + def test_setting_session_value_after_session_reset + with_test_route_set do + get '/set_session_value' + assert_response :success + assert cookies['_session_id'] + session_id = cookies['_session_id'] + + get '/call_reset_session' + assert_response :success + assert_not_equal [], headers['Set-Cookie'] + + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body + + get '/get_session_id' + assert_response :success + assert_not_equal session_id, response.body + end + end + + def test_getting_session_id + with_test_route_set do + get '/set_session_value' + assert_response :success + assert cookies['_session_id'] + session_id = cookies['_session_id'] + + get '/get_session_id' + assert_response :success + assert_equal session_id, response.body, "should be able to read session id without accessing the session hash" + end + end + + def test_deserializes_unloaded_class + with_test_route_set do + with_autoload_path "session_autoload_test" do + get '/set_serialized_session_value' + assert_response :success + assert cookies['_session_id'] + end + with_autoload_path "session_autoload_test" do + get '/get_session_id' + assert_response :success + end + with_autoload_path "session_autoload_test" do + get '/get_session_value' + assert_response :success + assert_equal 'foo: #', response.body, "should auto-load unloaded class" + end + end + end + + def test_doesnt_write_session_cookie_if_session_id_is_already_exists + with_test_route_set do + get '/set_session_value' + assert_response :success + assert cookies['_session_id'] + + get '/get_session_value' + assert_response :success + assert_equal nil, headers['Set-Cookie'], "should not resend the cookie again if session_id cookie is already exists" + end + end + + def test_prevents_session_fixation + with_test_route_set do + get '/get_session_value' + assert_response :success + assert_equal 'foo: nil', response.body + session_id = cookies['_session_id'] + + reset! + + get '/set_session_value', :_session_id => session_id + assert_response :success + assert_not_equal session_id, cookies['_session_id'] + end + end + + private + def with_test_route_set + with_routing do |set| + set.draw do + match ':action', :to => ::CacheStoreTest::TestController + end + + @app = self.class.build_app(set) do |middleware| + cache = ActiveSupport::Cache::MemoryStore.new + middleware.use ActionDispatch::Session::CacheStore, :key => '_session_id', :cache => cache + middleware.delete "ActionDispatch::ShowExceptions" + end + + yield + end + end +end diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index 5019d49686..b34c223b31 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -166,10 +166,10 @@ h3. Session Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of a number of different storage mechanisms: -* CookieStore - Stores everything on the client. -* DRbStore - Stores the data on a DRb server. -* MemCacheStore - Stores the data in a memcache. -* ActiveRecordStore - Stores the data in a database using Active Record. +* ActionDispatch::Session::CookieStore - Stores everything on the client. +* ActiveRecord::SessionStore - Stores the data in a database using Active Record. +* ActionDispatch::Session::CacheStore - Stores the data in the Rails cache. +* ActionDispatch::Session::MemCacheStore - Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead). All session stores use a cookie to store a unique ID for each session (you must use a cookie, Rails will not allow you to pass the session ID in the URL as this is less secure). @@ -177,6 +177,8 @@ For most stores this ID is used to look up the session data on the server, e.g. The CookieStore can store around 4kB of data -- much less than the others -- but this is usually enough. Storing large amounts of data in the session is discouraged no matter which session store your application uses. You should especially avoid storing complex objects (anything other than basic Ruby objects, the most common example being model instances) in the session, as the server might not be able to reassemble them between requests, which will result in an error. +If your user sessions don't store critical data or don't need to be around for long periods (for instance if you just use the flash for messaging), you can consider using ActionDispatch::Session::CacheStore. This will store sessions using the cache implementation you have configured for your application. The advantage of this is that you can use your existing cache infrastructure for storing sessions without requiring any additional setup or administration. The downside, of course, is that the sessions will be ephemeral and could disappear at any time. + Read more about session storage in the "Security Guide":security.html. If you need a different session storage mechanism, you can change it in the +config/initializers/session_store.rb+ file: diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile index 57c03b54dc..d6cbd84b1f 100644 --- a/railties/guides/source/rails_on_rack.textile +++ b/railties/guides/source/rails_on_rack.textile @@ -166,8 +166,9 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol |+Rack::Lock+|Sets env["rack.multithread"] flag to +true+ and wraps the application within a Mutex.| |+ActionController::Failsafe+|Returns HTTP Status +500+ to the client if an exception gets raised while dispatching.| |+ActiveRecord::QueryCache+|Enables the Active Record query cache.| -|+ActionController::Session::CookieStore+|Uses the cookie based session store.| -|+ActionController::Session::MemCacheStore+|Uses the memcached based session store.| +|+ActionDispatch::Session::CookieStore+|Uses the cookie based session store.| +|+ActionDispatch::Session::CacheStore+|Uses the Rails cache based session store.| +|+ActionDispatch::Session::MemCacheStore+|Uses the memcached based session store.| |+ActiveRecord::SessionStore+|Uses the database based session store.| |+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or env["HTTP_X_HTTP_METHOD_OVERRIDE"].| |+Rack::Head+|Discards the response body if the client sends a +HEAD+ request.| diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 8837e06de5..a499ef3d39 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -82,9 +82,9 @@ This will also be a good idea, if you modify the structure of an object and old h4. Session Storage --- _Rails provides several storage mechanisms for the session hashes. The most important are SessionStore and CookieStore._ +-- _Rails provides several storage mechanisms for the session hashes. The most important are ActiveRecord::SessionStore and ActionDispatch::Session::CookieStore._ -There are a number of session storages, i.e. where Rails saves the session hash and session id. Most real-live applications choose SessionStore (or one of its derivatives) over file storage due to performance and maintenance reasons. SessionStore keeps the session id and hash in a database table and saves and retrieves the hash on every request. +There are a number of session storages, i.e. where Rails saves the session hash and session id. Most real-live applications choose ActiveRecord::SessionStore (or one of its derivatives) over file storage due to performance and maintenance reasons. ActiveRecord::SessionStore keeps the session id and hash in a database table and saves and retrieves the hash on every request. Rails 2 introduced a new default session storage, CookieStore. CookieStore saves the session hash directly in a cookie on the client-side. The server retrieves the session hash from the cookie and eliminates the need for a session id. That will greatly increase the speed of the application, but it is a controversial storage option and you have to think about the security implications of it: -- cgit v1.2.3 From ec93f363cab7270c1469b420a52a21e306a89c30 Mon Sep 17 00:00:00 2001 From: Brian Durand Date: Fri, 21 Oct 2011 13:28:24 -0500 Subject: Fix ActiveSupport::Cache::FileStore.cleanup to actually work. --- .../lib/active_support/cache/file_store.rb | 21 +++++++++++-- activesupport/test/caching_test.rb | 34 ++++++++++++++++++++++ railties/guides/source/caching_with_rails.textile | 6 +++- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index b431041b76..bc5d94b5a7 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -26,11 +26,26 @@ module ActiveSupport FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) end + # Cleanup the cache by removing old entries. By default this will delete entries + # that haven't been accessed in one day. You can change this behavior by passing + # in a +not_accessed_in+ option. Any entry not accessed in that number of seconds + # in the past will be deleted. Alternatively, you can pass in +:expired_only+ with + # +true+ to only delete expired entries. def cleanup(options = nil) options = merged_options(options) - each_key(options) do |key| - entry = read_entry(key, options) - delete_entry(key, options) if entry && entry.expired? + expired_only = options[:expired_only] + timestamp = Time.now - (options[:not_accessed_in] || 1.day.to_i) + search_dir(cache_path) do |fname| + if expired_only + key = file_path_key(fname) + entry = read_entry(key, options) + delete_entry(key, options) if entry && entry.expired? + else + if File.atime(fname) <= timestamp + key = file_path_key(fname) + delete_entry(key, options) + end + end end end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index cb5362525f..1b2f6d061c 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -557,6 +557,29 @@ class FileStoreTest < ActiveSupport::TestCase key = @cache_with_pathname.send(:key_file_path, "views/index?id=1") assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key) end + + def test_cleanup_with_not_accessed_in + @cache.write(1, "aaaaaaaaaa") + @cache.write(2, "bbbbbbbbbb") + @cache.write(3, "cccccccccc") + sleep(2) + @cache.read(2) + @cache.cleanup(:not_accessed_in => 1) + assert_equal false, @cache.exist?(1) + assert_equal true, @cache.exist?(2) + assert_equal false, @cache.exist?(3) + end + + def test_cleanup_with_expired_only + @cache.write(1, "aaaaaaaaaa", :expires_in => 0.001) + @cache.write(2, "bbbbbbbbbb") + @cache.write(3, "cccccccccc", :expires_in => 0.001) + sleep(0.002) + @cache.cleanup(:expired_only => 0.001) + assert_equal false, @cache.exist?(1) + assert_equal true, @cache.exist?(2) + assert_equal false, @cache.exist?(3) + end # Because file systems have a maximum filename size, filenames > max size should be split in to directories # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B @@ -646,6 +669,17 @@ class MemoryStoreTest < ActiveSupport::TestCase assert_equal true, @cache.exist?(2) assert_equal false, @cache.exist?(1) end + + def test_cleanup_removes_expired_entries + @cache.write(1, "aaaaaaaaaa", :expires_in => 0.001) + @cache.write(2, "bbbbbbbbbb") + @cache.write(3, "cccccccccc", :expires_in => 0.001) + sleep(0.002) + @cache.cleanup + assert_equal false, @cache.exist?(1) + assert_equal true, @cache.exist?(2) + assert_equal false, @cache.exist?(3) + end end uses_memcached 'memcached backed store' do diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 4273d0dd64..721c791a33 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -289,7 +289,11 @@ ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts. -Note that the cache will grow until the disk is full unless you periodically clear out old entries. +Note that the cache will grow until the disk is full unless you periodically clear out old entries. You can call +ActiveSupport::Cache::FileStore#cleanup+ to remove entries older than a specified time. + + +Rails.cache.cleanup(:not_accessed_in => 2.days) + h4. ActiveSupport::Cache::MemCacheStore -- cgit v1.2.3 From f092be821db4a2e8f142e8f0b9d08e497ccf2eb2 Mon Sep 17 00:00:00 2001 From: Greg Reinacker Date: Fri, 21 Oct 2011 17:30:39 -0600 Subject: preserve decimal column attributes after migration --- .../connection_adapters/sqlite_adapter.rb | 3 ++ activerecord/test/cases/migration_test.rb | 36 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 1932a849ee..e0e957a12c 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -413,6 +413,8 @@ module ActiveRecord self.limit = options[:limit] if options.include?(:limit) self.default = options[:default] if include_default self.null = options[:null] if options.include?(:null) + self.precision = options[:precision] if options.include?(:precision) + self.scale = options[:scale] if options.include?(:scale) end end end @@ -467,6 +469,7 @@ module ActiveRecord @definition.column(column_name, column.type, :limit => column.limit, :default => column.default, + :precision => column.precision, :scale => column.scale, :null => column.null) end @definition.primary_key(primary_key(from)) if primary_key(from) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index b3f1785f44..49944eced9 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -518,6 +518,42 @@ if ActiveRecord::Base.connection.supports_migrations? assert_equal 7, wealth_column.scale end + # Test SQLite adapter specifically for decimal types with precision and scale + # attributes, since these need to be maintained in schema but aren't actually + # used in SQLite itself + if current_adapter?(:SQLite3Adapter) + def test_change_column_with_new_precision_and_scale + Person.delete_all + Person.connection.add_column 'people', 'wealth', :decimal, :precision => 9, :scale => 7 + Person.reset_column_information + + Person.connection.change_column 'people', 'wealth', :decimal, :precision => 12, :scale => 8 + Person.reset_column_information + + wealth_column = Person.columns_hash['wealth'] + assert_equal 12, wealth_column.precision + assert_equal 8, wealth_column.scale + end + + def test_change_column_preserve_other_column_precision_and_scale + Person.delete_all + Person.connection.add_column 'people', 'last_name', :string + Person.connection.add_column 'people', 'wealth', :decimal, :precision => 9, :scale => 7 + Person.reset_column_information + + wealth_column = Person.columns_hash['wealth'] + assert_equal 9, wealth_column.precision + assert_equal 7, wealth_column.scale + + Person.connection.change_column 'people', 'last_name', :string, :null => false + Person.reset_column_information + + wealth_column = Person.columns_hash['wealth'] + assert_equal 9, wealth_column.precision + assert_equal 7, wealth_column.scale + end + end + def test_native_types Person.delete_all Person.connection.add_column "people", "last_name", :string -- cgit v1.2.3 From 50be4231e9bd475cda905ab489d4bfc9ebd887f7 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 22 Oct 2011 15:51:55 +0530 Subject: Middleware details updated for 3.2 --- railties/guides/source/command_line.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile index f6b33d283c..d3f73e06e0 100644 --- a/railties/guides/source/command_line.textile +++ b/railties/guides/source/command_line.textile @@ -389,7 +389,7 @@ Action Pack version 3.1.0 Active Resource version 3.1.0 Action Mailer version 3.1.0 Active Support version 3.1.0 -Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, ActionDispatch::Callbacks, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::MethodOverride, ActionDispatch::Head +Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport Application root /home/foobar/commandsapp Environment development Database adapter sqlite3 -- cgit v1.2.3 From 6d5b92c735130a99186ef6f2ce6abe3f8745a8a5 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 22 Oct 2011 15:53:11 +0530 Subject: Rails version to 3.2.0.beta in docs --- railties/guides/source/command_line.textile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile index d3f73e06e0..ffa198891a 100644 --- a/railties/guides/source/command_line.textile +++ b/railties/guides/source/command_line.textile @@ -382,13 +382,13 @@ About your application's environment Ruby version 1.8.7 (x86_64-linux) RubyGems version 1.3.6 Rack version 1.1 -Rails version 3.1.0 +Rails version 3.2.0.beta JavaScript Runtime Node.js (V8) -Active Record version 3.1.0 -Action Pack version 3.1.0 -Active Resource version 3.1.0 -Action Mailer version 3.1.0 -Active Support version 3.1.0 +Active Record version 3.2.0.beta +Action Pack version 3.2.0.beta +Active Resource version 3.2.0.beta +Action Mailer version 3.2.0.beta +Active Support version 3.2.0.beta Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport Application root /home/foobar/commandsapp Environment development -- cgit v1.2.3 From 4ea21b6de260dd4cd610f88ae8d19a04977b5c2a Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 22 Oct 2011 15:54:55 +0530 Subject: Updated rack version in docs for 3.2 --- railties/guides/source/command_line.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile index ffa198891a..3f8643eca3 100644 --- a/railties/guides/source/command_line.textile +++ b/railties/guides/source/command_line.textile @@ -381,7 +381,7 @@ $ rake about About your application's environment Ruby version 1.8.7 (x86_64-linux) RubyGems version 1.3.6 -Rack version 1.1 +Rack version 1.3 Rails version 3.2.0.beta JavaScript Runtime Node.js (V8) Active Record version 3.2.0.beta -- cgit v1.2.3 From 50dfd58fdb10557d9f14dc22494f96cf55237330 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 22 Oct 2011 16:30:48 +0530 Subject: Warnings removed from RequestIdTest --- actionpack/test/dispatch/request_id_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb index ece8353810..b6e8b6c3ad 100644 --- a/actionpack/test/dispatch/request_id_test.rb +++ b/actionpack/test/dispatch/request_id_test.rb @@ -14,13 +14,13 @@ class RequestIdTest < ActiveSupport::TestCase end test "generating a request id when none is supplied" do - assert_match /\w+/, stub_request.uuid + assert_match(/\w+/, stub_request.uuid) end private def stub_request(env = {}) - ActionDispatch::RequestId.new(lambda { |env| [ 200, env, [] ] }).call(env) + ActionDispatch::RequestId.new(lambda { |environment| [ 200, environment, [] ] }).call(env) ActionDispatch::Request.new(env) end end -- cgit v1.2.3 From bc5d334c7a340c29a4f9a594101832e1abe831a5 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 22 Oct 2011 19:16:43 +0530 Subject: Using middleware name to show proper name in the info --- railties/lib/rails/info.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index a1e15092b2..2ba09d7b90 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -91,7 +91,7 @@ module Rails end property 'Middleware' do - Rails.configuration.middleware.map(&:inspect) + Rails.configuration.middleware.map(&:name) end # The application's location on the filesystem. -- cgit v1.2.3 From c930170581ac10acf8c3d9433f3ccd5f72b4e6bf Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 22 Oct 2011 21:47:33 +0530 Subject: No need to check ruby version here As rake 0.9.2.2 is out with the same fix as 0.9.3.beta having --- Gemfile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index f63260a260..4ac6bf764d 100644 --- a/Gemfile +++ b/Gemfile @@ -19,12 +19,7 @@ end # it being automatically loaded by sprockets gem "uglifier", ">= 1.0.3", :require => false -# Temp fix until rake 0.9.3 is out -if RUBY_VERSION >= "1.9.3" - gem "rake", "0.9.3.beta.1" -else - gem "rake", ">= 0.8.7" -end +gem "rake", ">= 0.8.7" gem "mocha", ">= 0.9.8" group :doc do -- cgit v1.2.3 From 1c1c3fc2c06fc02e67a8272adf2c2d2381e005b4 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sat, 22 Oct 2011 23:53:52 +0530 Subject: minor fixes in the composed_of doc --- activerecord/lib/active_record/aggregations.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index 81ddbba51e..5a8addc4e4 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -172,8 +172,8 @@ module ActiveRecord # with this option. # * :mapping - Specifies the mapping of entity attributes to attributes of the value # object. Each mapping is represented as an array where the first item is the name of the - # entity attribute and the second item is the name the attribute in the value object. The - # order in which mappings are defined determine the order in which attributes are sent to the + # entity attribute and the second item is the name of the attribute in the value object. The + # order in which mappings are defined determines the order in which attributes are sent to the # value class constructor. # * :allow_nil - Specifies that the value object will not be instantiated when all mapped # attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all @@ -191,7 +191,8 @@ module ActiveRecord # # Option examples: # composed_of :temperature, :mapping => %w(reading celsius) - # composed_of :balance, :class_name => "Money", :mapping => %w(balance amount), :converter => Proc.new { |balance| balance.to_money } + # composed_of :balance, :class_name => "Money", :mapping => %w(balance amount), + # :converter => Proc.new { |balance| balance.to_money } # composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ] # composed_of :gps_location # composed_of :gps_location, :allow_nil => true -- cgit v1.2.3 From 259741ae7324c18782bf97f236230c496bccf948 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sat, 22 Oct 2011 12:28:06 -0700 Subject: Revert "Merge pull request #3405 from arunagw/middleware_name" This reverts commit c33090523c3504a2a125d7f725a7f2a4b99ff3c0, reversing changes made to 1c1c3fc2c06fc02e67a8272adf2c2d2381e005b4. --- railties/lib/rails/info.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index 2ba09d7b90..a1e15092b2 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -91,7 +91,7 @@ module Rails end property 'Middleware' do - Rails.configuration.middleware.map(&:name) + Rails.configuration.middleware.map(&:inspect) end # The application's location on the filesystem. -- cgit v1.2.3 From a458833705cd3e9a0909d0710da84e2009f097ba Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Sat, 22 Oct 2011 14:34:05 -0500 Subject: Remove Turn from default Gemfile. We still looking for a best presentation for tests output. --- railties/lib/rails/generators/app_base.rb | 11 ----------- railties/lib/rails/generators/rails/app/templates/Gemfile | 2 -- railties/test/generators/app_generator_test.rb | 15 --------------- 3 files changed, 28 deletions(-) diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 40961f0c3e..10fdfdd8a9 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -190,17 +190,6 @@ module Rails end end - def turn_gemfile_entry - unless RUBY_VERSION < "1.9.2" || options[:skip_test_unit] - <<-GEMFILE.strip_heredoc - group :test do - # Pretty printed test output - gem 'turn', :require => false - end - GEMFILE - end - end - def assets_gemfile_entry <<-GEMFILE.strip_heredoc # Gems used only for assets and not required diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 910cd16950..d3b8f4d595 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -21,5 +21,3 @@ source 'http://rubygems.org' # To use debugger # <%= ruby_debugger_gemfile_entry %> - -<%= turn_gemfile_entry -%> diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 133efb872f..4b74bd6a4b 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -242,21 +242,6 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_inclusion_of_turn_gem_in_gemfile - run_generator - assert_file "Gemfile" do |contents| - assert_match(/gem 'turn'/, contents) unless RUBY_VERSION < '1.9.2' - assert_no_match(/gem 'turn'/, contents) if RUBY_VERSION < '1.9.2' - end - end - - def test_turn_gem_is_not_included_in_gemfile_if_skipping_test_unit - run_generator [destination_root, "--skip-test-unit"] - assert_file "Gemfile" do |contents| - assert_no_match(/gem 'turn'/, contents) unless RUBY_VERSION < '1.9.2' - end - end - def test_inclusion_of_ruby_debug run_generator assert_file "Gemfile" do |contents| -- cgit v1.2.3 From 227c31f7b6b13fcfc187d20618ed14d2970314c7 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sun, 23 Oct 2011 01:34:02 +0530 Subject: edge doesnt provide turn gem in the gemfile anymore --- railties/guides/code/getting_started/Gemfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/railties/guides/code/getting_started/Gemfile b/railties/guides/code/getting_started/Gemfile index 51774934cd..898510dcaa 100644 --- a/railties/guides/code/getting_started/Gemfile +++ b/railties/guides/code/getting_started/Gemfile @@ -25,8 +25,3 @@ gem 'jquery-rails' # To use debugger # gem 'ruby-debug19', :require => 'ruby-debug' - -group :test do - # Pretty printed test output - gem 'turn', :require => false -end -- cgit v1.2.3 From e75c18bff811b95e12634cdbf04df244a227d46d Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Sun, 23 Oct 2011 18:07:00 +0300 Subject: Ignore .rbx directories (rbx compiled bytecode files) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ab0950d7dd..437a1067f8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ railties/tmp .rvmrc .rbenv-version RDOC_MAIN.rdoc +.rbx -- cgit v1.2.3 From 244dcfea477ace65963b41de122f7dab7904900b Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Mon, 24 Oct 2011 14:11:20 +0530 Subject: ActionPack test fix for RBX --- actionpack/test/controller/mime_responds_test.rb | 4 +++- actionpack/test/template/html-scanner/tag_node_test.rb | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 2aa73f1650..e91e11a8a7 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -656,7 +656,9 @@ class RespondWithControllerTest < ActionController::TestCase @request.accept = "application/json" get :using_hash_resource assert_equal "application/json", @response.content_type - assert_equal %Q[{"result":{"name":"david","id":13}}], @response.body + assert @response.body.include?("result") + assert @response.body.include?('"name":"david"') + assert @response.body.include?('"id":13') end def test_using_hash_resource_with_post diff --git a/actionpack/test/template/html-scanner/tag_node_test.rb b/actionpack/test/template/html-scanner/tag_node_test.rb index 0d87f1bd42..3b72243e7d 100644 --- a/actionpack/test/template/html-scanner/tag_node_test.rb +++ b/actionpack/test/template/html-scanner/tag_node_test.rb @@ -55,7 +55,12 @@ class TagNodeTest < Test::Unit::TestCase def test_to_s node = tag("") - assert_equal %(), node.to_s + node = node.to_s + assert node.include?('a') + assert node.include?('b="c"') + assert node.include?('d="f"') + assert node.include?('g="h') + assert node.include?('i') end def test_tag -- cgit v1.2.3 From 17bf04ff0dbb2f11dd7bc1a87df035a96f9432ef Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 24 Oct 2011 14:43:46 +0200 Subject: registers PR #2419 in the CHANGELOG --- activerecord/CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 46076dac61..798d875034 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,8 @@ *Rails 3.2.0 (unreleased)* +* In development mode the db:drop task also drops the test database. For symmetry with + the db:create task. [Dmitriy Kiriyenko] + * Added ActiveRecord::Base.store for declaring simple single-column key/value stores [DHH] class User < ActiveRecord::Base -- cgit v1.2.3 From 9dd168c40262e850885fcb3dd0028b9067bb627f Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 24 Oct 2011 14:46:28 +0200 Subject: minor revision to some new code in databases.rake --- activerecord/lib/active_record/railties/databases.rake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 705ffe9dd7..f8fa65ea87 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -548,8 +548,9 @@ def drop_database_and_rescue(config) end def configs_for_environment - environments = [Rails.env, ("test" if Rails.env.development?)] - ActiveRecord::Base.configurations.values_at(*environments).compact + environments = [Rails.env] + environments << 'test' if Rails.env.development? + ActiveRecord::Base.configurations.values_at(*environments) end def session_table_name -- cgit v1.2.3 From b6fc41275c2e300c9e4ce55e48eedaac811c5fac Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Mon, 24 Oct 2011 21:56:27 +0530 Subject: Unused variable removed --- activesupport/test/buffered_logger_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb index 8699862d9e..386006677b 100644 --- a/activesupport/test/buffered_logger_test.rb +++ b/activesupport/test/buffered_logger_test.rb @@ -233,7 +233,7 @@ class BufferedLoggerTest < Test::Unit::TestCase end keep_running = true - b = Thread.new do + Thread.new do @logger.info("b") while keep_running sleep(0.001) -- cgit v1.2.3 From 98fbb50ebf531af28deb1312baf943c24990ad25 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Mon, 24 Oct 2011 22:38:10 +0400 Subject: Remove needless to_param in scaffold functional test --- .../generators/test_unit/scaffold/templates/functional_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb index 01fe6dda7a..9ec2e34545 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb @@ -26,23 +26,23 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase end test "should show <%= singular_table_name %>" do - get :show, <%= key_value :id, "@#{singular_table_name}.to_param" %> + get :show, <%= key_value :id, "@#{singular_table_name}" %> assert_response :success end test "should get edit" do - get :edit, <%= key_value :id, "@#{singular_table_name}.to_param" %> + get :edit, <%= key_value :id, "@#{singular_table_name}" %> assert_response :success end test "should update <%= singular_table_name %>" do - put :update, <%= key_value :id, "@#{singular_table_name}.to_param" %>, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %> + put :update, <%= key_value :id, "@#{singular_table_name}" %>, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %> assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>)) end test "should destroy <%= singular_table_name %>" do assert_difference('<%= class_name %>.count', -1) do - delete :destroy, <%= key_value :id, "@#{singular_table_name}.to_param" %> + delete :destroy, <%= key_value :id, "@#{singular_table_name}" %> end assert_redirected_to <%= index_helper %>_path -- cgit v1.2.3 From 7c6d4377b85a4e534f627a8b6ea126d74a7bb039 Mon Sep 17 00:00:00 2001 From: Bruce Adams Date: Mon, 24 Oct 2011 16:18:42 -0400 Subject: note that after_initialize is run for rake tasks --- railties/guides/source/configuring.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 58b92e7f9e..bb494fbd33 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -40,7 +40,7 @@ Rails will use that particular setting to configure Active Record. h4. Rails General Configuration -* +config.after_initialize+ takes a block which will be ran _after_ Rails has finished initializing the application. That includes the initialization of the framework itself, plugins, engines, and all the application's initializers in +config/initializers+. Useful for configuring values set up by other initializers: +* +config.after_initialize+ takes a block which will be run _after_ Rails has finished initializing the application. That includes the initialization of the framework itself, plugins, engines, and all the application's initializers in +config/initializers+. Note that this block _will_ be run for rake tasks. Useful for configuring values set up by other initializers: config.after_initialize do -- cgit v1.2.3 From 80bcfb00f71dbacd6af0a76429faa5d104ae3a36 Mon Sep 17 00:00:00 2001 From: Joost Baaij Date: Tue, 25 Oct 2011 13:57:24 +0300 Subject: Added a note that optimistic locking also needs a hidden field to function across web workers. --- activerecord/lib/active_record/locking/optimistic.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index 2df3309648..1a29ded787 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -37,6 +37,9 @@ module ActiveRecord # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, # or otherwise apply the business logic needed to resolve the conflict. # + # This locking mechanism will function inside a single Ruby process. To make it work across all + # web requests, the recommended approach is to add +lock_version+ as a hidden field to your form. + # # You must ensure that your database schema defaults the +lock_version+ column to 0. # # This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false. -- cgit v1.2.3 From a7641054d80a285c5da85d80b8678d899c27cd1a Mon Sep 17 00:00:00 2001 From: Nick Howard Date: Tue, 25 Oct 2011 10:39:20 -0600 Subject: add namespacing when referring to ActionController::RedirectBackError --- actionpack/lib/action_controller/metal/redirecting.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index f2dfb3833b..0355c9f458 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -54,8 +54,8 @@ module ActionController # redirect_to post_url(@post), :status => 301, :flash => { :updated_post_id => @post.id } # redirect_to { :action=>'atom' }, :alert => "Something serious happened" # - # When using redirect_to :back, if there is no referrer, RedirectBackError will be raised. You may specify some fallback - # behavior for this case by rescuing RedirectBackError. + # When using redirect_to :back, if there is no referrer, ActionController::RedirectBackError will be raised. You may specify some fallback + # behavior for this case by rescuing ActionController::RedirectBackError. def redirect_to(options = {}, response_status = {}) #:doc: raise ActionControllerError.new("Cannot redirect to nil!") unless options raise AbstractController::DoubleRenderError if response_body -- cgit v1.2.3 From e368583ba716f90120e7e6ccfc5ee76de015521c Mon Sep 17 00:00:00 2001 From: mjy Date: Tue, 25 Oct 2011 15:08:28 -0400 Subject: Adds missing closing regex slashes. --- actionpack/lib/action_dispatch/routing/mapper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index ef31d1e004..09a8c10043 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -696,7 +696,7 @@ module ActionDispatch # Allows you to constrain the nested routes based on a set of rules. # For instance, in order to change the routes to allow for a dot character in the +id+ parameter: # - # constraints(:id => /\d+\.\d+) do + # constraints(:id => /\d+\.\d+/) do # resources :posts # end # @@ -706,7 +706,7 @@ module ActionDispatch # You may use this to also restrict other parameters: # # resources :posts do - # constraints(:post_id => /\d+\.\d+) do + # constraints(:post_id => /\d+\.\d+/) do # resources :comments # end # end -- cgit v1.2.3 From ddce29bfa12462fde2342a0c2bd0eefd420c0eab Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 26 Oct 2011 00:41:41 +0530 Subject: safeguard against configs missing environment or the database key --- activerecord/lib/active_record/railties/databases.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index f8fa65ea87..44848b3391 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -550,7 +550,7 @@ end def configs_for_environment environments = [Rails.env] environments << 'test' if Rails.env.development? - ActiveRecord::Base.configurations.values_at(*environments) + ActiveRecord::Base.configurations.values_at(*environments).compact.reject { |config| config['database'].blank? } end def session_table_name -- cgit v1.2.3 From f7e56a3ab6f54ae5b9b021212b3d4e98eae6eeec Mon Sep 17 00:00:00 2001 From: Matthew Daubert Date: Tue, 25 Oct 2011 15:11:45 -0400 Subject: Fix deprecation warnings in action pack test suite due to passing template formats in the template name. --- actionpack/test/template/render_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 0ef3239f83..77659918f7 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -429,7 +429,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase if '1.9'.respond_to?(:force_encoding) def test_render_utf8_template_with_magic_comment with_external_encoding Encoding::ASCII_8BIT do - result = @view.render(:file => "test/utf8_magic.html", :layouts => "layouts/yield") + result = @view.render(:file => "test/utf8_magic", :formats => [:html], :layouts => "layouts/yield") assert_equal Encoding::UTF_8, result.encoding assert_equal "\nРусский \nтекст\n\nUTF-8\nUTF-8\nUTF-8\n", result end @@ -437,7 +437,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_default_external_encoding with_external_encoding Encoding::UTF_8 do - result = @view.render(:file => "test/utf8.html", :layouts => "layouts/yield") + result = @view.render(:file => "test/utf8", :formats => [:html], :layouts => "layouts/yield") assert_equal Encoding::UTF_8, result.encoding assert_equal "Русский текст\n\nUTF-8\nUTF-8\nUTF-8\n", result end @@ -446,7 +446,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_incompatible_external_encoding with_external_encoding Encoding::SHIFT_JIS do begin - @view.render(:file => "test/utf8.html", :layouts => "layouts/yield") + @view.render(:file => "test/utf8", :formats => [:html], :layouts => "layouts/yield") flunk 'Should have raised incompatible encoding error' rescue ActionView::Template::Error => error assert_match 'Your template was not saved as valid Shift_JIS', error.original_exception.message @@ -457,7 +457,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase def test_render_utf8_template_with_partial_with_incompatible_encoding with_external_encoding Encoding::SHIFT_JIS do begin - @view.render(:file => "test/utf8_magic_with_bare_partial.html", :layouts => "layouts/yield") + @view.render(:file => "test/utf8_magic_with_bare_partial", :formats => [:html], :layouts => "layouts/yield") flunk 'Should have raised incompatible encoding error' rescue ActionView::Template::Error => error assert_match 'Your template was not saved as valid Shift_JIS', error.original_exception.message -- cgit v1.2.3 From 771ca79f74db1e5a19703ad92472515dbebb70c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 25 Oct 2011 22:22:43 +0200 Subject: Revert "Merge pull request #3395 from bdurand/fix_file_store_cleanup" Tests were failing on Travis-CI. This reverts commit 79d01a8f16e20c556a086a2f07e3ccb4400f9819, reversing changes made to b838570bd69ff13d677fb43e79f10d6f3168c696. --- .../lib/active_support/cache/file_store.rb | 21 ++----------- activesupport/test/caching_test.rb | 34 ---------------------- railties/guides/source/caching_with_rails.textile | 6 +--- 3 files changed, 4 insertions(+), 57 deletions(-) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index bc5d94b5a7..b431041b76 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -26,26 +26,11 @@ module ActiveSupport FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) end - # Cleanup the cache by removing old entries. By default this will delete entries - # that haven't been accessed in one day. You can change this behavior by passing - # in a +not_accessed_in+ option. Any entry not accessed in that number of seconds - # in the past will be deleted. Alternatively, you can pass in +:expired_only+ with - # +true+ to only delete expired entries. def cleanup(options = nil) options = merged_options(options) - expired_only = options[:expired_only] - timestamp = Time.now - (options[:not_accessed_in] || 1.day.to_i) - search_dir(cache_path) do |fname| - if expired_only - key = file_path_key(fname) - entry = read_entry(key, options) - delete_entry(key, options) if entry && entry.expired? - else - if File.atime(fname) <= timestamp - key = file_path_key(fname) - delete_entry(key, options) - end - end + each_key(options) do |key| + entry = read_entry(key, options) + delete_entry(key, options) if entry && entry.expired? end end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 1b2f6d061c..cb5362525f 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -557,29 +557,6 @@ class FileStoreTest < ActiveSupport::TestCase key = @cache_with_pathname.send(:key_file_path, "views/index?id=1") assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key) end - - def test_cleanup_with_not_accessed_in - @cache.write(1, "aaaaaaaaaa") - @cache.write(2, "bbbbbbbbbb") - @cache.write(3, "cccccccccc") - sleep(2) - @cache.read(2) - @cache.cleanup(:not_accessed_in => 1) - assert_equal false, @cache.exist?(1) - assert_equal true, @cache.exist?(2) - assert_equal false, @cache.exist?(3) - end - - def test_cleanup_with_expired_only - @cache.write(1, "aaaaaaaaaa", :expires_in => 0.001) - @cache.write(2, "bbbbbbbbbb") - @cache.write(3, "cccccccccc", :expires_in => 0.001) - sleep(0.002) - @cache.cleanup(:expired_only => 0.001) - assert_equal false, @cache.exist?(1) - assert_equal true, @cache.exist?(2) - assert_equal false, @cache.exist?(3) - end # Because file systems have a maximum filename size, filenames > max size should be split in to directories # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B @@ -669,17 +646,6 @@ class MemoryStoreTest < ActiveSupport::TestCase assert_equal true, @cache.exist?(2) assert_equal false, @cache.exist?(1) end - - def test_cleanup_removes_expired_entries - @cache.write(1, "aaaaaaaaaa", :expires_in => 0.001) - @cache.write(2, "bbbbbbbbbb") - @cache.write(3, "cccccccccc", :expires_in => 0.001) - sleep(0.002) - @cache.cleanup - assert_equal false, @cache.exist?(1) - assert_equal true, @cache.exist?(2) - assert_equal false, @cache.exist?(3) - end end uses_memcached 'memcached backed store' do diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 721c791a33..4273d0dd64 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -289,11 +289,7 @@ ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts. -Note that the cache will grow until the disk is full unless you periodically clear out old entries. You can call +ActiveSupport::Cache::FileStore#cleanup+ to remove entries older than a specified time. - - -Rails.cache.cleanup(:not_accessed_in => 2.days) - +Note that the cache will grow until the disk is full unless you periodically clear out old entries. h4. ActiveSupport::Cache::MemCacheStore -- cgit v1.2.3 From 057a268d45e8432341bd73ae4c141bb926381f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 25 Oct 2011 22:23:55 +0200 Subject: Revert "Ignore .rbx directories (rbx compiled bytecode files)" This should go in your ~/.gitignore. This reverts commit e75c18bff811b95e12634cdbf04df244a227d46d. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 437a1067f8..ab0950d7dd 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,3 @@ railties/tmp .rvmrc .rbenv-version RDOC_MAIN.rdoc -.rbx -- cgit v1.2.3 From 139562f241136ca89209ddaffaf10b0b3a599b39 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 25 Oct 2011 13:30:50 -0700 Subject: Clean up .gitignore and make a note about using global ignores --- .gitignore | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index ab0950d7dd..aa14cee911 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,23 @@ -pkg -.bundle -Gemfile.lock +# Don't put *.swp, *.bak, etc here; those belong in a global ~/.gitignore. +# Check out http://help.github.com/ignore-files/ for how to set that up. + debug.log -doc/rdoc -activemodel/doc -activeresource/doc -activerecord/doc -activerecord/sqlnet.log -actionpack/doc -actionmailer/doc -activesupport/doc -activesupport/test/tmp -activemodel/test/fixtures/fixture_database.sqlite3 -actionpack/test/tmp -activesupport/test/fixtures/isolation_test -dist -railties/test/500.html -railties/test/fixtures/tmp -railties/test/initializer/root/log -railties/doc -railties/guides/output -railties/tmp -.rvmrc -.rbenv-version -RDOC_MAIN.rdoc +/.bundle +/.rbenv-version +/.rvmrc +/Gemfile.lock +/pkg +/dist +/doc/rdoc +/*/doc +/*/test/tmp +/activerecord/sqlnet.log +/activemodel/test/fixtures/fixture_database.sqlite3 +/activesupport/test/fixtures/isolation_test +/railties/test/500.html +/railties/test/fixtures/tmp +/railties/test/initializer/root/log +/railties/doc +/railties/guides/output +/railties/tmp +/RDOC_MAIN.rdoc -- cgit v1.2.3 From 5daf07704ad21d885661216281ffc48b6ea6adfb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 25 Oct 2011 17:22:52 -0500 Subject: Fix that changing a store should mark the store attribute as changed --- activerecord/lib/active_record/store.rb | 1 + activerecord/test/cases/store_test.rb | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb index d5910df891..8cc84f81d0 100644 --- a/activerecord/lib/active_record/store.rb +++ b/activerecord/lib/active_record/store.rb @@ -37,6 +37,7 @@ module ActiveRecord Array(keys).flatten.each do |key| define_method("#{key}=") do |value| send(store_attribute)[key] = value + send("#{store_attribute}_will_change!") end define_method(key) do diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index 3d056d93b6..3f7a965cfb 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -26,4 +26,9 @@ class StoreTest < ActiveRecord::TestCase assert 'graeters', @john.reload.settings[:icecream] end + + test "updating the store will mark it as changed" do + @john.color = 'red' + assert @john.settings_changed? + end end -- cgit v1.2.3 From 450257c95b0ca2c61eca2cefbcb2afd69e90f4a9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 25 Oct 2011 17:44:17 -0700 Subject: properly handle lists of lists. Thanks @adrianpike for reporting! --- actionpack/lib/action_view/helpers/form_options_helper.rb | 7 ++++++- actionpack/test/template/form_options_helper_test.rb | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index d636702111..1a6c3b9740 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -579,7 +579,12 @@ module ActionView def to_select_tag(choices, options, html_options) selected_value = options.has_key?(:selected) ? options[:selected] : value(object) - if !choices.empty? && Array === choices.first + # Grouped choices look like this: + # + # [nil, []] + # { nil => [] } + # + if !choices.empty? && choices.first.last.respond_to?(:each) option_tags = grouped_options_for_select(choices, :selected => selected_value, :disabled => options[:disabled]) else option_tags = options_for_select(choices, :selected => selected_value, :disabled => options[:disabled]) diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index d3e0cc41a9..469718e1bd 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -596,6 +596,15 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_list_of_lists + @post = Post.new + @post.category = "" + assert_dom_equal( + "", + select("post", "category", [["Number", "number"], ["Text", "text"], ["Yes/No", "boolean"]], :prompt => true, :include_blank => true) + ) + end + def test_select_with_selected_value @post = Post.new @post.category = "" -- cgit v1.2.3 From df5f88c7c0fce0d3b7a994ae376e626cd6d47d34 Mon Sep 17 00:00:00 2001 From: Henare Degan Date: Wed, 26 Oct 2011 19:03:53 +1200 Subject: Fix a little typo --- railties/guides/source/asset_pipeline.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index 6eb4ae49e3..6ff5e87b6d 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -438,7 +438,7 @@ location ~ ^/assets/ { } -When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. One the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves. +When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves. Nginx is able to do this automatically enabling +gzip_static+: -- cgit v1.2.3 From 20c59dd214b771efd978c7b35b314a785ffc176a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 26 Oct 2011 09:17:14 +0200 Subject: Fix failing tests. --- railties/test/application/rack/logger_test.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/railties/test/application/rack/logger_test.rb b/railties/test/application/rack/logger_test.rb index 8b2b2f1802..387eb25525 100644 --- a/railties/test/application/rack/logger_test.rb +++ b/railties/test/application/rack/logger_test.rb @@ -12,6 +12,8 @@ module ApplicationTests build_app require "#{app_path}/config/environment" super + @logger = MockLogger.new + Rails.stubs(:logger).returns(@logger) end def teardown -- cgit v1.2.3 From aef62c4b4e89e7fa91973c188c9e7f281a44ecd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 26 Oct 2011 09:29:38 +0200 Subject: Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box. --- railties/CHANGELOG | 2 ++ .../generators/rails/scaffold_controller/templates/controller.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 7f7b24804d..404bc73b0b 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.2.0 (unreleased)* +* Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box. [José Valim] + * Updated Rails::Rack::Logger middleware to apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications [DHH] * Default options to `rails new` can be set in ~/.railsrc [Guillermo Iguaran] diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb index 32b961d9fc..4ff15fd288 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb @@ -62,7 +62,7 @@ class <%= controller_class_name %>Controller < ApplicationController respond_to do |format| if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %> format.html { redirect_to @<%= singular_table_name %>, <%= key_value :notice, "'#{human_name} was successfully updated.'" %> } - format.json { head :ok } + format.json { head :no_content } else format.html { render <%= key_value :action, '"edit"' %> } format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> } @@ -78,7 +78,7 @@ class <%= controller_class_name %>Controller < ApplicationController respond_to do |format| format.html { redirect_to <%= index_helper %>_url } - format.json { head :ok } + format.json { head :no_content } end end end -- cgit v1.2.3 From 80768b739ed7e2053d85a01dd5fa60bde67aad9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 26 Oct 2011 09:31:56 +0200 Subject: Responders now return 204 No Content for API requests without a response body (as in the new scaffold) --- actionpack/CHANGELOG | 2 ++ .../lib/action_controller/metal/responder.rb | 22 +--------------------- actionpack/test/controller/mime_responds_test.rb | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 31 deletions(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index e7886facb9..a7a47bf930 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.2.0 (unreleased)* +* Responders now return 204 No Content for API requests without a response body (as in the new scaffold) [José Valim] + * Added ActionDispatch::RequestId middleware that'll make a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog [DHH] * Limit the number of options for select_year to 1000. diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb index c7827309dd..b932302a60 100644 --- a/actionpack/lib/action_controller/metal/responder.rb +++ b/actionpack/lib/action_controller/metal/responder.rb @@ -202,10 +202,8 @@ module ActionController #:nodoc: display resource elsif post? display resource, :status => :created, :location => api_location - elsif has_empty_resource_definition? - display empty_resource, :status => :ok else - head :ok + head :no_content end end @@ -269,24 +267,6 @@ module ActionController #:nodoc: @action ||= ACTIONS_FOR_VERBS[request.request_method_symbol] end - # Check whether resource needs a specific definition of empty resource to be valid - # - def has_empty_resource_definition? - respond_to?("empty_#{format}_resource") - end - - # Delegate to proper empty resource method - # - def empty_resource - send("empty_#{format}_resource") - end - - # Return a valid empty JSON resource - # - def empty_json_resource - "{}" - end - def resource_errors respond_to?("#{format}_resource_errors") ? send("#{format}_resource_errors") : resource.errors end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index e91e11a8a7..76a8c89e60 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -796,21 +796,21 @@ class RespondWithControllerTest < ActionController::TestCase end end - def test_using_resource_for_put_with_xml_yields_ok_on_success + def test_using_resource_for_put_with_xml_yields_no_content_on_success @request.accept = "application/xml" put :using_resource assert_equal "application/xml", @response.content_type - assert_equal 200, @response.status + assert_equal 204, @response.status assert_equal " ", @response.body end - def test_using_resource_for_put_with_json_yields_ok_on_success + def test_using_resource_for_put_with_json_yields_no_content_on_success Customer.any_instance.stubs(:to_json).returns('{"name": "David"}') @request.accept = "application/json" put :using_resource assert_equal "application/json", @response.content_type - assert_equal 200, @response.status - assert_equal "{}", @response.body + assert_equal 204, @response.status + assert_equal " ", @response.body end def test_using_resource_for_put_with_xml_yields_unprocessable_entity_on_failure @@ -846,23 +846,23 @@ class RespondWithControllerTest < ActionController::TestCase end end - def test_using_resource_for_delete_with_xml_yields_ok_on_success + def test_using_resource_for_delete_with_xml_yields_no_content_on_success Customer.any_instance.stubs(:destroyed?).returns(true) @request.accept = "application/xml" delete :using_resource assert_equal "application/xml", @response.content_type - assert_equal 200, @response.status + assert_equal 204, @response.status assert_equal " ", @response.body end - def test_using_resource_for_delete_with_json_yields_ok_on_success + def test_using_resource_for_delete_with_json_yields_no_content_on_success Customer.any_instance.stubs(:to_json).returns('{"name": "David"}') Customer.any_instance.stubs(:destroyed?).returns(true) @request.accept = "application/json" delete :using_resource assert_equal "application/json", @response.content_type - assert_equal 200, @response.status - assert_equal "{}", @response.body + assert_equal 204, @response.status + assert_equal " ", @response.body end def test_using_resource_for_delete_with_html_redirects_on_failure -- cgit v1.2.3 From 2e62af310d98fba78f338d916f7c17996446bc40 Mon Sep 17 00:00:00 2001 From: bradrobertson Date: Wed, 26 Oct 2011 09:31:37 -0400 Subject: correct documentation on initialize method to accept a single parameter --- activemodel/lib/active_model/validator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb index 0e444738ba..35ec98c822 100644 --- a/activemodel/lib/active_model/validator.rb +++ b/activemodel/lib/active_model/validator.rb @@ -57,7 +57,7 @@ module ActiveModel #:nodoc: # To add behavior to the initialize method, use the following signature: # # class MyValidator < ActiveModel::Validator - # def initialize(record, options) + # def initialize(options) # super # @my_custom_field = options[:field_name] || :first_name # end -- cgit v1.2.3 From 0d0176c4ffe5c58fd1002efbd8f7bd45a8872e33 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 26 Oct 2011 18:20:12 +0100 Subject: Allow instances to disable record_timestamps --- activerecord/lib/active_record/timestamp.rb | 2 +- activerecord/test/cases/timestamp_test.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index 4d5e469a7f..0c760e9850 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -33,7 +33,7 @@ module ActiveRecord extend ActiveSupport::Concern included do - class_attribute :record_timestamps, :instance_writer => false + class_attribute :record_timestamps self.record_timestamps = true end diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb index 4445a12e1d..447aa29ffe 100644 --- a/activerecord/test/cases/timestamp_test.rb +++ b/activerecord/test/cases/timestamp_test.rb @@ -60,6 +60,16 @@ class TimestampTest < ActiveRecord::TestCase Developer.record_timestamps = true end + def test_saving_when_instance_record_timestamps_is_false_doesnt_update_its_timestamp + @developer.record_timestamps = false + assert Developer.record_timestamps + + @developer.name = "John Smith" + @developer.save! + + assert_equal @previously_updated_at, @developer.updated_at + end + def test_touching_an_attribute_updates_timestamp previously_created_at = @developer.created_at @developer.touch(:created_at) -- cgit v1.2.3 From 902764379838d0d2b98e262c4039b7069cada3f8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 26 Oct 2011 10:30:14 -0700 Subject: scumbag 1.8: strings are enumerable :'( --- actionpack/lib/action_view/helpers/form_options_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 1a6c3b9740..f895cad058 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -584,7 +584,7 @@ module ActionView # [nil, []] # { nil => [] } # - if !choices.empty? && choices.first.last.respond_to?(:each) + if !choices.empty? && Array === choices.first.last option_tags = grouped_options_for_select(choices, :selected => selected_value, :disabled => options[:disabled]) else option_tags = options_for_select(choices, :selected => selected_value, :disabled => options[:disabled]) -- cgit v1.2.3 From 177f893a28ca2bdf2bdb204e8af139ed90f3266d Mon Sep 17 00:00:00 2001 From: Denis Odorcic Date: Thu, 27 Oct 2011 02:16:59 -0400 Subject: Fix railtie configuration test calling PostsController#create which didn't exist --- railties/test/application/configuration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 97ad47ac14..f356805d6e 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -476,7 +476,7 @@ module ApplicationTests app_file 'app/controllers/posts_controller.rb', <<-RUBY class PostsController < ApplicationController - def index + def create render :text => params[:post].inspect end end -- cgit v1.2.3 From 485b99611b22bb77cbc476ecd65d19b59fa719a8 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 27 Oct 2011 15:41:15 +0530 Subject: Test fix Allow instances to disable record_timestamps Removed here 0d0176c4ffe5c58fd1002efbd8f7bd45a8872e33 --- activerecord/test/cases/mass_assignment_security_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb index ef35f3341e..a47842f5e0 100644 --- a/activerecord/test/cases/mass_assignment_security_test.rb +++ b/activerecord/test/cases/mass_assignment_security_test.rb @@ -231,7 +231,7 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase def test_protection_against_class_attribute_writers [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, - :default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method| + :default_timezone, :schema_format, :lock_optimistically].each do |method| assert_respond_to Task, method assert_respond_to Task, "#{method}=" assert_respond_to Task.new, method -- cgit v1.2.3 From 80fc29f36f0410c3beabe54c54823f1f335f96f3 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 27 Oct 2011 15:47:56 +0530 Subject: Adding more checks for instance_writer false --- activerecord/test/cases/mass_assignment_security_test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb index a47842f5e0..23961918f4 100644 --- a/activerecord/test/cases/mass_assignment_security_test.rb +++ b/activerecord/test/cases/mass_assignment_security_test.rb @@ -231,7 +231,8 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase def test_protection_against_class_attribute_writers [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, - :default_timezone, :schema_format, :lock_optimistically].each do |method| + :default_timezone, :schema_format, :lock_optimistically, :timestamped_migrations, :default_scopes, + :connection_handler, :nested_attributes_options].each do |method| assert_respond_to Task, method assert_respond_to Task, "#{method}=" assert_respond_to Task.new, method -- cgit v1.2.3 From 95d9c120d3bdf54173a10b25bbcbf1138815ff2e Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 27 Oct 2011 16:25:50 +0530 Subject: More checks for instance writers. --- activerecord/test/cases/mass_assignment_security_test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb index 23961918f4..9fff50edcb 100644 --- a/activerecord/test/cases/mass_assignment_security_test.rb +++ b/activerecord/test/cases/mass_assignment_security_test.rb @@ -232,7 +232,8 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase def test_protection_against_class_attribute_writers [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :default_timezone, :schema_format, :lock_optimistically, :timestamped_migrations, :default_scopes, - :connection_handler, :nested_attributes_options].each do |method| + :connection_handler, :nested_attributes_options, :_attr_readonly, :attribute_types_cached_by_default, + :attribute_method_matchers, :time_zone_aware_attributes, :skip_time_zone_conversion_for_attributes].each do |method| assert_respond_to Task, method assert_respond_to Task, "#{method}=" assert_respond_to Task.new, method -- cgit v1.2.3 From 420f7fd507fd5868adc1e0398c2422aac16d2013 Mon Sep 17 00:00:00 2001 From: Joe Van Dyk Date: Thu, 27 Oct 2011 08:25:42 -0700 Subject: Added failing test case for changing schema in migration not clearing the prepared statement cache --- activerecord/test/cases/query_cache_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index b2429d631f..9554386dcf 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -170,6 +170,18 @@ end class QueryCacheExpiryTest < ActiveRecord::TestCase fixtures :tasks, :posts, :categories, :categories_posts + def test_cache_gets_cleared_after_migration + # warm the cache + Post.find(1) + + # change the column definition + Post.connection.change_column :posts, :title, :string, :limit => 80 + assert_nothing_raised { Post.find(1) } + + # restore the old definition + Post.connection.change_column :posts, :title, :string + end + def test_find Task.connection.expects(:clear_query_cache).times(1) -- cgit v1.2.3 From 4a065d56edcafacc99196522ea35fe28c5f45937 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 27 Oct 2011 10:55:52 -0700 Subject: clear statement cache when tables are altered --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 3d084bb178..e8a43e7bce 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -922,12 +922,14 @@ module ActiveRecord # Example: # rename_table('octopuses', 'octopi') def rename_table(name, new_name) + clear_cache! execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}" end # Adds a new column to the named table. # See TableDefinition#column for details of the options you can use. def add_column(table_name, column_name, type, options = {}) + clear_cache! add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" add_column_options!(add_column_sql, options) @@ -936,6 +938,7 @@ module ActiveRecord # Changes the column of a table. def change_column(table_name, column_name, type, options = {}) + clear_cache! quoted_table_name = quote_table_name(table_name) execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" @@ -946,10 +949,12 @@ module ActiveRecord # Changes the default value of a table column. def change_column_default(table_name, column_name, default) + clear_cache! execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}" end def change_column_null(table_name, column_name, null, default = nil) + clear_cache! unless null || default.nil? execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") end @@ -958,6 +963,7 @@ module ActiveRecord # Renames a column in a table. def rename_column(table_name, column_name, new_column_name) + clear_cache! execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}" end -- cgit v1.2.3 From 07c4297282c9c2d0768922722ad2ab08dedf4d8d Mon Sep 17 00:00:00 2001 From: Paul McMahon Date: Fri, 28 Oct 2011 15:34:12 +0900 Subject: Add missing type to number_field_tag documentation --- actionpack/lib/action_view/helpers/form_tag_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 13b9dc8553..1424a3584d 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -582,7 +582,7 @@ module ActionView # # ==== Examples # number_field_tag 'quantity', nil, :in => 1...10 - # => + # => def number_field_tag(name, value = nil, options = {}) options = options.stringify_keys options["type"] ||= "number" -- cgit v1.2.3 From f936996f69ec728b7c0d38cd30084fc74943f9c7 Mon Sep 17 00:00:00 2001 From: Joost Baaij Date: Fri, 28 Oct 2011 13:24:14 +0200 Subject: Updated links to authentication plugins. Removed mention of restful_authentication. Added devise and authlogic. Also mention Rails 3.1 built-in logic. --- railties/guides/source/security.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index a499ef3d39..c2ef7bf9b5 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -474,7 +474,7 @@ h3. User Management -- _Almost every web application has to deal with authorization and authentication. Instead of rolling your own, it is advisable to use common plug-ins. But keep them up-to-date, too. A few additional precautions can make your application even more secure._ -There are some authorization and authentication plug-ins for Rails available. A good one saves only encrypted passwords, not plain-text passwords. The most popular plug-in is +restful_authentication+ which protects from session fixation, too. However, earlier versions allowed you to login without user name and password in certain circumstances. +There are a number of authentication plug-ins for Rails available. Good ones, such as the popular "devise":https://github.com/plataformatec/devise and "authlogic":https://github.com/binarylogic/authlogic, store only encrypted passwords, not plain-text passwords. In Rails 3.1 you can use the built-in +has_secure_password+ method which has similar features. Every new user gets an activation code to activate his account when he gets an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested an URL like these, he would be logged in as the first activated user found in the database (and chances are that this is the administrator): -- cgit v1.2.3 From 0c7c1dbc41414c12799f339c87e1c04327e9def9 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 29 Oct 2011 12:34:08 +0530 Subject: ActiveRecord is no more in controller directory. --- actionpack/RUNNING_UNIT_TESTS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/RUNNING_UNIT_TESTS b/actionpack/RUNNING_UNIT_TESTS index 1e3ba7abe7..1b29abd2d1 100644 --- a/actionpack/RUNNING_UNIT_TESTS +++ b/actionpack/RUNNING_UNIT_TESTS @@ -18,7 +18,7 @@ which can be further narrowed down to one test: == Dependency on Active Record and database setup -Test cases in the test/controller/active_record/ directory depend on having +Test cases in the test/active_record/ directory depend on having activerecord and sqlite installed. If Active Record is not in actionpack/../activerecord directory, or the sqlite rubygem is not installed, these tests are skipped. -- cgit v1.2.3 From 0fc531392d1f606054a6d6e394304c72a846d4c8 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 29 Oct 2011 01:07:54 -0700 Subject: let demodulize do less work, and add tests This is also faster on 1.9. --- activesupport/lib/active_support/inflector/methods.rb | 4 +++- activesupport/test/inflector_test.rb | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 934529d496..454637191e 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -166,7 +166,9 @@ module ActiveSupport # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections" # "Inflections".demodulize # => "Inflections" def demodulize(class_name_in_module) - class_name_in_module.to_s.gsub(/^.*::/, '') + # If you remove the module part of an empty string, you get an empty string. + # That's why the regexp uses the * quantifier. + class_name_in_module.to_s[/[^:]*\z/] end # Creates a foreign key name from a class name. diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index 5c956e0075..7d15b3c7e5 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -194,6 +194,8 @@ class InflectorTest < Test::Unit::TestCase def test_demodulize assert_equal "Account", ActiveSupport::Inflector.demodulize("MyApplication::Billing::Account") + assert_equal "Account", ActiveSupport::Inflector.demodulize("Account") + assert_equal "", ActiveSupport::Inflector.demodulize("") end def test_foreign_key -- cgit v1.2.3 From 3fa8f362ad09a6f94ab012094014e31513ee36e0 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Sat, 29 Oct 2011 15:45:04 +0530 Subject: method redefined warning removed! --- railties/lib/rails/test_unit/testing.rake | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index fa01f42c5b..3d87529ad4 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -61,6 +61,7 @@ end # Recreated here from Active Support because :uncommitted needs it before Rails is available module Kernel + remove_method :silence_stderr # Removing old method to prevent method redefined warning def silence_stderr old_stderr = STDERR.dup STDERR.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null') -- cgit v1.2.3 From 010622bb989cb9fa3aac600a7fa7bcb894bb081a Mon Sep 17 00:00:00 2001 From: Hendy Tanata Date: Sat, 15 Oct 2011 17:20:54 +0800 Subject: On inpsect routes, show :controller and :action to indicate dynamic. --- railties/lib/rails/application/route_inspector.rb | 15 ++++++++------- railties/test/application/route_inspect_test.rb | 12 ++++++++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/railties/lib/rails/application/route_inspector.rb b/railties/lib/rails/application/route_inspector.rb index 8c6911e6bb..8252f21aa7 100644 --- a/railties/lib/rails/application/route_inspector.rb +++ b/railties/lib/rails/application/route_inspector.rb @@ -10,20 +10,21 @@ module Rails end routes = all_routes.collect do |route| + route_reqs = route.requirements - reqs = route.requirements.dup rack_app = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/ - endpoint = rack_app ? rack_app.inspect : "#{reqs[:controller]}##{reqs[:action]}" - constraints = reqs.except(:controller, :action) + controller = route_reqs[:controller] || ':controller' + action = route_reqs[:action] || ':action' - reqs = endpoint == '#' ? '' : endpoint + endpoint = rack_app ? rack_app.inspect : "#{controller}##{action}" + constraints = route_reqs.except(:controller, :action) - unless constraints.empty? - reqs = reqs.empty? ? constraints.inspect : "#{reqs} #{constraints.inspect}" - end + reqs = endpoint + reqs += " #{constraints.inspect}" unless constraints.empty? verb = route.verb.source.gsub(/[$^]/, '') + {:name => route.name.to_s, :verb => verb, :path => route.path.spec.to_s, :reqs => reqs} end diff --git a/railties/test/application/route_inspect_test.rb b/railties/test/application/route_inspect_test.rb index add8256b5d..78980705ed 100644 --- a/railties/test/application/route_inspect_test.rb +++ b/railties/test/application/route_inspect_test.rb @@ -49,12 +49,20 @@ module ApplicationTests assert_equal ["root / pages#main"], output end + def test_inspect_routes_shows_dynamic_action_route + @set.draw do + match 'api/:action' => 'api' + end + output = @inspector.format @set.routes + assert_equal [" /api/:action(.:format) api#:action"], output + end + def test_inspect_routes_shows_controller_and_action_only_route @set.draw do match ':controller/:action' end output = @inspector.format @set.routes - assert_equal [" /:controller/:action(.:format) "], output + assert_equal [" /:controller/:action(.:format) :controller#:action"], output end def test_inspect_routes_shows_controller_and_action_route_with_constraints @@ -62,7 +70,7 @@ module ApplicationTests match ':controller(/:action(/:id))', :id => /\d+/ end output = @inspector.format @set.routes - assert_equal [" /:controller(/:action(/:id))(.:format) {:id=>/\\d+/}"], output + assert_equal [" /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"], output end def test_rake_routes_shows_route_with_defaults -- cgit v1.2.3 From 596d625c9b7f3a95cb8460d495b328d322d5bee6 Mon Sep 17 00:00:00 2001 From: kennyj Date: Sun, 30 Oct 2011 01:32:02 +0900 Subject: removed reference to SynchronizedMemoryStore and CompressedMemCacheStore (the remaining code from 9cafc28874) --- activesupport/lib/active_support/cache.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 95d936b32f..8cb74b2a86 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -16,8 +16,6 @@ module ActiveSupport autoload :FileStore, 'active_support/cache/file_store' autoload :MemoryStore, 'active_support/cache/memory_store' autoload :MemCacheStore, 'active_support/cache/mem_cache_store' - autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store' - autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store' # These options mean something to all cache implementations. Individual cache # implementations may support additional options. -- cgit v1.2.3 From 7b65d12db5951682666a41fe864b53ad5ec510ac Mon Sep 17 00:00:00 2001 From: kennyj Date: Sun, 30 Oct 2011 01:55:09 +0900 Subject: fix a document for race_condition_ttl. ActiveSupport::Cache::MemoryCache isn't exist --- activesupport/lib/active_support/cache.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 95d936b32f..b9cdd9c6b3 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -232,7 +232,7 @@ module ActiveSupport # :race_condition_ttl does not play any role. # # # Set all values to expire after one minute. - # cache = ActiveSupport::Cache::MemoryCache.new(:expires_in => 1.minute) + # cache = ActiveSupport::Cache::MemoryStore.new(:expires_in => 1.minute) # # cache.write("foo", "original value") # val_1 = nil -- cgit v1.2.3 From 3b546afd049221fd4aa407d6b99f1c4de312c704 Mon Sep 17 00:00:00 2001 From: kennyj Date: Sun, 30 Oct 2011 03:14:35 +0900 Subject: avoided to call twice --- activesupport/lib/active_support/cache.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 8cb74b2a86..df3602f860 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -559,7 +559,7 @@ module ActiveSupport @value = nil else @value = Marshal.dump(value) - if should_compress?(value, options) + if should_compress?(@value, options) @value = Zlib::Deflate.deflate(@value) @compressed = true end @@ -613,13 +613,10 @@ module ActiveSupport end private - def should_compress?(value, options) - if options[:compress] && value - unless value.is_a?(Numeric) - compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT - serialized_value = value.is_a?(String) ? value : Marshal.dump(value) - return true if serialized_value.size >= compress_threshold - end + def should_compress?(serialized_value, options) + if options[:compress] + compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT + return true if serialized_value.size >= compress_threshold end false end -- cgit v1.2.3 From eabda416b7c66f3b8d03237e7334bd2d14ff9190 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 29 Oct 2011 14:14:13 -0700 Subject: Removing db/seeds.rb is fine. Don't blow up. --- railties/lib/rails/engine.rb | 2 +- railties/test/railties/engine_test.rb | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 2d25273050..1c9627734e 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -488,7 +488,7 @@ module Rails # Blog::Engine.load_seed def load_seed seed_file = paths["db/seeds"].existent.first - load(seed_file) if File.exist?(seed_file) + load(seed_file) if seed_file && File.exist?(seed_file) end # Add configured load paths to ruby load paths and remove duplicates. diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 06a60cd858..22dbcf9644 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -455,12 +455,18 @@ module RailtiesTest Rails.application.load_seed assert Rails.application.config.app_seeds_loaded - assert_raise(NoMethodError) do Bukkits::Engine.config.bukkits_seeds_loaded end + assert_raise(NoMethodError) { Bukkits::Engine.config.bukkits_seeds_loaded } Bukkits::Engine.load_seed assert Bukkits::Engine.config.bukkits_seeds_loaded end + test "skips nonexistent seed data" do + FileUtils.rm "#{app_path}/db/seeds.rb" + boot_rails + assert_nil Rails.application.load_seed + end + test "using namespace more than once on one module should not overwrite _railtie method" do @plugin.write "lib/bukkits.rb", <<-RUBY module AppTemplate -- cgit v1.2.3 From 11f6795b238172c4a13176062bd38b83285799b7 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 29 Oct 2011 18:03:35 -0700 Subject: defines Module#qualified_const_(defined?|get|set) and String#deconstantize This commit also implements a faster version of #demodulize I was unable to isolate with git add --patch. Not a big fan of the name #deconstantize. It complements #demodulize getting rid of the rightmost constant, hence the name, but it is unrelated to the well-known #constantize. So unsure. Could not come with anything better, please feel free to rename. --- activesupport/CHANGELOG | 6 ++ .../lib/active_support/core_ext/module.rb | 3 +- .../core_ext/module/qualified_const.rb | 64 +++++++++++++++ .../active_support/core_ext/string/inflections.rb | 15 ++++ activesupport/lib/active_support/dependencies.rb | 14 ++-- .../lib/active_support/inflector/methods.rb | 29 +++++-- .../test/core_ext/module/qualified_const_test.rb | 94 ++++++++++++++++++++++ activesupport/test/core_ext/string_ext_test.rb | 4 + activesupport/test/inflector_test.rb | 12 +++ .../source/active_support_core_extensions.textile | 83 +++++++++++++++++++ 10 files changed, 311 insertions(+), 13 deletions(-) create mode 100644 activesupport/lib/active_support/core_ext/module/qualified_const.rb create mode 100644 activesupport/test/core_ext/module/qualified_const_test.rb diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index d3a838cff0..8609198641 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,11 @@ *Rails 3.2.0 (unreleased)* +* Module#qualified_const_(defined?|get|set) are analogous to the corresponding methods + in the standard API, but accept qualified constant names. [fxn] + +* Added inflection #deconstantize which complements #demodulize. This inflection + removes the righmost segment in a qualified constant name. [fxn] + * Added ActiveSupport:TaggedLogging that can wrap any standard Logger class to provide tagging capabilities [DHH] Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb index 9fed346b7c..f399fce410 100644 --- a/activesupport/lib/active_support/core_ext/module.rb +++ b/activesupport/lib/active_support/core_ext/module.rb @@ -8,4 +8,5 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/module/synchronization' require 'active_support/core_ext/module/deprecation' require 'active_support/core_ext/module/remove_method' -require 'active_support/core_ext/module/method_names' \ No newline at end of file +require 'active_support/core_ext/module/method_names' +require 'active_support/core_ext/module/qualified_const' \ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/module/qualified_const.rb b/activesupport/lib/active_support/core_ext/module/qualified_const.rb new file mode 100644 index 0000000000..d1a0ee2f83 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/module/qualified_const.rb @@ -0,0 +1,64 @@ +require 'active_support/core_ext/string/inflections' + +#-- +# Allows code reuse in the methods below without polluting Module. +#++ +module QualifiedConstUtils + def self.raise_if_absolute(path) + raise NameError, "wrong constant name #$&" if path =~ /\A::[^:]+/ + end + + def self.names(path) + path.split('::') + end +end + +## +# Extends the API for constants to be able to deal with qualified names. Arguments +# are assumed to be relative to the receiver. +# +#-- +# Qualified names are required to be relative because we are extending existing +# methods that expect constant names, ie, relative paths of length 1. For example, +# Object.const_get("::String") raises NameError and so does qualified_const_get. +#++ +class Module + if method(:const_defined?).arity == 1 + def qualified_const_defined?(path) + QualifiedConstUtils.raise_if_absolute(path) + + QualifiedConstUtils.names(path).inject(self) do |mod, name| + return unless mod.const_defined?(name) + mod.const_get(name) + end + return true + end + else + def qualified_const_defined?(path, search_parents=true) + QualifiedConstUtils.raise_if_absolute(path) + + QualifiedConstUtils.names(path).inject(self) do |mod, name| + return unless mod.const_defined?(name, search_parents) + mod.const_get(name) + end + return true + end + end + + def qualified_const_get(path) + QualifiedConstUtils.raise_if_absolute(path) + + QualifiedConstUtils.names(path).inject(self) do |mod, name| + mod.const_get(name) + end + end + + def qualified_const_set(path, value) + QualifiedConstUtils.raise_if_absolute(path) + + const_name = path.demodulize + mod_name = path.deconstantize + mod = mod_name.empty? ? self : qualified_const_get(mod_name) + mod.const_set(const_name, value) + end +end diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index fd91b3cacb..9356940650 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -117,10 +117,25 @@ class String # # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections" # "Inflections".demodulize # => "Inflections" + # + # See also +deconstatize+. def demodulize ActiveSupport::Inflector.demodulize(self) end + # Removes the rightmost segment from the constant expression in the string. + # + # "Net::HTTP".deconstantize # => "Net" + # "::Net::HTTP".deconstantize # => "::Net" + # "String".deconstantize # => "" + # "::String".deconstantize # => "" + # "".deconstantize # => "" + # + # See also +demodulize+. + def deconstantize + ActiveSupport::Inflector.deconstantize(self) + end + # Replaces special characters in a string so that it may be used as part of a 'pretty' URL. # # ==== Examples diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index c072a8e646..b3ac271778 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -5,6 +5,7 @@ require 'active_support/core_ext/module/aliasing' require 'active_support/core_ext/module/attribute_accessors' require 'active_support/core_ext/module/introspection' require 'active_support/core_ext/module/anonymous' +require 'active_support/core_ext/module/qualified_const' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/load_error' require 'active_support/core_ext/name_error' @@ -357,12 +358,13 @@ module ActiveSupport #:nodoc: end # Is the provided constant path defined? - def qualified_const_defined?(path) - names = path.sub(/^::/, '').to_s.split('::') - - names.inject(Object) do |mod, name| - return false unless local_const_defined?(mod, name) - mod.const_get name + if Module.method(:const_defined?).arity == 1 + def qualified_const_defined?(path) + Object.qualified_const_defined?(path.sub(/^::/, '')) + end + else + def qualified_const_defined?(path) + Object.qualified_const_defined?(path.sub(/^::/, ''), false) end end diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 454637191e..e76ee60dd7 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -160,15 +160,32 @@ module ActiveSupport underscored_word.gsub(/_/, '-') end - # Removes the module part from the expression in the string. + # Removes the module part from the expression in the string: # - # Examples: # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections" # "Inflections".demodulize # => "Inflections" - def demodulize(class_name_in_module) - # If you remove the module part of an empty string, you get an empty string. - # That's why the regexp uses the * quantifier. - class_name_in_module.to_s[/[^:]*\z/] + # + # See also +deconstantize+. + def demodulize(path) + path = path.to_s + if i = path.rindex('::') + path[(i+2)..-1] + else + path + end + end + + # Removes the rightmost segment from the constant expression in the string: + # + # "Net::HTTP".deconstantize # => "Net" + # "::Net::HTTP".deconstantize # => "::Net" + # "String".deconstantize # => "" + # "::String".deconstantize # => "" + # "".deconstantize # => "" + # + # See also +demodulize+. + def deconstantize(path) + path.to_s[0...(path.rindex('::') || 0)] # implementation based on the one in facets' Module#spacename end # Creates a foreign key name from a class name. diff --git a/activesupport/test/core_ext/module/qualified_const_test.rb b/activesupport/test/core_ext/module/qualified_const_test.rb new file mode 100644 index 0000000000..8af0b9a023 --- /dev/null +++ b/activesupport/test/core_ext/module/qualified_const_test.rb @@ -0,0 +1,94 @@ +require 'abstract_unit' +require 'active_support/core_ext/module/qualified_const' + +module QualifiedConstTestMod + X = false + + module M + X = 1 + + class C + X = 2 + end + end + + module N + include M + end +end + +class QualifiedConstTest < ActiveSupport::TestCase + test "Object.qualified_const_defined?" do + assert Object.qualified_const_defined?("QualifiedConstTestMod") + assert !Object.qualified_const_defined?("NonExistingQualifiedConstTestMod") + + assert Object.qualified_const_defined?("QualifiedConstTestMod::X") + assert !Object.qualified_const_defined?("QualifiedConstTestMod::Y") + + assert Object.qualified_const_defined?("QualifiedConstTestMod::M::X") + assert !Object.qualified_const_defined?("QualifiedConstTestMod::M::Y") + + if Module.method(:const_defined?).arity == 1 + assert !Object.qualified_const_defined?("QualifiedConstTestMod::N::X") + else + assert Object.qualified_const_defined?("QualifiedConstTestMod::N::X") + assert !Object.qualified_const_defined?("QualifiedConstTestMod::N::X", false) + assert Object.qualified_const_defined?("QualifiedConstTestMod::N::X", true) + end + end + + test "mod.qualified_const_defined?" do + assert QualifiedConstTestMod.qualified_const_defined?("M") + assert !QualifiedConstTestMod.qualified_const_defined?("NonExistingM") + + assert QualifiedConstTestMod.qualified_const_defined?("M::X") + assert !QualifiedConstTestMod.qualified_const_defined?("M::Y") + + assert QualifiedConstTestMod.qualified_const_defined?("M::C::X") + assert !QualifiedConstTestMod.qualified_const_defined?("M::C::Y") + + if Module.method(:const_defined?).arity == 1 + assert !QualifiedConstTestMod.qualified_const_defined?("QualifiedConstTestMod::N::X") + else + assert QualifiedConstTestMod.qualified_const_defined?("N::X") + assert !QualifiedConstTestMod.qualified_const_defined?("N::X", false) + assert QualifiedConstTestMod.qualified_const_defined?("N::X", true) + end + end + + test "qualified_const_get" do + assert_equal false, Object.qualified_const_get("QualifiedConstTestMod::X") + assert_equal false, QualifiedConstTestMod.qualified_const_get("X") + assert_equal 1, QualifiedConstTestMod.qualified_const_get("M::X") + assert_equal 1, QualifiedConstTestMod.qualified_const_get("N::X") + assert_equal 2, QualifiedConstTestMod.qualified_const_get("M::C::X") + + assert_raise(NameError) { QualifiedConstTestMod.qualified_const_get("M::C::Y")} + end + + test "qualified_const_set" do + m = Module.new + assert_equal m, Object.qualified_const_set("QualifiedConstTestMod2", m) + assert_equal m, ::QualifiedConstTestMod2 + + # We are going to assign to existing constants on purpose, so silence warnings. + silence_warnings do + assert_equal true, QualifiedConstTestMod.qualified_const_set("QualifiedConstTestMod::X", true) + assert_equal true, QualifiedConstTestMod::X + + assert_equal 10, QualifiedConstTestMod::M.qualified_const_set("X", 10) + assert_equal 10, QualifiedConstTestMod::M::X + end + end + + test "reject absolute paths" do + assert_raise(NameError, "wrong constant name ::X") { Object.qualified_const_defined?("::X")} + assert_raise(NameError, "wrong constant name ::X") { Object.qualified_const_defined?("::X::Y")} + + assert_raise(NameError, "wrong constant name ::X") { Object.qualified_const_get("::X")} + assert_raise(NameError, "wrong constant name ::X") { Object.qualified_const_get("::X::Y")} + + assert_raise(NameError, "wrong constant name ::X") { Object.qualified_const_set("::X", nil)} + assert_raise(NameError, "wrong constant name ::X") { Object.qualified_const_set("::X::Y", nil)} + end +end diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 4d876954cf..ade09efc56 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -111,6 +111,10 @@ class StringInflectionsTest < Test::Unit::TestCase assert_equal "Account", "MyApplication::Billing::Account".demodulize end + def test_deconstantize + assert_equal "MyApplication::Billing", "MyApplication::Billing::Account".deconstantize + end + def test_foreign_key ClassNameToForeignKeyWithUnderscore.each do |klass, foreign_key| assert_equal(foreign_key, klass.foreign_key) diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index 7d15b3c7e5..6b7e839e43 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -198,6 +198,18 @@ class InflectorTest < Test::Unit::TestCase assert_equal "", ActiveSupport::Inflector.demodulize("") end + def test_deconstantize + assert_equal "MyApplication::Billing", ActiveSupport::Inflector.deconstantize("MyApplication::Billing::Account") + assert_equal "::MyApplication::Billing", ActiveSupport::Inflector.deconstantize("::MyApplication::Billing::Account") + + assert_equal "MyApplication", ActiveSupport::Inflector.deconstantize("MyApplication::Billing") + assert_equal "::MyApplication", ActiveSupport::Inflector.deconstantize("::MyApplication::Billing") + + assert_equal "", ActiveSupport::Inflector.deconstantize("Account") + assert_equal "", ActiveSupport::Inflector.deconstantize("::Account") + assert_equal "", ActiveSupport::Inflector.deconstantize("") + end + def test_foreign_key ClassNameToForeignKeyWithUnderscore.each do |klass, foreign_key| assert_equal(foreign_key, ActiveSupport::Inflector.foreign_key(klass)) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index c04e49281e..0941953d1c 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -725,6 +725,64 @@ WARNING: This method returns precise results in Ruby 1.9. In older versions of R NOTE: Defined in +active_support/core_ext/module/introspection.rb+. +h5. Qualified Constant Names + +The standard methods +const_defined?+, +const_get+ , and +const_set+ accept +bare constant names. Active Support extends this API to be able to pass +relative qualified constant reference expressions. + +The new methods are +qualified_const_defined?+, +qualified_const_get+, and ++qualified_const_set+. Their arguments are assumed to be qualified constant +names relative to their receiver: + + +Object.qualified_const_defined?("Math::PI") # => true +Object.qualified_const_get("Math::PI") # => 3.141592653589793 +Object.qualified_const_set("Math::Phi", 1.618034) # => 1.618034 + + +Arguments may be bare constant names: + + +Math.qualified_const_get("E") # => 2.718281828459045 + + +These methods are analogous to their builtin counterparts. In particular, ++qualified_constant_defined?+ accepts an optional second argument in 1.9 +to be able to say whether you want the predicate to look in the ancestors. +This flag is taken into account for each constant in the expression while +walking down the path. + +For example, given + + +module M + X = 1 +end + +module N + class C + include M + end +end + + ++qualified_const_defined?+ behaves this way: + + +N.qualified_const_defined?("C::X", false) # => false (1.9 only) +N.qualified_const_defined?("C::X", true) # => true (1.9 only) +N.qualified_const_defined?("C::X") # => false in 1.8, true in 1.9 + + +As the last example implies, in 1.9 the second argument defaults to true, +as in +const_defined?+. + +For coherence with the builtin methods only relative paths are accepted. +Absolute qualified constant names like +::Math::PI+ raise +NameError+. + +NOTE: Defined in +active_support/core_ext/module/qualified_const.rb+. + h4. Synchronization The +synchronize+ macro declares a method to be synchronized: @@ -1620,6 +1678,31 @@ end NOTE: Defined in +active_support/core_ext/string/inflections.rb+. +h5. +deconstantize+ + +Given a string with a qualified constant reference expression, +deconstantize+ removes the rightmost segment, generally leaving the name of the constant's container: + + +"Product".deconstantize # => "" +"Backoffice::UsersController".deconstantize # => "Backoffice" +"Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel" + + +Active Support for example uses this method in +Module#qualified_const_set+: + + +def qualified_const_set(path, value) + QualifiedConstUtils.raise_if_absolute(path) + + const_name = path.demodulize + mod_name = path.deconstantize + mod = mod_name.empty? ? self : qualified_const_get(mod_name) + mod.const_set(const_name, value) +end + + +NOTE: Defined in +active_support/core_ext/string/inflections.rb+. + h5. +parameterize+ The method +parameterize+ normalizes its receiver in a way that can be used in pretty URLs. -- cgit v1.2.3 From 9d1ba3755e9af6196240fc18472e2cc4fcbb4911 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 30 Oct 2011 02:08:59 -0700 Subject: fixes a typo (thanks to Alexey Vakhov) --- activesupport/lib/active_support/core_ext/string/inflections.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index 9356940650..1e57b586d9 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -118,7 +118,7 @@ class String # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections" # "Inflections".demodulize # => "Inflections" # - # See also +deconstatize+. + # See also +deconstantize+. def demodulize ActiveSupport::Inflector.demodulize(self) end -- cgit v1.2.3 From c6b933faa91107a8213f0e8e151f8f1a72f55cdc Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 30 Oct 2011 02:24:30 -0700 Subject: prefer qualified constant "name" to "reference expression", much simpler --- railties/guides/source/active_support_core_extensions.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 0941953d1c..ff6c5f967f 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -729,7 +729,7 @@ h5. Qualified Constant Names The standard methods +const_defined?+, +const_get+ , and +const_set+ accept bare constant names. Active Support extends this API to be able to pass -relative qualified constant reference expressions. +relative qualified constant names. The new methods are +qualified_const_defined?+, +qualified_const_get+, and +qualified_const_set+. Their arguments are assumed to be qualified constant @@ -1655,7 +1655,7 @@ NOTE: Defined in +active_support/core_ext/string/inflections.rb+. h5. +demodulize+ -Given a string with a qualified constant reference expression, +demodulize+ returns the very constant name, that is, the rightmost part of it: +Given a string with a qualified constant name, +demodulize+ returns the very constant name, that is, the rightmost part of it: "Product".demodulize # => "Product" -- cgit v1.2.3 From 38da6249f0449204e0806f3142c0342ad2565344 Mon Sep 17 00:00:00 2001 From: kennyj Date: Sun, 30 Oct 2011 19:18:23 +0900 Subject: fix a document for :compress_threshold. DEFAULT_COMPRESS_LIMIT is 16K. --- activesupport/lib/active_support/cache.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 8b45efaf2a..6535cc1eb5 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -139,7 +139,7 @@ module ActiveSupport # large enough to warrant compression. To turn on compression either pass # :compress => true in the initializer or as an option to +fetch+ # or +write+. To specify the threshold at which to compress values, set the - # :compress_threshold option. The default threshold is 32K. + # :compress_threshold option. The default threshold is 16K. class Store cattr_accessor :logger, :instance_writer => true -- cgit v1.2.3 From 7670a5187d2000a577c9aa982158808550033dfd Mon Sep 17 00:00:00 2001 From: kennyj Date: Sun, 30 Oct 2011 21:50:17 +0900 Subject: Refactor ActiveSupport::Cache::FileStore. used method and deleted duplicate code. --- activesupport/lib/active_support/cache/file_store.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index b431041b76..85e7e21624 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -14,6 +14,7 @@ module ActiveSupport DIR_FORMATTER = "%03X" FILENAME_MAX_SIZE = 230 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write) + EXCLUDED_DIRS = ['.', '..'].freeze def initialize(cache_path, options = nil) super(options) @@ -22,7 +23,7 @@ module ActiveSupport end def clear(options = nil) - root_dirs = Dir.entries(cache_path).reject{|f| f.in?(['.', '..'])} + root_dirs = Dir.entries(cache_path).reject{|f| f.in?(EXCLUDED_DIRS)} FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) end @@ -149,7 +150,7 @@ module ActiveSupport # Delete empty directories in the cache. def delete_empty_directories(dir) return if dir == cache_path - if Dir.entries(dir).reject{|f| f.in?(['.', '..'])}.empty? + if Dir.entries(dir).reject{|f| f.in?(EXCLUDED_DIRS)}.empty? File.delete(dir) rescue nil delete_empty_directories(File.dirname(dir)) end @@ -163,7 +164,7 @@ module ActiveSupport def search_dir(dir, &callback) return if !File.exist?(dir) Dir.foreach(dir) do |d| - next if d == "." || d == ".." + next if d.in?(EXCLUDED_DIRS) name = File.join(dir, d) if File.directory?(name) search_dir(name, &callback) -- cgit v1.2.3 From 2d337ef080aec2c2e21ede3451f652ab5eaadca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Silva?= Date: Sun, 30 Oct 2011 18:34:49 -0200 Subject: Fix typo on the performance test guide --- railties/guides/source/performance_testing.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile index f3ea7e38bc..2440927542 100644 --- a/railties/guides/source/performance_testing.textile +++ b/railties/guides/source/performance_testing.textile @@ -447,7 +447,7 @@ h4. Using Ruby-Prof on MRI and REE Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile under MRI or REE: -gem 'ruby-prof', :path => 'git://github.com/wycats/ruby-prof.git' +gem 'ruby-prof', :git => 'git://github.com/wycats/ruby-prof.git' Now run +bundle install+ and you're ready to go. -- cgit v1.2.3 From d106b34bd582483ebae57f8fa57f8d3649a31829 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Mon, 31 Oct 2011 10:36:38 +0400 Subject: Update routing guides, root route should be at the top of the file --- railties/guides/source/routing.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index f281009fee..29c729592b 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -620,7 +620,7 @@ You can specify what Rails should route +"/"+ to with the +root+ method: root :to => 'pages#main' -You should put the +root+ route at the end of the file. You also need to delete the +public/index.html+ file for the root route to take effect. +You should put the +root+ route at the top of the file, because it is the most popular route and should be matched first. You also need to delete the +public/index.html+ file for the root route to take effect. h3. Customizing Resourceful Routes -- cgit v1.2.3 From ff9c2799c1a065fb132df64da6d19683c647b5b4 Mon Sep 17 00:00:00 2001 From: Laust Rud Jacobsen Date: Tue, 1 Nov 2011 07:29:48 +0100 Subject: dump_schema_information: explicitly order inserts into schema_migrations table This change reduces churn in the db/development_structure.sql file when using :sql as active_record.schema_format, and makes comparing diffs much easier. Test ensures the output SQL-statements are lexically ordered by version. --- .../connection_adapters/abstract/schema_statements.rb | 2 +- activerecord/test/cases/migration_test.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index b4a9e29ef1..910ef3efce 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -405,7 +405,7 @@ module ActiveRecord def dump_schema_information #:nodoc: sm_table = ActiveRecord::Migrator.schema_migrations_table_name - migrated = select_values("SELECT version FROM #{sm_table}") + migrated = select_values("SELECT version FROM #{sm_table} ORDER BY version") migrated.map { |v| "INSERT INTO #{sm_table} (version) VALUES ('#{v}');" }.join("\n\n") end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 49944eced9..4fdb7d2f25 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1339,6 +1339,15 @@ if ActiveRecord::Base.connection.supports_migrations? end end + def test_dump_schema_information_outputs_lexically_ordered_versions + migration_path = MIGRATIONS_ROOT + '/valid_with_timestamps' + ActiveRecord::Migrator.run(:up, migration_path, 20100301010101) + ActiveRecord::Migrator.run(:up, migration_path, 20100201010101) + + schema_info = ActiveRecord::Base.connection.dump_schema_information + assert_match schema_info, /20100201010101.*20100301010101/m + end + def test_finds_pending_migrations ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1) migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations -- cgit v1.2.3 From 1afe269a4aa18a815c509d3f0348ed99a9b4b560 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Mon, 31 Oct 2011 19:01:03 +0530 Subject: assert_match takes a regexp and a string in that order --- activerecord/test/cases/migration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 4fdb7d2f25..f61d0315d0 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1345,7 +1345,7 @@ if ActiveRecord::Base.connection.supports_migrations? ActiveRecord::Migrator.run(:up, migration_path, 20100201010101) schema_info = ActiveRecord::Base.connection.dump_schema_information - assert_match schema_info, /20100201010101.*20100301010101/m + assert_match(/20100201010101.*20100301010101/m, schema_info) end def test_finds_pending_migrations -- cgit v1.2.3 From 6cbe4223a77d7ea364b4d2dc46cec6a0c58c9537 Mon Sep 17 00:00:00 2001 From: Christopher Meiklejohn Date: Sat, 30 Jul 2011 00:49:36 -0400 Subject: Ensure that the format isn't applied twice to the cache key, else it becomes impossible to target with expire_action. --- actionpack/lib/action_controller/caching/actions.rb | 2 +- actionpack/test/controller/caching_test.rb | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 0031d2701f..f6b23e4efc 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -175,7 +175,7 @@ module ActionController #:nodoc: private def normalize!(path) path << 'index' if path[-1] == ?/ - path << ".#{extension}" if extension and !path.ends_with?(extension) + path << ".#{extension}" if extension and !path.split('?').first.try(:ends_with?, ".#{extension}") URI.parser.unescape(path) end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 618e7b77b2..2364bbf3a3 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -194,6 +194,7 @@ class ActionCachingTestController < CachingController caches_action :show, :cache_path => 'http://test.host/custom/show' caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" } caches_action :with_layout + caches_action :with_format_and_http_param, :cache_path => Proc.new { |c| { :key => 'value' } } caches_action :layout_false, :layout => false caches_action :record_not_found, :four_oh_four, :simple_runtime_error @@ -219,6 +220,11 @@ class ActionCachingTestController < CachingController render :text => @cache_this, :layout => true end + def with_format_and_http_param + @cache_this = MockTime.now.to_f.to_s + render :text => @cache_this + end + def record_not_found raise ActiveRecord::RecordNotFound, "oops!" end @@ -359,6 +365,13 @@ class ActionCacheTest < ActionController::TestCase assert !fragment_exist?('hostname.com/action_caching_test') end + def test_action_cache_with_format_and_http_param + get :with_format_and_http_param, :format => 'json' + assert_response :success + assert !fragment_exist?('hostname.com/action_caching_test/with_format_and_http_param.json?key=value.json') + assert fragment_exist?('hostname.com/action_caching_test/with_format_and_http_param.json?key=value') + end + def test_action_cache_with_store_options MockTime.expects(:now).returns(12345).once @controller.expects(:read_fragment).with('hostname.com/action_caching_test', :expires_in => 1.hour).once -- cgit v1.2.3 From 62a86748ae8e6a43c20e917a963a614a02098a58 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 31 Oct 2011 15:17:16 -0400 Subject: this should never return nil, so no use for "try" --- actionpack/lib/action_controller/caching/actions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index f6b23e4efc..f988de39dd 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -175,7 +175,7 @@ module ActionController #:nodoc: private def normalize!(path) path << 'index' if path[-1] == ?/ - path << ".#{extension}" if extension and !path.split('?').first.try(:ends_with?, ".#{extension}") + path << ".#{extension}" if extension and !path.split('?').first.ends_with?(".#{extension}") URI.parser.unescape(path) end end -- cgit v1.2.3 From dfdbbe059f464a0ab2437a93e9f8222942920155 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Fri, 28 Oct 2011 18:46:18 +1100 Subject: [engines guide] add 'General engine configuration' section --- railties/guides/source/engines.textile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/railties/guides/source/engines.textile b/railties/guides/source/engines.textile index da56f3d0ed..694b36bea1 100644 --- a/railties/guides/source/engines.textile +++ b/railties/guides/source/engines.textile @@ -506,6 +506,10 @@ Now instead of the ugly Ruby object output the author's name will be displayed. h4. Configuring an engine +This section covers firstly how you can make the +user_class+ setting of the Blorgh engine configurable, followed by general configuration tips for the engine. + +h5. Setting configuration settings in the application + The next step is to make the class that represents a +User+ in the application customizable for the engine. This is because, as explained before, that class may not always be +User+. To make this customizable, the engine will have a configuration setting called +user_class+ that will be used to specify what the class representing users is inside the application. To define this configuration setting, you should use a +mattr_accessor+ inside the +Blorgh+ module for the engine, located at +lib/blorgh.rb+ inside the engine. Inside this module, put this line: @@ -542,6 +546,14 @@ Go ahead and try to create a new post. You will see that it works exactly in the There are now no strict dependencies on what the class is, only what the class's API must be. The engine simply requires this class to define a +find_or_create_by_name+ method which returns an object of that class to be associated with a post when it's created. +h5. General engine configuration + +Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines! + +If you wish to use initializers (code that should run before the engine is loaded), the best place for them is the +config/initializers+ folder. This directory's functionality is explained in the "Initializers section":http://guides.rubyonrails.org/configuring.html#initializers of the Configuring guide. + +For locales, simply place the locale files in the +config/locales+ directory, just like you would in an application. + h3. Extending engine functionality This section looks at overriding or adding functionality to the views, controllers and models provided by an engine. -- cgit v1.2.3 From e28bd7b22698dc2a5df05fe6ab9ceba715452a33 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Tue, 1 Nov 2011 11:18:17 +1100 Subject: [config guide] mention that config methods are to be called on Railtie subclasses --- railties/guides/source/configuring.textile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index bb494fbd33..cd6e7d116e 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -40,6 +40,8 @@ Rails will use that particular setting to configure Active Record. h4. Rails General Configuration +These configuration methods are to be called on a +Rails::Railtie+ object, such as a subclass of +Rails::Engine+ or +Rails::Application+. + * +config.after_initialize+ takes a block which will be run _after_ Rails has finished initializing the application. That includes the initialization of the framework itself, plugins, engines, and all the application's initializers in +config/initializers+. Note that this block _will_ be run for rake tasks. Useful for configuring values set up by other initializers: -- cgit v1.2.3 From 5f4550889dcab7def4122d37a3379d57627f68e2 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Tue, 1 Nov 2011 08:55:03 +0400 Subject: Fix typo in constraints method documentation --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 09a8c10043..e8bfe9bbd0 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -735,7 +735,7 @@ module ActionDispatch # if the user should be given access to that route, or +false+ if the user should not. # # class Iphone - # def self.matches(request) + # def self.matches?(request) # request.env["HTTP_USER_AGENT"] =~ /iPhone/ # end # end -- cgit v1.2.3 From 702aecb126712de9f996da74357cafe14f449d24 Mon Sep 17 00:00:00 2001 From: Aviv Ben-Yosef Date: Tue, 1 Nov 2011 08:59:20 +0200 Subject: Fix typo in Dispatcher#controller documentation --- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index e7bc431783..2bcde16110 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -37,7 +37,7 @@ module ActionDispatch # If this is a default_controller (i.e. a controller specified by the user) # we should raise an error in case it's not found, because it usually means - # an user error. However, if the controller was retrieved through a dynamic + # a user error. However, if the controller was retrieved through a dynamic # segment, as in :controller(/:action), we should simply return nil and # delegate the control back to Rack cascade. Besides, if this is not a default # controller, it means we should respect the @scope[:module] parameter. -- cgit v1.2.3 From ed4bde5a0937f8eadfd806b1f579048bf5ac9b07 Mon Sep 17 00:00:00 2001 From: juandebravo Date: Tue, 1 Nov 2011 20:45:00 +0200 Subject: Fix wrong link in initialization doc --- railties/guides/source/initialization.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index f88405a2fd..7710c9bd6c 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -817,7 +817,7 @@ def initializer(name, opts = {}, &blk) end -An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":[http://ryanbigg.com/guides/configuring.html#rails-railtie-initializer]. +An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":http://guides.rubyonrails.org/configuring.html#rails-railtie-initializer. The +Initializer+ class here is defined within the +Rails::Initializable+ module and its +initialize+ method is defined to just set up a couple of variables: -- cgit v1.2.3 From 9aa880f2e860ff2058dc0d359c6310848b1e4383 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 2 Nov 2011 00:37:18 +0530 Subject: use relative urls for linking to sections in the guides --- railties/guides/source/initialization.textile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 7710c9bd6c..036b356a37 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -525,19 +525,19 @@ silence_warnings do end -These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":http://guides.rubyonrails.org/active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide. +These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide. h4. +active_support/core_ext/logger.rb+ The next file that is required is another Active Support core extension, this time to the +Logger+ class. This begins by defining the +around_[level]+ helpers for the +Logger+ class as well as other methods such as a +datetime_format+ getter and setter for the +formatter+ object tied to a +Logger+ object. -For more information see the "Extensions to Logger":http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-logger section from the Active Support Core Extensions Guide. +For more information see the "Extensions to Logger":active_support_core_extensions.html#extensions-to-logger section from the Active Support Core Extensions Guide. h4. +railties/lib/rails/application.rb+ The next file required by +railties/lib/rails.rb+ is +application.rb+. This file defines the +Rails::Application+ constant which the application's class defined in +config/application.rb+ in a standard Rails application depends on. Before the +Rails::Application+ class is defined however, there's some other files that get required first. -The first of these is +active_support/core_ext/hash/reverse_merge+ which can be "read about in the Active Support Core Extensions guide":http://guides.rubyonrails.org/active_support_core_extensions.html#merging under the "Merging" section. +The first of these is +active_support/core_ext/hash/reverse_merge+ which can be "read about in the Active Support Core Extensions guide":active_support_core_extensions.html#merging under the "Merging" section. h4. +active_support/file_update_checker.rb+ @@ -575,7 +575,7 @@ Now that +rails/initializable.rb+ has finished being required from +rails/railti h4. +railties/lib/rails/configuration.rb+ -This file defines the +Rails::Configuration+ module, containing the +MiddlewareStackProxy+ class as well as the +Generators+ class. The +MiddlewareStackProxy+ class is used for managing the middleware stack for an application, which we'll see later on. The +Generators+ class provides the functionality used for configuring what generators an application uses through the "+config.generators+ option":http://guides.rubyonrails.org/configuring.html#configuring-generators. +This file defines the +Rails::Configuration+ module, containing the +MiddlewareStackProxy+ class as well as the +Generators+ class. The +MiddlewareStackProxy+ class is used for managing the middleware stack for an application, which we'll see later on. The +Generators+ class provides the functionality used for configuring what generators an application uses through the "+config.generators+ option":configuring.html#configuring-generators. The first file required in this file is +activesupport/deprecation+. @@ -598,11 +598,11 @@ This file defines the +ActiveSupport::Notifications+ module. Notifications provi The "API documentation":http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html for +ActiveSupport::Notifications+ explains the usage of this module, including the methods that it defines. -The file required in +active_support/notifications.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation. +The file required in +active_support/notifications.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":active_support_core_extensions.html#method-delegation. h4. +activesupport/core_ext/array/wrap+ -As this file comprises of a core extension, it is covered exclusively in "the Active Support Core Extensions guide":http://guides.rubyonrails.org/active_support_core_extensions.html#wrapping +As this file comprises of a core extension, it is covered exclusively in "the Active Support Core Extensions guide":active_support_core_extensions.html#wrapping h4. +activesupport/lib/active_support/deprecation/reporting.rb+ @@ -624,7 +624,7 @@ h4. +active_support/ordered_options+ This file is the next file required from +rails/configuration.rb+ is the file that defines +ActiveSupport::OrderedOptions+ which is used for configuration options such as +config.active_support+ and the like. -The next file required is +active_support/core_ext/hash/deep_dup+ which is covered in "Active Support Core Extensions guide":http://guides.rubyonrails.org/active_support_core_extensions.html#deep_dup +The next file required is +active_support/core_ext/hash/deep_dup+ which is covered in "Active Support Core Extensions guide":active_support_core_extensions.html#deep_dup The file that is required next from is +rails/paths+ @@ -682,7 +682,7 @@ When the module from this file (+Rails::Initializable+) is included, it extends h4. +railties/lib/rails/engine.rb+ -The next file required in +rails/engine.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation. +The next file required in +rails/engine.rb+ is +active_support/core_ext/module/delegation+ which is documented in the "Active Support Core Extensions Guide":active_support_core_extensions.html#method-delegation. The next two files after this are Ruby standard library files: +pathname+ and +rbconfig+. The file after these is +rails/engine/railties+. @@ -698,7 +698,7 @@ Once this file has finished loading we jump back to +railties/lib/rails/plugin.r h4. Back to +railties/lib/rails/plugin.rb+ -The next file required in this is a core extension from Active Support called +array/conversions+ which is covered in "this section":http://guides.rubyonrails.org/active_support_core_extensions.html#array-conversions of the Active Support Core Extensions Guide. +The next file required in this is a core extension from Active Support called +array/conversions+ which is covered in "this section":active_support_core_extensions.html#array-conversions of the Active Support Core Extensions Guide. Once that file has finished loading, the +Rails::Plugin+ class is defined. @@ -817,7 +817,7 @@ def initializer(name, opts = {}, &blk) end -An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":http://guides.rubyonrails.org/configuring.html#rails-railtie-initializer. +An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":configuring.html#rails-railtie-initializer. The +Initializer+ class here is defined within the +Rails::Initializable+ module and its +initialize+ method is defined to just set up a couple of variables: -- cgit v1.2.3 From 836b6208504a761d6e0427b2709d0a87dfe98e06 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 1 Nov 2011 17:41:37 -0700 Subject: Revert "Disable 1.9.3 builds until upgraded from -preview1 to -rc1" This reverts commit 8a6acc17bb8badf70e300f599bf0440ee197028c. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4a27f7788d..265124a3af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ script: 'ci/travis.rb' rvm: - 1.8.7 - 1.9.2 - #- 1.9.3 # Disable 1.9.3 builds until Travis is on 1.9.3-rc1. + - 1.9.3 env: - "GEM=railties" - "GEM=ap,am,amo,ares,as" -- cgit v1.2.3 From 5745a5e85e1900c52d169f79ec0802060e110e21 Mon Sep 17 00:00:00 2001 From: Colin MacKenzie IV Date: Wed, 2 Nov 2011 09:00:18 -0400 Subject: treat USAGE as an ERB template --- railties/lib/rails/generators/base.rb | 2 +- railties/test/fixtures/lib/generators/usage_template/USAGE | 1 + .../lib/generators/usage_template/usage_template_generator.rb | 5 +++++ railties/test/generators_test.rb | 6 ++++++ 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 railties/test/fixtures/lib/generators/usage_template/USAGE create mode 100644 railties/test/fixtures/lib/generators/usage_template/usage_template_generator.rb diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index 911f80cf3a..f38a487a4e 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -34,7 +34,7 @@ module Rails usage = source_root && File.expand_path("../USAGE", source_root) @desc ||= if usage && File.exist?(usage) - File.read(usage) + ERB.new(File.read(usage)).result(binding) else "Description:\n Create #{base_name.humanize.downcase} files for #{generator_name} generator." end diff --git a/railties/test/fixtures/lib/generators/usage_template/USAGE b/railties/test/fixtures/lib/generators/usage_template/USAGE new file mode 100644 index 0000000000..bcd63c52e2 --- /dev/null +++ b/railties/test/fixtures/lib/generators/usage_template/USAGE @@ -0,0 +1 @@ +:: <%= 1 + 1 %> :: \ No newline at end of file diff --git a/railties/test/fixtures/lib/generators/usage_template/usage_template_generator.rb b/railties/test/fixtures/lib/generators/usage_template/usage_template_generator.rb new file mode 100644 index 0000000000..078b0f9412 --- /dev/null +++ b/railties/test/fixtures/lib/generators/usage_template/usage_template_generator.rb @@ -0,0 +1,5 @@ +require 'rails/generators' + +class UsageTemplateGenerator < Rails::Generators::Base + source_root File.expand_path("templates", File.dirname(__FILE__)) +end diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 56329f3183..5f9ee220dc 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -201,4 +201,10 @@ class GeneratorsTest < Rails::Generators::TestCase mspec = Rails::Generators.find_by_namespace :fixjour assert mspec.source_paths.include?(File.join(Rails.root, "lib", "templates", "fixjour")) end + + def test_usage_with_embedded_ruby + require File.expand_path("fixtures/lib/generators/usage_template/usage_template_generator", File.dirname(__FILE__)) + output = capture(:stdout) { Rails::Generators.invoke :usage_template, ['--help'] } + assert_match /:: 2 ::/, output + end end -- cgit v1.2.3 From b3c1cfa2772e64b20681bae8e765f37660087b18 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 2 Nov 2011 23:01:30 +0530 Subject: minor edits in AR validations guide --- .../source/active_record_validations_callbacks.textile | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index 665e7f9ccc..4c1f66aedf 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -796,17 +796,9 @@ person.errors.size # => 0 h3. Displaying Validation Errors in the View -Rails maintains an official plugin, DynamicForm, that provides helpers to display the error messages of your models in your view templates. You can install it as a plugin or as a Gem. +"DynamicForm":https://github.com/joelmoss/dynamic_form provides helpers to display the error messages of your models in your view templates. -h4. Installing as a plugin - - -$ rails plugin install git://github.com/joelmoss/dynamic_form.git - - -h4. Installing as a Gem - -Add this line in your Gemfile: +You can install it as a gem by adding this line to your Gemfile: gem "dynamic_form" -- cgit v1.2.3 From bc09a11a666a1fba848d866dd61bf7123d4d5759 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 2 Nov 2011 23:34:27 +0530 Subject: minor edit --- railties/guides/source/action_view_overview.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile index 40cde6ad84..e2b69fa0d5 100644 --- a/railties/guides/source/action_view_overview.textile +++ b/railties/guides/source/action_view_overview.textile @@ -16,7 +16,7 @@ Action View and Action Controller are the two major components of Action Pack. I Action View templates are written using embedded Ruby in tags mingled with HTML. To avoid cluttering the templates with boilerplate code, a number of helper classes provide common behavior for forms, dates, and strings. It's also easy to add new helpers to your application as it evolves. -Note: Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend. +NOTE. Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend. h3. Using Action View with Rails -- cgit v1.2.3 From 746331711585cfcb158dafcaf3ea5d60d9825ed2 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Thu, 3 Nov 2011 08:43:28 +0400 Subject: Fix small typos in routing docs --- actionpack/lib/action_dispatch/routing/mapper.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index e8bfe9bbd0..970236a05a 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -285,7 +285,7 @@ module ActionDispatch # A pattern can also point to a +Rack+ endpoint i.e. anything that # responds to +call+: # - # match 'photos/:id' => lambda {|hash| [200, {}, "Coming soon" } + # match 'photos/:id' => lambda {|hash| [200, {}, "Coming soon"] } # match 'photos/:id' => PhotoRackApp # # Yes, controller actions are just rack endpoints # match 'photos/:id' => PhotosController.action(:show) @@ -1023,6 +1023,7 @@ module ActionDispatch # creates seven different routes in your application, all mapping to # the +Photos+ controller: # + # GET /photos # GET /photos/new # POST /photos # GET /photos/:id @@ -1038,6 +1039,7 @@ module ActionDispatch # # This generates the following comments routes: # + # GET /photos/:photo_id/comments # GET /photos/:photo_id/comments/new # POST /photos/:photo_id/comments # GET /photos/:photo_id/comments/:id -- cgit v1.2.3 From a8468731f7cbb0d8702e7fb0722559194dd930ad Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Thu, 3 Nov 2011 09:02:11 +0400 Subject: Fix javascript_include_tag examples in documentation --- .../action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index 09700bd0c5..d9f1f88ade 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -119,10 +119,10 @@ module ActionView # # # # javascript_include_tag "http://www.example.com/xmlhr" - # # => + # # => # # javascript_include_tag "http://www.example.com/xmlhr.js" - # # => + # # => # # javascript_include_tag :defaults # # => -- cgit v1.2.3 From b4b178f7e9a00a0235574a773cdbc06fe856acaf Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 3 Nov 2011 10:23:42 +0000 Subject: Fix #3247. Fixes creating records in a through association with a polymorphic source type. --- activerecord/CHANGELOG | 8 +++++++- .../lib/active_record/associations/through_association.rb | 2 +- .../test/cases/associations/has_many_through_associations_test.rb | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 798d875034..698a337dcc 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -8,7 +8,7 @@ class User < ActiveRecord::Base store :settings, accessors: [ :color, :homepage ] end - + u = User.new(color: 'black', homepage: '37signals.com') u.color # Accessor stored attribute u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor @@ -37,6 +37,12 @@ [Aaron Christy] +*Rails 3.1.2 (unreleased)* + +* Fix creating records in a through association with a polymorphic source type. [GH #3247] + + [Jon Leighton] + *Rails 3.1.1 (October 7, 2011)* * Add deprecation for the preload_associations method. Fixes #3022. diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index b347a94978..f95e5337c2 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -44,7 +44,7 @@ module ActiveRecord join_attributes = { source_reflection.foreign_key => records.map { |record| - record.send(source_reflection.association_primary_key) + record.send(source_reflection.association_primary_key(reflection.klass)) } } diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index b703c96ec1..2f4dd9e55c 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -825,4 +825,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_explicitly_joining_join_table assert_equal owners(:blackbeard).toys, owners(:blackbeard).toys.with_pet end + + def test_has_many_through_with_polymorphic_source + post = tags(:general).tagged_posts.create! :title => "foo", :body => "bar" + assert_equal [tags(:general)], post.reload.tags + end end -- cgit v1.2.3 From 71bc921ec8ac89840077bb54752282a3d89429f6 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 3 Nov 2011 12:37:37 +0000 Subject: Fix adding multiple instances of the same record to a has_many :through. Fixes #3425. --- activerecord/CHANGELOG | 4 ++ .../associations/has_many_through_association.rb | 64 +++++++++++++++------- .../has_many_through_associations_test.rb | 10 ++++ 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 698a337dcc..fac9ad1188 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -39,6 +39,10 @@ *Rails 3.1.2 (unreleased)* +* Fix adding multiple instances of the same record to a has_many :through. [GH #3425] + + [Jon Leighton] + * Fix creating records in a through association with a polymorphic source type. [GH #3247] [Jon Leighton] diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 2e818dca5d..d82d041b69 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -6,6 +6,11 @@ module ActiveRecord class HasManyThroughAssociation < HasManyAssociation #:nodoc: include ThroughAssociation + def initialize(owner, reflection) + super + @through_records = {} + end + # Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been # loaded and calling collection.size if it has. If it's more likely than not that the collection does # have a size larger than zero, and you need to fetch that collection afterwards, it'll take one fewer @@ -42,27 +47,42 @@ module ActiveRecord end end - through_record(record).save! + save_through_record(record) update_counter(1) record end private - def through_record(record) - through_association = owner.association(through_reflection.name) - attributes = construct_join_attributes(record) - - through_record = Array.wrap(through_association.target).find { |candidate| - candidate.attributes.slice(*attributes.keys) == attributes - } + def through_association + owner.association(through_reflection.name) + end - unless through_record - through_record = through_association.build(attributes) + # We temporarily cache through record that has been build, because if we build a + # through record in build_record and then subsequently call insert_record, then we + # want to use the exact same object. + # + # However, after insert_record has been called, we clear the cache entry because + # we want it to be possible to have multiple instances of the same record in an + # association + def build_through_record(record) + @through_records[record.object_id] ||= begin + through_record = through_association.build(construct_join_attributes(record)) through_record.send("#{source_reflection.name}=", record) + through_record end + end - through_record + def save_through_record(record) + build_through_record(record).save! + ensure + @through_records.delete(record.object_id) + end + + def through_record(record) + attributes = construct_join_attributes(record) + candidates = Array.wrap(through_association.target) + candidates.find { |c| c.attributes.slice(*attributes.keys) == attributes } end def build_record(attributes, options = {}) @@ -73,9 +93,9 @@ module ActiveRecord inverse = source_reflection.inverse_of if inverse if inverse.macro == :has_many - record.send(inverse.name) << through_record(record) + record.send(inverse.name) << build_through_record(record) elsif inverse.macro == :has_one - record.send("#{inverse.name}=", through_record(record)) + record.send("#{inverse.name}=", build_through_record(record)) end end @@ -104,7 +124,7 @@ module ActiveRecord def delete_records(records, method) ensure_not_nested - through = owner.association(through_reflection.name) + through = through_association scope = through.scoped.where(construct_join_attributes(*records)) case method @@ -126,14 +146,16 @@ module ActiveRecord end def delete_through_records(through, records) - if through_reflection.macro == :has_many - records.each do |record| - through.target.delete(through_record(record)) - end - else - records.each do |record| - through.target = nil if through.target == through_record(record) + records.each do |record| + through_record = through_record(record) + + if through_reflection.macro == :has_many + through.target.delete(through_record) + else + through.target = nil if through.target == through_record end + + @through_records.delete(record.object_id) end end diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 2f4dd9e55c..115e06144e 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -67,6 +67,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end end + def test_associate_existing_record_twice_should_add_records_twice + post = posts(:thinking) + person = people(:david) + + assert_difference 'post.people.count', 2 do + post.people << person + post.people << person + end + end + def test_associating_new assert_queries(1) { posts(:thinking) } new_person = nil # so block binding catches it -- cgit v1.2.3 From 19b2a5f2bdd5bf6404bfc3e574b7477038e9b2bf Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 3 Nov 2011 13:12:04 +0000 Subject: Remove all revelant through records. If a record is removed from a has_many :through, all of the join records relating to that record should also be removed from the through association's target. (Previously the records were removed in the database, but only one was removed from the in-memory target array.) --- activerecord/CHANGELOG | 5 +++++ .../associations/has_many_through_association.rb | 18 +++++++++--------- .../associations/has_many_through_associations_test.rb | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index fac9ad1188..203b110e98 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -39,6 +39,11 @@ *Rails 3.1.2 (unreleased)* +* If a record is removed from a has_many :through, all of the join records relating to that + record should also be removed from the through association's target. + + [Jon Leighton] + * Fix adding multiple instances of the same record to a has_many :through. [GH #3425] [Jon Leighton] diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index d82d041b69..6ba405ba4c 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -79,12 +79,6 @@ module ActiveRecord @through_records.delete(record.object_id) end - def through_record(record) - attributes = construct_join_attributes(record) - candidates = Array.wrap(through_association.target) - candidates.find { |c| c.attributes.slice(*attributes.keys) == attributes } - end - def build_record(attributes, options = {}) ensure_not_nested @@ -145,14 +139,20 @@ module ActiveRecord update_counter(-count) end + def through_records_for(record) + attributes = construct_join_attributes(record) + candidates = Array.wrap(through_association.target) + candidates.find_all { |c| c.attributes.slice(*attributes.keys) == attributes } + end + def delete_through_records(through, records) records.each do |record| - through_record = through_record(record) + through_records = through_records_for(record) if through_reflection.macro == :has_many - through.target.delete(through_record) + through_records.each { |r| through.target.delete(r) } else - through.target = nil if through.target == through_record + through.target = nil if through_records.include?(through.target) end @through_records.delete(record.object_id) diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 115e06144e..7a6aba6a6b 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -77,6 +77,21 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end end + def test_add_two_instance_and_then_deleting + post = posts(:thinking) + person = people(:david) + + post.people << person + post.people << person + + counts = ['post.people.count', 'post.people.to_a.count', 'post.readers.count', 'post.readers.to_a.count'] + assert_difference counts, -2 do + post.people.delete(person) + end + + assert !post.people.reload.include?(person) + end + def test_associating_new assert_queries(1) { posts(:thinking) } new_person = nil # so block binding catches it -- cgit v1.2.3 From 567d454d99bd472ef342c047c0038504fa4f960c Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 3 Nov 2011 13:24:39 +0000 Subject: Memoize through association --- .../associations/has_many_through_association.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 6ba405ba4c..7e6e3be382 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -8,7 +8,9 @@ module ActiveRecord def initialize(owner, reflection) super - @through_records = {} + + @through_records = {} + @through_association = nil end # Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been @@ -55,7 +57,7 @@ module ActiveRecord private def through_association - owner.association(through_reflection.name) + @through_association ||= owner.association(through_reflection.name) end # We temporarily cache through record that has been build, because if we build a @@ -118,8 +120,7 @@ module ActiveRecord def delete_records(records, method) ensure_not_nested - through = through_association - scope = through.scoped.where(construct_join_attributes(*records)) + scope = through_association.scoped.where(construct_join_attributes(*records)) case method when :destroy @@ -130,7 +131,7 @@ module ActiveRecord count = scope.delete_all end - delete_through_records(through, records) + delete_through_records(records) if through_reflection.macro == :has_many && update_through_counter?(method) update_counter(-count, through_reflection) @@ -145,14 +146,16 @@ module ActiveRecord candidates.find_all { |c| c.attributes.slice(*attributes.keys) == attributes } end - def delete_through_records(through, records) + def delete_through_records(records) records.each do |record| through_records = through_records_for(record) if through_reflection.macro == :has_many - through_records.each { |r| through.target.delete(r) } + through_records.each { |r| through_association.target.delete(r) } else - through.target = nil if through_records.include?(through.target) + if through_records.include?(through_association.target) + through_association.target = nil + end end @through_records.delete(record.object_id) -- cgit v1.2.3 From a50f659e081785479b068b311862703584a589ca Mon Sep 17 00:00:00 2001 From: Olivier Lacan Date: Thu, 3 Nov 2011 10:01:32 -0400 Subject: CSS fix to prevent error output from being breaking out of body element. Using the white-space: pre-wrap adds extra line breaks to prevent the text from breaking out of the element's box. In this case single line output can be extremely long, breaking out the element. See for reference: http://www.quirksmode.org/css/whitespace.html Before: http://link.olivierlacan.com/BVU4 After: http://link.olivierlacan.com/BUfM --- actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb index 6e71fd7ddc..1a308707d1 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb @@ -16,6 +16,7 @@ background-color: #eee; padding: 10px; font-size: 11px; + white-space: pre-wrap; } a { color: #000; } -- cgit v1.2.3 From d486103570bf680307ba474915efc01862e99403 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 3 Nov 2011 15:07:24 +0000 Subject: Fix #3271. Building the conditions of a nested through association could potentially modify the conditions of the through and/or source association. This is a Bad Thing. --- activerecord/CHANGELOG | 7 +++++++ activerecord/lib/active_record/reflection.rb | 2 +- activerecord/test/cases/reflection_test.rb | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 203b110e98..871cc624ca 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -39,6 +39,13 @@ *Rails 3.1.2 (unreleased)* +* Fix bug where building the conditions of a nested through association could potentially + modify the conditions of the through and/or source association. If you have experienced + bugs with conditions appearing in the wrong queries when using nested through associations, + this probably solves your problems. [GH #3271] + + [Jon Leighton] + * If a record is removed from a has_many :through, all of the join records relating to that record should also be removed from the through association's target. diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 5285060288..98f0418d3f 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -433,7 +433,7 @@ module ActiveRecord # of relevant reflections, plus any :source_type or polymorphic :as constraints. def conditions @conditions ||= begin - conditions = source_reflection.conditions + conditions = source_reflection.conditions.map { |c| c.dup } # Add to it the conditions from this reflection if necessary. conditions.first << options[:conditions] if options[:conditions] diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 69e9fc8d61..4d21822cf5 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -319,6 +319,12 @@ class ReflectionTest < ActiveRecord::TestCase assert_equal "category_id", Post.reflect_on_association(:categorizations).foreign_key.to_s end + def test_through_reflection_conditions_do_not_modify_other_reflections + orig_conds = Post.reflect_on_association(:first_blue_tags_2).conditions.inspect + Author.reflect_on_association(:misc_post_first_blue_tags_2).conditions + assert_equal orig_conds, Post.reflect_on_association(:first_blue_tags_2).conditions.inspect + end + private def assert_reflection(klass, association, options) assert reflection = klass.reflect_on_association(association) -- cgit v1.2.3 From b5f908a7ad515215f164e306f82c3e6c506182cb Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 3 Nov 2011 16:09:57 +0000 Subject: Stub find_template so that when handle_render_error is called in ActionView::Template, we get to see the actual underlying error rather than a NoMethodError. This shows an encoding bug on Ruby 1.9.3. --- actionpack/test/template/template_test.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb index b0ca7de0b6..70ca876c67 100644 --- a/actionpack/test/template/template_test.rb +++ b/actionpack/test/template/template_test.rb @@ -8,6 +8,9 @@ class TestERBTemplate < ActiveSupport::TestCase def disable_cache yield end + + def find_template(*args) + end end class Context -- cgit v1.2.3 From 7102a3d7fc55067b6cda1a7eeb3b3452050d9b6b Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Fri, 4 Nov 2011 04:50:53 +0900 Subject: move Rails console top level methods to IRB context --- railties/lib/rails/console/app.rb | 48 +++++++++++++++++-------------- railties/lib/rails/console/helpers.rb | 14 +++++---- railties/test/application/console_test.rb | 14 ++++++--- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb index 95c74baae2..cf081473a3 100644 --- a/railties/lib/rails/console/app.rb +++ b/railties/lib/rails/console/app.rb @@ -5,28 +5,32 @@ require 'action_controller' # work around the at_exit hook in test/unit, which kills IRB Test::Unit.run = true if Test::Unit.respond_to?(:run=) -# reference the global "app" instance, created on demand. To recreate the -# instance, pass a non-false value as the parameter. -def app(create=false) - @app_integration_instance = nil if create - @app_integration_instance ||= new_session do |sess| - sess.host! "www.example.com" - end -end +module IRB + module ExtendCommandBundle + # reference the global "app" instance, created on demand. To recreate the + # instance, pass a non-false value as the parameter. + def app(create=false) + @app_integration_instance = nil if create + @app_integration_instance ||= new_session do |sess| + sess.host! "www.example.com" + end + end -# create a new session. If a block is given, the new session will be yielded -# to the block before being returned. -def new_session - app = Rails.application - session = ActionDispatch::Integration::Session.new(app) - yield session if block_given? - session -end + # create a new session. If a block is given, the new session will be yielded + # to the block before being returned. + def new_session + app = Rails.application + session = ActionDispatch::Integration::Session.new(app) + yield session if block_given? + session + end -# reloads the environment -def reload!(print=true) - puts "Reloading..." if print - ActionDispatch::Reloader.cleanup! - ActionDispatch::Reloader.prepare! - true + # reloads the environment + def reload!(print=true) + puts "Reloading..." if print + ActionDispatch::Reloader.cleanup! + ActionDispatch::Reloader.prepare! + true + end + end end diff --git a/railties/lib/rails/console/helpers.rb b/railties/lib/rails/console/helpers.rb index 212fc6125a..070d3c2bbf 100644 --- a/railties/lib/rails/console/helpers.rb +++ b/railties/lib/rails/console/helpers.rb @@ -1,7 +1,11 @@ -def helper - @helper ||= ApplicationController.helpers -end +module IRB + module ExtendCommandBundle + def helper + @helper ||= ApplicationController.helpers + end -def controller - @controller ||= ApplicationController.new + def controller + @controller ||= ApplicationController.new + end + end end diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb index 1528d5dd87..5a1f71ddad 100644 --- a/railties/test/application/console_test.rb +++ b/railties/test/application/console_test.rb @@ -18,16 +18,20 @@ class ConsoleTest < Test::Unit::TestCase Rails.application.load_console end + def irb_context + Object.new.extend(IRB::ExtendCommandBundle) + end + def test_app_method_should_return_integration_session TestHelpers::Rack.send :remove_method, :app load_environment - console_session = app + console_session = irb_context.app assert_instance_of ActionDispatch::Integration::Session, console_session end def test_new_session_should_return_integration_session load_environment - session = new_session + session = irb_context.new_session assert_instance_of ActionDispatch::Integration::Session, session end @@ -41,7 +45,7 @@ class ConsoleTest < Test::Unit::TestCase ActionDispatch::Reloader.to_prepare { c = 3 } # Hide Reloading... output - silence_stream(STDOUT) { reload! } + silence_stream(STDOUT) { irb_context.reload! } assert_equal 1, a assert_equal 2, b @@ -66,12 +70,14 @@ class ConsoleTest < Test::Unit::TestCase MODEL assert !User.new.respond_to?(:age) - silence_stream(STDOUT) { reload! } + silence_stream(STDOUT) { irb_context.reload! } + session = irb_context.new_session assert User.new.respond_to?(:age) end def test_access_to_helpers load_environment + helper = irb_context.helper assert_not_nil helper assert_instance_of ActionView::Base, helper assert_equal 'Once upon a time in a world...', -- cgit v1.2.3 From 8611f14cafea0e2fcfddd9d22cca442c31664940 Mon Sep 17 00:00:00 2001 From: Henrik Hodne Date: Thu, 3 Nov 2011 22:19:49 +0100 Subject: Added bundle exec to rake test. This is in response to rails/rails#3504. --- railties/guides/source/contributing_to_ruby_on_rails.textile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile index 5848172510..4d84c50e2a 100644 --- a/railties/guides/source/contributing_to_ruby_on_rails.textile +++ b/railties/guides/source/contributing_to_ruby_on_rails.textile @@ -87,21 +87,21 @@ $ bundle install --without db This command will install all dependencies except the MySQL and PostgreSQL Ruby drivers. We will come back at these soon. With dependencies installed, you can run the test suite with: -$ rake test +$ bundle exec rake test You can also run tests for a specific framework, like Action Pack, by going into its directory and executing the same command: $ cd actionpack -$ rake test +$ bundle exec rake test If you want to run tests from the specific directory use the +TEST_DIR+ environment variable. For example, this will run tests inside +railties/test/generators+ directory only: $ cd railties -$ TEST_DIR=generators rake test +$ TEST_DIR=generators bundle exec rake test h4. Warnings @@ -111,7 +111,7 @@ The test suite runs with warnings enabled. Ideally Ruby on Rails should issue no As of this writing they are specially noisy with Ruby 1.9. If you are sure about what you are doing and would like to have a more clear output, there's a way to override the flag: -$ RUBYOPT=-W0 rake test +$ RUBYOPT=-W0 bundle exec rake test h4. Testing Active Record @@ -130,7 +130,7 @@ The gem +sqlite3-ruby+ does not belong to the "db" group indeed, if you followed $ cd activerecord -$ rake test_sqlite3 +$ bundle exec rake test_sqlite3 h5. MySQL and PostgreSQL @@ -195,7 +195,7 @@ test_postgresql respectively. As we mentioned before -$ rake test +$ bundle exec rake test will now run the four of them in turn. -- cgit v1.2.3 From 533a9f84b035756eedf9fdccf0c494dc9701ba72 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 3 Nov 2011 21:14:51 -0700 Subject: Merge pull request #3507 from jmazzi/issue-3503 Preserve SELECT columns on the COUNT for finder_sql when possible --- .../active_record/associations/collection_association.rb | 8 ++++++-- .../test/cases/associations/has_many_associations_test.rb | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index cec876149c..362f1053cd 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -344,8 +344,12 @@ module ActiveRecord if options[:counter_sql] interpolate(options[:counter_sql]) else - # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */ - interpolate(options[:finder_sql]).sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" } + # replace the SELECT clause with COUNT(SELECTS), preserving any hints within /* ... */ + interpolate(options[:finder_sql]).sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) do + count_with = $2.to_s + count_with = '*' if count_with.blank? || count_with =~ /,/ + "SELECT #{$1}COUNT(#{count_with}) FROM" + end end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index cddd2a6f8c..a60af7c046 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -41,6 +41,21 @@ class HasManyAssociationsTestForCountWithCountSql < ActiveRecord::TestCase end end +class HasManyAssociationsTestForCountDistinctWithFinderSql < ActiveRecord::TestCase + class Invoice < ActiveRecord::Base + has_many :custom_line_items, :class_name => 'LineItem', :finder_sql => "SELECT DISTINCT line_items.amount from line_items" + end + + def test_should_count_distinct_results + invoice = Invoice.new + invoice.custom_line_items << LineItem.new(:amount => 0) + invoice.custom_line_items << LineItem.new(:amount => 0) + invoice.save! + + assert_equal 1, invoice.custom_line_items.count + end +end + class HasManyAssociationsTest < ActiveRecord::TestCase -- cgit v1.2.3 From 56207a3f0165650abb273594f1f54fbb92bbf177 Mon Sep 17 00:00:00 2001 From: Waseem Ahmad Date: Fri, 4 Nov 2011 15:03:02 +0530 Subject: Remove 'size' attribute from number_field form helper fixes #3454 f.number_field generates which is invalid HTML5. See: http://dev.w3.org/html5/spec/Overview.html#number-state --- actionpack/lib/action_view/helpers/form_helper.rb | 2 ++ actionpack/test/template/form_helper_test.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index f22c466666..5c10b67586 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1027,6 +1027,8 @@ module ActionView def to_number_field_tag(field_type, options = {}) options = options.stringify_keys + options['size'] ||= nil + if range = options.delete("in") || options.delete("within") options.update("min" => range.min, "max" => range.max) end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index e36d032f6c..bd7b322fc9 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -438,12 +438,12 @@ class FormHelperTest < ActionView::TestCase end def test_number_field - expected = %{} + expected = %{} assert_dom_equal(expected, number_field("order", "quantity", :in => 1...10)) end def test_range_input - expected = %{} + expected = %{} assert_dom_equal(expected, range_field("hifi", "volume", :in => 0..11, :step => 0.1)) end -- cgit v1.2.3 From d163d3bf7ebb98d90977974aed8f85b7ec678afd Mon Sep 17 00:00:00 2001 From: Karthik Muthupalaniappan Date: Fri, 4 Nov 2011 15:18:37 +0530 Subject: outline two ways to invoke a custom active model validator --- activemodel/README.rdoc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index 67701bc422..fa3353a780 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -162,13 +162,21 @@ modules: {Learn more}[link:classes/ActiveModel/Validations.html] * Custom validators - + class Person include ActiveModel::Validations validates_with HasNameValidator attr_accessor :name end + class Person + include ActiveModel::Validations + validates :name, :has_name => true + attr_accessor :name + end + + You could use any of the two ways mentioned above to use a Custom Validator. + class HasNameValidator < ActiveModel::Validator def validate(record) record.errors[:name] = "must exist" if record.name.blank? -- cgit v1.2.3 From 36a5f48f9323c4a770c290a9a16ae58388e7925f Mon Sep 17 00:00:00 2001 From: Karthik Muthupalaniappan Date: Fri, 4 Nov 2011 15:22:50 +0530 Subject: make the inline text a comment in the code block --- .gitignore | 2 ++ activemodel/README.rdoc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index aa14cee911..203fed69a5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ debug.log /railties/guides/output /railties/tmp /RDOC_MAIN.rdoc +.DS_Store +activemodel/.DS_Store diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index fa3353a780..173bc18af1 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -175,7 +175,7 @@ modules: attr_accessor :name end - You could use any of the two ways mentioned above to use a Custom Validator. + #You could use any of the two ways mentioned above to use a Custom Validator. class HasNameValidator < ActiveModel::Validator def validate(record) -- cgit v1.2.3 From e6cc2ea201857a5f3700f589336df2880564cfea Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Fri, 4 Nov 2011 11:16:55 +0000 Subject: Allow the :class_name option for associations to take a symbol. This is to avoid confusing newbies, and to be consistent with the fact that other options like :foreign_key already allow a symbol or a string. --- activerecord/CHANGELOG | 8 ++++++++ activerecord/lib/active_record/reflection.rb | 2 +- activerecord/test/cases/reflection_test.rb | 6 +++++- activerecord/test/models/company.rb | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 871cc624ca..5417824805 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,13 @@ *Rails 3.2.0 (unreleased)* +* Allow the :class_name option for associations to take a symbol (:Client) in addition to + a string ('Client'). + + This is to avoid confusing newbies, and to be consistent with the fact that other options + like :foreign_key already allow a symbol or a string. + + [Jon Leighton] + * In development mode the db:drop task also drops the test database. For symmetry with the db:create task. [Dmitriy Kiriyenko] diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 98f0418d3f..52968070cb 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -124,7 +124,7 @@ module ActiveRecord # composed_of :balance, :class_name => 'Money' returns 'Money' # has_many :clients returns 'Client' def class_name - @class_name ||= options[:class_name] || derive_class_name + @class_name ||= (options[:class_name] || derive_class_name).to_s end # Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute, diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 4d21822cf5..3868ecb3cb 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -189,7 +189,7 @@ class ReflectionTest < ActiveRecord::TestCase def test_reflection_of_all_associations # FIXME these assertions bust a lot - assert_equal 36, Firm.reflect_on_all_associations.size + assert_equal 37, Firm.reflect_on_all_associations.size assert_equal 26, Firm.reflect_on_all_associations(:has_many).size assert_equal 10, Firm.reflect_on_all_associations(:has_one).size assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size @@ -325,6 +325,10 @@ class ReflectionTest < ActiveRecord::TestCase assert_equal orig_conds, Post.reflect_on_association(:first_blue_tags_2).conditions.inspect end + def test_symbol_for_class_name + assert_equal Client, Firm.reflect_on_association(:unsorted_clients_with_symbol).klass + end + private def assert_reflection(klass, association, options) assert reflection = klass.reflect_on_association(association) diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index c1f7a4171a..78eb4c57ac 100644 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -42,6 +42,7 @@ class Firm < Company :before_remove => :log_before_remove, :after_remove => :log_after_remove has_many :unsorted_clients, :class_name => "Client" + has_many :unsorted_clients_with_symbol, :class_name => :Client has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC" has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id" has_many :unvalidated_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :validate => false -- cgit v1.2.3 From 281272ad36e29b49595c1758d56a82f338c21b1a Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Fri, 4 Nov 2011 12:55:17 +0000 Subject: Convert CHANGELOGs to Markdown format. Reasons: * Markdown reads well as plain text, but can also be formatted. * It will make it easier for people to read on the web as Github formats the Markdown nicely. * It will encourage a level of consistency when people are writing CHANGELOG entries. The script used to perform the conversion is at https://gist.github.com/1339263 --- actionmailer/CHANGELOG | 449 --- actionmailer/CHANGELOG.md | 449 +++ actionpack/CHANGELOG | 5689 ------------------------------------- actionpack/CHANGELOG.md | 5663 +++++++++++++++++++++++++++++++++++++ activemodel/CHANGELOG | 109 - activemodel/CHANGELOG.md | 109 + activerecord/CHANGELOG | 6602 ------------------------------------------- activerecord/CHANGELOG.md | 6564 ++++++++++++++++++++++++++++++++++++++++++ activeresource/CHANGELOG | 337 --- activeresource/CHANGELOG.md | 334 +++ activesupport/CHANGELOG | 1571 ---------- activesupport/CHANGELOG.md | 1571 ++++++++++ railties/CHANGELOG | 2390 ---------------- railties/CHANGELOG.md | 2390 ++++++++++++++++ 14 files changed, 17080 insertions(+), 17147 deletions(-) delete mode 100644 actionmailer/CHANGELOG create mode 100644 actionmailer/CHANGELOG.md delete mode 100644 actionpack/CHANGELOG create mode 100644 actionpack/CHANGELOG.md delete mode 100644 activemodel/CHANGELOG create mode 100644 activemodel/CHANGELOG.md delete mode 100644 activerecord/CHANGELOG create mode 100644 activerecord/CHANGELOG.md delete mode 100644 activeresource/CHANGELOG create mode 100644 activeresource/CHANGELOG.md delete mode 100644 activesupport/CHANGELOG create mode 100644 activesupport/CHANGELOG.md delete mode 100644 railties/CHANGELOG create mode 100644 railties/CHANGELOG.md diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG deleted file mode 100644 index 14c887eb53..0000000000 --- a/actionmailer/CHANGELOG +++ /dev/null @@ -1,449 +0,0 @@ -*Rails 3.1.0 (August 30, 2011)* - -* No changes - - -*Rails 3.0.7 (April 18, 2011)* - -* remove AM delegating register_observer and register_interceptor to Mail [Josh Kalderimis] - - -*Rails 3.0.6 (April 5, 2011) - -* Don't allow i18n to change the minor version, version now set to ~> 0.5.0 [Santiago Pastorino] - - -*Rails 3.0.5 (February 26, 2011)* - -* No changes. - - -*Rails 3.0.4 (February 8, 2011)* - -* No changes. - - -*Rails 3.0.3 (November 16, 2010)* - -* No changes. - - -*Rails 3.0.2 (November 15, 2010)* - -* No changes - - -*Rails 3.0.1 (October 15, 2010)* - -* No Changes, just a version bump. - - -*Rails 3.0.0 (August 29, 2010)* - -* subject is automatically looked up on I18n using mailer_name and action_name as scope as in t(".subject") [JK] - -* Changed encoding behaviour of mail, so updated tests in actionmailer and bumped mail version to 2.2.1 [ML] - -* Added ability to pass Proc objects to the defaults hash [ML] - -* Removed all quoting.rb type files from ActionMailer and put Mail 2.2.0 in instead [ML] - -* Lot of updates to various test cases that now work better with the new Mail and so have different expectations - -* Added interceptors and observers from Mail [ML] - - ActionMailer::Base.register_interceptor calls Mail.register_interceptor - ActionMailer::Base.register_observer calls Mail.register_observer - -* Mail::Part now no longer has nil as a default charset, it is always set to something, and defaults to UTF-8 - -* Added explict setting of charset in set_fields! method to make sure Mail has the user defined default - -* Removed quoting.rb and refactored for Mail to take responsibility of all quoting and auto encoding requirements for the header. - -* Fixed several tests which had incorrect encoding. - -* Changed all utf-8 to UTF-8 for consistency - -* Whole new API added with tests. See base.rb for full details. Old API is deprecated. - -* The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted - -* Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'} - -* ActionMailer::Base :default_implicit_parts_order now is in the sequence of the order you want, no reversing of ordering takes place. The default order now is text/plain, then text/enriched, then text/html and then any other part that is not one of these three. - -* Mail does not have "quoted_body", "quoted_subject" etc. All of these are accessed via body.encoded, subject.encoded etc - -* Every object in a Mail object returns an object, never a string. So Mail.body returns a Mail::Body class object, need to call #encoded or #decoded to get the string you want. -* Mail::Message#set_content_type does not exist, it is simply Mail::Message#content_type - -* Every mail message gets a unique message_id unless you specify one, had to change all the tests that check for equality with expected.encoded == actual.encoded to first replace their message_ids with control values - -* Mail now has a proper concept of parts, remove the ActionMailer::Part and ActionMailer::PartContainer classes - -* Calling #encoded on any object returns it as a string ready to go into the output stream of an email, this means it includes the \r\n at the end of the lines and the object is pre-wrapped with \r\n\t if it is a header field. Also, the "encoded" value includes the field name if it is a header field. - -* Attachments are only the actual attachment, with filename etc. A part contains an attachment. The part has the content_type etc. So attachments.last.content_type is invalid. But parts.last.content_type - -* There is no idea of a "sub_head" in Mail. A part is just a Message with some extra functionality, so it just has a "header" like a normal mail message - - -*2.3.2 [Final] (March 15, 2009)* - -* Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP #1842 [Matt Jones] - -* Fixed RFC-2045 quoted-printable bug #1421 [squadette] - -* Fixed that no body charset would be set when there are attachments present #740 [Paweł Kondzior] - - -*2.2.1 [RC2] (November 14th, 2008)* - -* Turn on STARTTLS if it is available in Net::SMTP (added in Ruby 1.8.7) and the SMTP server supports it (This is required for Gmail's SMTP server) #1336 [Grant Hollingworth] - - -*2.2.0 [RC1] (October 24th, 2008)* - -* Add layout functionality to mailers [Pratik Naik] - - 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] - -* Less verbose mail logging: just recipients for :info log level; the whole email for :debug only. #8000 [iaddict, Tarmo Tänav] - -* Updated TMail to version 1.2.1 [Mikel Lindsaar] - -* Fixed that you don't have to call super in ActionMailer::TestCase#setup #10406 [jamesgolick] - - -*2.0.2* (December 16th, 2007) - -* Included in Rails 2.0.2 - - -*2.0.1* (December 7th, 2007) - -* Update ActionMailer so it treats ActionView the same way that ActionController does. Closes #10244 [Rick Olson] - - * Pass the template_root as an array as ActionView's view_path - * Request templates with the "#{mailer_name}/#{action}" as opposed to just "#{action}" - -* Fixed that partials would be broken when using text.plain.erb as the extension #10130 [java] - -* Update README to use new smtp settings configuration API. Closes #10060 [psq] - -* Allow ActionMailer subclasses to individually set their delivery method (so two subclasses can have different delivery methods) #10033 [Zach Dennis] - -* Update TMail to v1.1.0. Use an updated version of TMail if available. [Mikel Lindsaar] - -* Introduce a new base test class for testing Mailers. ActionMailer::TestCase [Michael Koziarski] - -* Fix silent failure of rxml templates. #9879 [jstewart] - -* Fix attachment decoding when using the TMail C extension. #7861 [orangechicken] - -* Increase mail delivery test coverage. #8692 [Kamal Fariz Mahyuddin] - -* Register alternative template engines using ActionMailer::Base.register_template_extension('haml'). #7534 [cwd, Josh Peek] - -* Only load ActionController::UrlWriter if ActionController is present [Rick Olson] - -* Make sure parsed emails recognized attachments nested inside multipart parts. #6714 [Jamis Buck] - -* Allow mailer actions named send by using __send__ internally. #6467 [iGEL] - -* Add assert_emails and assert_no_emails to test the number of emails delivered. #6479 [Jonathan Viney] - # Assert total number of emails delivered: - assert_emails 0 - ContactMailer.deliver_contact - assert_emails 1 - - # Assert number of emails delivered within a block: - assert_emails 1 do - post :signup, :name => 'Jonathan' - end - - -*1.3.3* (March 12th, 2007) - -* Depend on Action Pack 1.13.3 - - -*1.3.2* (February 5th, 2007) - -* Deprecate server_settings renaming it to smtp_settings, add sendmail_settings to allow you to override the arguments to and location of the sendmail executable. [Michael Koziarski] - - -*1.3.1* (January 16th, 2007) - -* Depend on Action Pack 1.13.1 - - -*1.3.0* (January 16th, 2007) - -* Make mime version default to 1.0. closes #2323 [ror@andreas-s.net] - -* Make sure quoted-printable text is decoded correctly when only portions of the text are encoded. closes #3154. [jon@siliconcircus.com] - -* Make sure DOS newlines in quoted-printable text are normalized to unix newlines before unquoting. closes #4166 and #4452. [Jamis Buck] - -* Fixed that iconv decoding should catch InvalidEncoding #3153 [jon@siliconcircus.com] - -* Tighten rescue clauses. #5985 [james@grayproductions.net] - -* Automatically included ActionController::UrlWriter, such that URL generation can happen within ActionMailer controllers. [David Heinemeier Hansson] - -* Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar] - -* Mailer template root applies to a class and its subclasses rather than acting globally. #5555 [somekool@gmail.com] - -* Resolve action naming collision. #5520 [ssinghi@kreeti.com] - -* ActionMailer::Base documentation rewrite. Closes #4991 [Kevin Clark, Marcel Molina Jr.] - -* Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.] - -* Replace Ruby's deprecated append_features in favor of included. [Marcel Molina Jr.] - -* Correct spurious documentation example code which results in a SyntaxError. [Marcel Molina Jr.] - - -*1.2.1* (April 6th, 2006) - -* Be part of Rails 1.1.1 - - -*1.2.0* (March 27th, 2006) - -* Nil charset caused subject line to be improperly quoted in implicitly multipart messages #2662 [ehalvorsen+rails@runbox.com] - -* Parse content-type apart before using it so that sub-parts of the header can be set correctly #2918 [Jamis Buck] - -* Make custom headers work in subparts #4034 [elan@bluemandrill.com] - -* Template paths with dot chars in them no longer mess up implicit template selection for multipart messages #3332 [Chad Fowler] - -* Make sure anything with content-disposition of "attachment" is passed to the attachment presenter when parsing an email body [Jamis Buck] - -* Make sure TMail#attachments includes anything with content-disposition of "attachment", regardless of content-type [Jamis Buck] - - -*1.1.5* (December 13th, 2005) - -* Become part of Rails 1.0 - - -*1.1.4* (December 7th, 2005) - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - -* Stricter matching for implicitly multipart filenames excludes files ending in unsupported extensions (such as foo.rhtml.bak) and without a two-part content type (such as foo.text.rhtml or foo.text.really.plain.rhtml). #2398 [Dave Burt , Jeremy Kemper] - - -*1.1.3* (November 7th, 2005) - -* Allow Mailers to have custom initialize methods that set default instance variables for all mail actions #2563 [mrj@bigpond.net.au] - - -*1.1.2* (October 26th, 2005) - -* Upgraded to Action Pack 1.10.2 - - -*1.1.1* (October 19th, 2005) - -* Upgraded to Action Pack 1.10.1 - - -*1.1.0* (October 16th, 2005) - -* Update and extend documentation (rdoc) - -* Minero Aoki made TMail available to Rails/ActionMailer under the MIT license (instead of LGPL) [RubyConf '05] - -* Austin Ziegler made Text::Simple available to Rails/ActionMailer under a MIT-like licens [See rails ML, subject "Text::Format Licence Exception" on Oct 15, 2005] - -* Fix vendor require paths to prevent files being required twice - -* Don't add charset to content-type header for a part that contains subparts (for AOL compatibility) #2013 [John Long] - -* Preserve underscores when unquoting message bodies #1930 - -* Encode multibyte characters correctly #1894 - -* Multipart messages specify a MIME-Version header automatically #2003 [John Long] - -* Add a unified render method to ActionMailer (delegates to ActionView::Base#render) - -* Move mailer initialization to a separate (overridable) method, so that subclasses may alter the various defaults #1727 - -* Look at content-location header (if available) to determine filename of attachments #1670 - -* ActionMailer::Base.deliver(email) had been accidentally removed, but was documented in the Rails book #1849 - -* Fix problem with sendmail delivery where headers should be delimited by \n characters instead of \r\n, which confuses some mail readers #1742 [Kent Sibilev] - - -*1.0.1* (11 July, 2005) - -* Bind to Action Pack 1.9.1 - - -*1.0.0* (6 July, 2005) - -* Avoid adding nil header values #1392 - -* Better multipart support with implicit multipart/alternative and sorting of subparts [John Long] - -* Allow for nested parts in multipart mails #1570 [Flurin Egger] - -* Normalize line endings in outgoing mail bodies to "\n" #1536 [John Long] - -* Allow template to be explicitly specified #1448 [tuxie@dekadance.se] - -* Allow specific "multipart/xxx" content-type to be set on multipart messages #1412 [Flurin Egger] - -* Unquoted @ characters in headers are now accepted in spite of RFC 822 #1206 - -* Helper support (borrowed from ActionPack) - -* Silently ignore Errno::EINVAL errors when converting text. - -* Don't cause an error when parsing an encoded attachment name #1340 [lon@speedymac.com] - -* Nested multipart message parts are correctly processed in TMail::Mail#body - -* BCC headers are removed when sending via SMTP #1402 - -* Added 'content_type' accessor, to allow content type to be set on a per-message basis. content_type defaults to "text/plain". - -* Silently ignore Iconv::IllegalSequence errors when converting text #1341 [lon@speedymac.com] - -* Support attachments and multipart messages. - -* Added new accessors for the various mail properties. - -* Fix to only perform the charset conversion if a 'from' and a 'to' charset are given (make no assumptions about what the charset was) #1276 [Jamis Buck] - -* Fix attachments and content-type problems #1276 [Jamis Buck] - -* Fixed the TMail#body method to look at the content-transfer-encoding header and unquote the body according to the rules it specifies #1265 [Jamis Buck] - -* Added unquoting even if the iconv lib can't be loaded--in that case, only the charset conversion is skipped #1265 [Jamis Buck] - -* Added automatic decoding of base64 bodies #1214 [Jamis Buck] - -* Added that delivery errors are caught in a way so the mail is still returned whether the delivery was successful or not - -* Fixed that email address like "Jamis Buck, M.D." would cause the quoter to generate emails resulting in "bad address" errors from the mail server #1220 [Jamis Buck] - - -*0.9.1* (20th April, 2005) - -* Depend on Action Pack 1.8.1 - - -*0.9.0* (19th April, 2005) - -* Added that deliver_* will now return the email that was sent - -* Added that quoting to UTF-8 only happens if the characters used are in that range #955 [Jamis Buck] - -* Fixed quoting for all address headers, not just to #955 [Jamis Buck] - -* Fixed unquoting of emails that doesn't have an explicit charset #1036 [wolfgang@stufenlos.net] - - -*0.8.1* (27th March, 2005) - -* Fixed that if charset was found that the end of a mime part declaration TMail would throw an error #919 [lon@speedymac.com] - -* Fixed that TMail::Unquoter would fail to recognize quoting method if it was in lowercase #919 [lon@speedymac.com] - -* Fixed that TMail::Encoder would fail when it attempts to parse e-mail addresses which are encoded using something other than the messages encoding method #919 [lon@speedymac.com] - -* Added rescue for missing iconv library and throws warnings if subject/body is called on a TMail object without it instead - - -*0.8.0* (22th March, 2005) - -* Added framework support for processing incoming emails with an Action Mailer class. See example in README. - - -*0.7.1* (7th March, 2005) - -* Bind to newest Action Pack (1.5.1) - - -*0.7.0* (24th February, 2005) - -* Added support for charsets for both subject and body. The default charset is now UTF-8 #673 [Jamis Buck]. Examples: - - def iso_charset(recipient) - @recipients = recipient - @subject = "testing iso charsets" - @from = "system@loudthinking.com" - @body = "Nothing to see here." - @charset = "iso-8859-1" - end - - def unencoded_subject(recipient) - @recipients = recipient - @subject = "testing unencoded subject" - @from = "system@loudthinking.com" - @body = "Nothing to see here." - @encode_subject = false - @charset = "iso-8859-1" - end - - -*0.6.1* (January 18th, 2005) - -* Fixed sending of emails to use Tmail#from not the deprecated Tmail#from_address - - -*0.6* (January 17th, 2005) - -* Fixed that bcc and cc should be settable through @bcc and @cc -- not just @headers["Bcc"] and @headers["Cc"] #453 [Eric Hodel] - -* Fixed Action Mailer to be "warnings safe" so you can run with ruby -w and not get framework warnings #453 [Eric Hodel] - - -*0.5* - -* Added access to custom headers, like cc, bcc, and reply-to #268 [Andreas Schwarz]. Example: - - def post_notification(recipients, post) - @recipients = recipients - @from = post.author.email_address_with_name - @headers["bcc"] = SYSTEM_ADMINISTRATOR_EMAIL - @headers["reply-to"] = "notifications@example.com" - @subject = "[#{post.account.name} #{post.title}]" - @body["post"] = post - end - -*0.4* (5) - -* Consolidated the server configuration options into Base#server_settings= and expanded that with controls for authentication and more [Marten] - NOTE: This is an API change that could potentially break your application if you used the old application form. Please do change! - -* Added Base#deliveries as an accessor for an array of emails sent out through that ActionMailer class when using the :test delivery option. [Jeremy Kemper] - -* Added Base#perform_deliveries= which can be set to false to turn off the actual delivery of the email through smtp or sendmail. - This is especially useful for functional testing that shouldn't send off real emails, but still trigger delivery_* methods. - -* Added option to specify delivery method with Base#delivery_method=. Default is :smtp and :sendmail is currently the only other option. - Sendmail is assumed to be present at "/usr/sbin/sendmail" if that option is used. [Kent Sibilev] - -* Dropped "include TMail" as it added to much baggage into the default namespace (like Version) [Chad Fowler] - - -*0.3* - -* First release diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md new file mode 100644 index 0000000000..57af4ee6a4 --- /dev/null +++ b/actionmailer/CHANGELOG.md @@ -0,0 +1,449 @@ +## Rails 3.1.0 (August 30, 2011) ## + +* No changes + + +## Rails 3.0.7 (April 18, 2011) ## + +* remove AM delegating register_observer and register_interceptor to Mail *Josh Kalderimis* + + +* Rails 3.0.6 (April 5, 2011) + +* Don't allow i18n to change the minor version, version now set to ~> 0.5.0 *Santiago Pastorino* + + +## Rails 3.0.5 (February 26, 2011) ## + +* No changes. + + +## Rails 3.0.4 (February 8, 2011) ## + +* No changes. + + +## Rails 3.0.3 (November 16, 2010) ## + +* No changes. + + +## Rails 3.0.2 (November 15, 2010) ## + +* No changes + + +## Rails 3.0.1 (October 15, 2010) ## + +* No Changes, just a version bump. + + +## Rails 3.0.0 (August 29, 2010) ## + +* subject is automatically looked up on I18n using mailer_name and action_name as scope as in t(".subject") *JK* + +* Changed encoding behaviour of mail, so updated tests in actionmailer and bumped mail version to 2.2.1 *ML* + +* Added ability to pass Proc objects to the defaults hash *ML* + +* Removed all quoting.rb type files from ActionMailer and put Mail 2.2.0 in instead *ML* + +* Lot of updates to various test cases that now work better with the new Mail and so have different expectations + +* Added interceptors and observers from Mail *ML* + + ActionMailer::Base.register_interceptor calls Mail.register_interceptor + ActionMailer::Base.register_observer calls Mail.register_observer + +* Mail::Part now no longer has nil as a default charset, it is always set to something, and defaults to UTF-8 + +* Added explict setting of charset in set_fields! method to make sure Mail has the user defined default + +* Removed quoting.rb and refactored for Mail to take responsibility of all quoting and auto encoding requirements for the header. + +* Fixed several tests which had incorrect encoding. + +* Changed all utf-8 to UTF-8 for consistency + +* Whole new API added with tests. See base.rb for full details. Old API is deprecated. + +* The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted + +* Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'} + +* ActionMailer::Base :default_implicit_parts_order now is in the sequence of the order you want, no reversing of ordering takes place. The default order now is text/plain, then text/enriched, then text/html and then any other part that is not one of these three. + +* Mail does not have "quoted_body", "quoted_subject" etc. All of these are accessed via body.encoded, subject.encoded etc + +* Every object in a Mail object returns an object, never a string. So Mail.body returns a Mail::Body class object, need to call #encoded or #decoded to get the string you want. +* Mail::Message#set_content_type does not exist, it is simply Mail::Message#content_type + +* Every mail message gets a unique message_id unless you specify one, had to change all the tests that check for equality with expected.encoded == actual.encoded to first replace their message_ids with control values + +* Mail now has a proper concept of parts, remove the ActionMailer::Part and ActionMailer::PartContainer classes + +* Calling #encoded on any object returns it as a string ready to go into the output stream of an email, this means it includes the \r\n at the end of the lines and the object is pre-wrapped with \r\n\t if it is a header field. Also, the "encoded" value includes the field name if it is a header field. + +* Attachments are only the actual attachment, with filename etc. A part contains an attachment. The part has the content_type etc. So attachments.last.content_type is invalid. But parts.last.content_type + +* There is no idea of a "sub_head" in Mail. A part is just a Message with some extra functionality, so it just has a "header" like a normal mail message + + +## 2.3.2 Final (March 15, 2009) ## + +* Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP #1842 *Matt Jones* + +* Fixed RFC-2045 quoted-printable bug #1421 *squadette* + +* Fixed that no body charset would be set when there are attachments present #740 *Paweł Kondzior* + + +## 2.2.1 RC2 (November 14th, 2008) ## + +* Turn on STARTTLS if it is available in Net::SMTP (added in Ruby 1.8.7) and the SMTP server supports it (This is required for Gmail's SMTP server) #1336 *Grant Hollingworth* + + +## 2.2.0 RC1 (October 24th, 2008) ## + +* Add layout functionality to mailers *Pratik Naik* + + 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* + +* Less verbose mail logging: just recipients for :info log level; the whole email for :debug only. #8000 *iaddict, Tarmo Tänav* + +* Updated TMail to version 1.2.1 *Mikel Lindsaar* + +* Fixed that you don't have to call super in ActionMailer::TestCase#setup #10406 *jamesgolick* + + +## 2.0.2 (December 16th, 2007) ## + +* Included in Rails 2.0.2 + + +## 2.0.1 (December 7th, 2007) ## + +* Update ActionMailer so it treats ActionView the same way that ActionController does. Closes #10244 *Rick Olson* + + * Pass the template_root as an array as ActionView's view_path + * Request templates with the "#{mailer_name}/#{action}" as opposed to just "#{action}" + +* Fixed that partials would be broken when using text.plain.erb as the extension #10130 *java* + +* Update README to use new smtp settings configuration API. Closes #10060 *psq* + +* Allow ActionMailer subclasses to individually set their delivery method (so two subclasses can have different delivery methods) #10033 *Zach Dennis* + +* Update TMail to v1.1.0. Use an updated version of TMail if available. *Mikel Lindsaar* + +* Introduce a new base test class for testing Mailers. ActionMailer::TestCase *Michael Koziarski* + +* Fix silent failure of rxml templates. #9879 *jstewart* + +* Fix attachment decoding when using the TMail C extension. #7861 *orangechicken* + +* Increase mail delivery test coverage. #8692 *Kamal Fariz Mahyuddin* + +* Register alternative template engines using ActionMailer::Base.register_template_extension('haml'). #7534 *cwd, Josh Peek* + +* Only load ActionController::UrlWriter if ActionController is present *Rick Olson* + +* Make sure parsed emails recognized attachments nested inside multipart parts. #6714 *Jamis Buck* + +* Allow mailer actions named send by using __send__ internally. #6467 *iGEL* + +* Add assert_emails and assert_no_emails to test the number of emails delivered. #6479 *Jonathan Viney* + # Assert total number of emails delivered: + assert_emails 0 + ContactMailer.deliver_contact + assert_emails 1 + + # Assert number of emails delivered within a block: + assert_emails 1 do + post :signup, :name => 'Jonathan' + end + + +## 1.3.3 (March 12th, 2007) ## + +* Depend on Action Pack 1.13.3 + + +## 1.3.2 (February 5th, 2007) ## + +* Deprecate server_settings renaming it to smtp_settings, add sendmail_settings to allow you to override the arguments to and location of the sendmail executable. *Michael Koziarski* + + +## 1.3.1 (January 16th, 2007) ## + +* Depend on Action Pack 1.13.1 + + +## 1.3.0 (January 16th, 2007) ## + +* Make mime version default to 1.0. closes #2323 *ror@andreas-s.net* + +* Make sure quoted-printable text is decoded correctly when only portions of the text are encoded. closes #3154. *jon@siliconcircus.com* + +* Make sure DOS newlines in quoted-printable text are normalized to unix newlines before unquoting. closes #4166 and #4452. *Jamis Buck* + +* Fixed that iconv decoding should catch InvalidEncoding #3153 *jon@siliconcircus.com* + +* Tighten rescue clauses. #5985 *james@grayproductions.net* + +* Automatically included ActionController::UrlWriter, such that URL generation can happen within ActionMailer controllers. *David Heinemeier Hansson* + +* Replace Reloadable with Reloadable::Deprecated. *Nicholas Seckar* + +* Mailer template root applies to a class and its subclasses rather than acting globally. #5555 *somekool@gmail.com* + +* Resolve action naming collision. #5520 *ssinghi@kreeti.com* + +* ActionMailer::Base documentation rewrite. Closes #4991 *Kevin Clark, Marcel Molina Jr.* + +* Replace alias method chaining with Module#alias_method_chain. *Marcel Molina Jr.* + +* Replace Ruby's deprecated append_features in favor of included. *Marcel Molina Jr.* + +* Correct spurious documentation example code which results in a SyntaxError. *Marcel Molina Jr.* + + +## 1.2.1 (April 6th, 2006) ## + +* Be part of Rails 1.1.1 + + +## 1.2.0 (March 27th, 2006) ## + +* Nil charset caused subject line to be improperly quoted in implicitly multipart messages #2662 *ehalvorsen+rails@runbox.com* + +* Parse content-type apart before using it so that sub-parts of the header can be set correctly #2918 *Jamis Buck* + +* Make custom headers work in subparts #4034 *elan@bluemandrill.com* + +* Template paths with dot chars in them no longer mess up implicit template selection for multipart messages #3332 *Chad Fowler* + +* Make sure anything with content-disposition of "attachment" is passed to the attachment presenter when parsing an email body *Jamis Buck* + +* Make sure TMail#attachments includes anything with content-disposition of "attachment", regardless of content-type *Jamis Buck* + + +## 1.1.5 (December 13th, 2005) ## + +* Become part of Rails 1.0 + + +## 1.1.4 (December 7th, 2005) ## + +* Rename Version constant to VERSION. #2802 *Marcel Molina Jr.* + +* Stricter matching for implicitly multipart filenames excludes files ending in unsupported extensions (such as foo.rhtml.bak) and without a two-part content type (such as foo.text.rhtml or foo.text.really.plain.rhtml). #2398 *Dave Burt , Jeremy Kemper* + + +## 1.1.3 (November 7th, 2005) ## + +* Allow Mailers to have custom initialize methods that set default instance variables for all mail actions #2563 *mrj@bigpond.net.au* + + +## 1.1.2 (October 26th, 2005) ## + +* Upgraded to Action Pack 1.10.2 + + +## 1.1.1 (October 19th, 2005) ## + +* Upgraded to Action Pack 1.10.1 + + +## 1.1.0 (October 16th, 2005) ## + +* Update and extend documentation (rdoc) + +* Minero Aoki made TMail available to Rails/ActionMailer under the MIT license (instead of LGPL) *RubyConf '05* + +* Austin Ziegler made Text::Simple available to Rails/ActionMailer under a MIT-like licens *See rails ML, subject "Text::Format Licence Exception" on Oct 15, 2005* + +* Fix vendor require paths to prevent files being required twice + +* Don't add charset to content-type header for a part that contains subparts (for AOL compatibility) #2013 *John Long* + +* Preserve underscores when unquoting message bodies #1930 + +* Encode multibyte characters correctly #1894 + +* Multipart messages specify a MIME-Version header automatically #2003 *John Long* + +* Add a unified render method to ActionMailer (delegates to ActionView::Base#render) + +* Move mailer initialization to a separate (overridable) method, so that subclasses may alter the various defaults #1727 + +* Look at content-location header (if available) to determine filename of attachments #1670 + +* ActionMailer::Base.deliver(email) had been accidentally removed, but was documented in the Rails book #1849 + +* Fix problem with sendmail delivery where headers should be delimited by \n characters instead of \r\n, which confuses some mail readers #1742 *Kent Sibilev* + + +## 1.0.1 (11 July, 2005) ## + +* Bind to Action Pack 1.9.1 + + +## 1.0.0 (6 July, 2005) ## + +* Avoid adding nil header values #1392 + +* Better multipart support with implicit multipart/alternative and sorting of subparts *John Long* + +* Allow for nested parts in multipart mails #1570 *Flurin Egger* + +* Normalize line endings in outgoing mail bodies to "\n" #1536 *John Long* + +* Allow template to be explicitly specified #1448 *tuxie@dekadance.se* + +* Allow specific "multipart/xxx" content-type to be set on multipart messages #1412 *Flurin Egger* + +* Unquoted @ characters in headers are now accepted in spite of RFC 822 #1206 + +* Helper support (borrowed from ActionPack) + +* Silently ignore Errno::EINVAL errors when converting text. + +* Don't cause an error when parsing an encoded attachment name #1340 *lon@speedymac.com* + +* Nested multipart message parts are correctly processed in TMail::Mail#body + +* BCC headers are removed when sending via SMTP #1402 + +* Added 'content_type' accessor, to allow content type to be set on a per-message basis. content_type defaults to "text/plain". + +* Silently ignore Iconv::IllegalSequence errors when converting text #1341 *lon@speedymac.com* + +* Support attachments and multipart messages. + +* Added new accessors for the various mail properties. + +* Fix to only perform the charset conversion if a 'from' and a 'to' charset are given (make no assumptions about what the charset was) #1276 *Jamis Buck* + +* Fix attachments and content-type problems #1276 *Jamis Buck* + +* Fixed the TMail#body method to look at the content-transfer-encoding header and unquote the body according to the rules it specifies #1265 *Jamis Buck* + +* Added unquoting even if the iconv lib can't be loaded--in that case, only the charset conversion is skipped #1265 *Jamis Buck* + +* Added automatic decoding of base64 bodies #1214 *Jamis Buck* + +* Added that delivery errors are caught in a way so the mail is still returned whether the delivery was successful or not + +* Fixed that email address like "Jamis Buck, M.D." would cause the quoter to generate emails resulting in "bad address" errors from the mail server #1220 *Jamis Buck* + + +## 0.9.1 (20th April, 2005) ## + +* Depend on Action Pack 1.8.1 + + +## 0.9.0 (19th April, 2005) ## + +* Added that deliver_* will now return the email that was sent + +* Added that quoting to UTF-8 only happens if the characters used are in that range #955 *Jamis Buck* + +* Fixed quoting for all address headers, not just to #955 *Jamis Buck* + +* Fixed unquoting of emails that doesn't have an explicit charset #1036 *wolfgang@stufenlos.net* + + +## 0.8.1 (27th March, 2005) ## + +* Fixed that if charset was found that the end of a mime part declaration TMail would throw an error #919 *lon@speedymac.com* + +* Fixed that TMail::Unquoter would fail to recognize quoting method if it was in lowercase #919 *lon@speedymac.com* + +* Fixed that TMail::Encoder would fail when it attempts to parse e-mail addresses which are encoded using something other than the messages encoding method #919 *lon@speedymac.com* + +* Added rescue for missing iconv library and throws warnings if subject/body is called on a TMail object without it instead + + +## 0.8.0 (22th March, 2005) ## + +* Added framework support for processing incoming emails with an Action Mailer class. See example in README. + + +## 0.7.1 (7th March, 2005) ## + +* Bind to newest Action Pack (1.5.1) + + +## 0.7.0 (24th February, 2005) ## + +* Added support for charsets for both subject and body. The default charset is now UTF-8 #673 [Jamis Buck]. Examples: + + def iso_charset(recipient) + @recipients = recipient + @subject = "testing iso charsets" + @from = "system@loudthinking.com" + @body = "Nothing to see here." + @charset = "iso-8859-1" + end + + def unencoded_subject(recipient) + @recipients = recipient + @subject = "testing unencoded subject" + @from = "system@loudthinking.com" + @body = "Nothing to see here." + @encode_subject = false + @charset = "iso-8859-1" + end + + +## 0.6.1 (January 18th, 2005) ## + +* Fixed sending of emails to use Tmail#from not the deprecated Tmail#from_address + + +## 0.6 (January 17th, 2005) ## + +* Fixed that bcc and cc should be settable through @bcc and @cc -- not just @headers["Bcc"] and @headers["Cc"] #453 *Eric Hodel* + +* Fixed Action Mailer to be "warnings safe" so you can run with ruby -w and not get framework warnings #453 *Eric Hodel* + + +## 0.5 ## + +* Added access to custom headers, like cc, bcc, and reply-to #268 [Andreas Schwarz]. Example: + + def post_notification(recipients, post) + @recipients = recipients + @from = post.author.email_address_with_name + @headers["bcc"] = SYSTEM_ADMINISTRATOR_EMAIL + @headers["reply-to"] = "notifications@example.com" + @subject = "[#{post.account.name} #{post.title}]" + @body["post"] = post + end + +## 0.4 (5) ## + +* Consolidated the server configuration options into Base#server_settings= and expanded that with controls for authentication and more *Marten* + NOTE: This is an API change that could potentially break your application if you used the old application form. Please do change! + +* Added Base#deliveries as an accessor for an array of emails sent out through that ActionMailer class when using the :test delivery option. *Jeremy Kemper* + +* Added Base#perform_deliveries= which can be set to false to turn off the actual delivery of the email through smtp or sendmail. + This is especially useful for functional testing that shouldn't send off real emails, but still trigger delivery_* methods. + +* Added option to specify delivery method with Base#delivery_method=. Default is :smtp and :sendmail is currently the only other option. + Sendmail is assumed to be present at "/usr/sbin/sendmail" if that option is used. *Kent Sibilev* + +* Dropped "include TMail" as it added to much baggage into the default namespace (like Version) *Chad Fowler* + + +## 0.3 ## + +* First release diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG deleted file mode 100644 index a7a47bf930..0000000000 --- a/actionpack/CHANGELOG +++ /dev/null @@ -1,5689 +0,0 @@ -*Rails 3.2.0 (unreleased)* - -* Responders now return 204 No Content for API requests without a response body (as in the new scaffold) [José Valim] - -* Added ActionDispatch::RequestId middleware that'll make a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog [DHH] - -* Limit the number of options for select_year to 1000. - - Pass the :max_years_allowed option to set your own limit. - - [Libo Cannici] - -* Passing formats or handlers to render :template and friends is deprecated. For example: [Nick Sutterer & José Valim] - - render :template => "foo.html.erb" - - Instead, you can provide :handlers and :formats directly as option: - - render :template => "foo", :formats => [:html, :js], :handlers => :erb - -* Changed log level of warning for missing CSRF token from :debug to :warn. [Mike Dillon] - -* content_tag_for and div_for can now take the collection of records. It will also yield the record as the first argument if you set a receiving argument in your block [Prem Sichanugrist] - - So instead of having to do this: - - @items.each do |item| - content_tag_for(:li, item) do - Title: <%= item.title %> - end - end - - You can now do this: - - content_tag_for(:li, @items) do |item| - Title: <%= item.title %> - end - -* send_file now guess the mime type [Esad Hajdarevic] - -* Mime type entries for PDF, ZIP and other formats were added [Esad Hajdarevic] - -* Generate hidden input before select with :multiple option set to true. - This is useful when you rely on the fact that when no options is set, - the state of select will be sent to rails application. Without hidden field - nothing is sent according to HTML spec [Bogdan Gusiev] - -* Refactor ActionController::TestCase cookies [Andrew White] - - Assigning cookies for test cases should now use cookies[], e.g: - - cookies[:email] = 'user@example.com' - get :index - assert_equal 'user@example.com', cookies[:email] - - To clear the cookies, use clear, e.g: - - cookies.clear - get :index - assert_nil cookies[:email] - - We now no longer write out HTTP_COOKIE and the cookie jar is - persistent between requests so if you need to manipulate the environment - for your test you need to do it before the cookie jar is created. - - -*Rails 3.1.1 (unreleased)* - -* javascript_path and stylesheet_path now refer to /assets if asset pipelining -is on. [Santiago Pastorino] - -* button_to support form option. Now you're able to pass for example -'data-type' => 'json'. [ihower] - -* image_path and image_tag should use /assets if asset pipelining is turned -on. Closes #3126 [Santiago Pastorino and christos] - -* Avoid use of existing precompiled assets during rake assets:precompile run. -Closes #3119 [Guillermo Iguaran] - -* Copy assets to nondigested filenames too [Santiago Pastorino] - -* Give precedence to `config.digest = false` over the existence of -manifest.yml asset digests [christos] - -* escape options for the stylesheet_link_tag method [Alexey Vakhov] - -* Re-launch assets:precompile task using (Rake.)ruby instead of Kernel.exec so -it works on Windows [cablegram] - -* env var passed to process shouldn't be modified in process method. [Santiago -Pastorino] - -* `rake assets:precompile` loads the application but does not initialize -it. - - To the app developer, this means configuration add in - config/initializers/* will not be executed. - - Plugins developers need to special case their initializers that are - meant to be run in the assets group by adding :group => :assets. [José Valim] - -* Sprockets uses config.assets.prefix for asset_path [asee] - -* FileStore key_file_path properly limit filenames to 255 characters. [phuibonhoa] - -* Fix Hash#to_query edge case with html_safe strings. [brainopia] - -* Allow asset tag helper methods to accept :digest => false option in order to completely avoid the digest generation. -Useful for linking assets from static html files or from emails when the user -could probably look at an older html email with an older asset. [Santiago Pastorino] - -* Don't mount Sprockets server at config.assets.prefix if config.assets.compile is false. [Mark J. Titorenko] - -* Set relative url root in assets when controller isn't available for Sprockets (eg. Sass files using asset_path). Fixes #2435 [Guillermo Iguaran] - -* Fix basic auth credential generation to not make newlines. GH #2882 - -* Fixed the behavior of asset pipeline when config.assets.digest and config.assets.compile are false and requested asset isn't precompiled. - Before the requested asset were compiled anyway ignoring that the config.assets.compile flag is false. [Guillermo Iguaran] - -* CookieJar is now Enumerable. Fixes #2795 - -* Fixed AssetNotPrecompiled error raised when rake assets:precompile is compiling certain .erb files. See GH #2763 #2765 #2805 [Guillermo Iguaran] - -* Manifest is correctly placed in assets path when default assets prefix is changed. Fixes #2776 [Guillermo Iguaran] - -* Fixed stylesheet_link_tag and javascript_include_tag to respect additional options passed by the users when debug is on. [Guillermo Iguaran] - - -*Rails 3.1.0 (August 30, 2011)* - -* Param values are `paramified` in controller tests. [David Chelimsky] - -* x_sendfile_header now defaults to nil and config/environments/production.rb doesn't set a particular value for it. This allows servers to set it through X-Sendfile-Type. [Santiago Pastorino] - -* The submit form helper does not generate an id "object_name_id" anymore. [fbrusatti] - -* Make sure respond_with with :js tries to render a template in all cases [José Valim] - -* json_escape will now return a SafeBuffer string if it receives SafeBuffer string [tenderlove] - -* Make sure escape_js returns SafeBuffer string if it receives SafeBuffer string [Prem Sichanugrist] - -* Fix escape_js to work correctly with the new SafeBuffer restriction [Paul Gallagher] - -* Brought back alternative convention for namespaced models in i18n [thoefer] - - Now the key can be either "namespace.model" or "namespace/model" until further deprecation. - -* It is prohibited to perform a in-place SafeBuffer mutation [tenderlove] - - The old behavior of SafeBuffer allowed you to mutate string in place via - method like `sub!`. These methods can add unsafe strings to a safe buffer, - and the safe buffer will continue to be marked as safe. - - An example problem would be something like this: - - <%= link_to('hello world', @user).sub!(/hello/, params[:xss]) %> - - In the above example, an untrusted string (`params[:xss]`) is added to the - safe buffer returned by `link_to`, and the untrusted content is successfully - sent to the client without being escaped. To prevent this from happening - `sub!` and other similar methods will now raise an exception when they are called on a safe buffer. - - In addition to the in-place versions, some of the versions of these methods which return a copy of the string will incorrectly mark strings as safe. For example: - - <%= link_to('hello world', @user).sub(/hello/, params[:xss]) %> - - The new versions will now ensure that *all* strings returned by these methods on safe buffers are marked unsafe. - - You can read more about this change in http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2e516e7acc96c4fb - -* Warn if we cannot verify CSRF token authenticity [José Valim] - -* Allow AM/PM format in datetime selectors [Aditya Sanghi] - -* Only show dump of regular env methods on exception screen (not all the rack crap) [DHH] - -* auto_link has been removed with no replacement. If you still use auto_link - please install the rails_autolink gem: - http://github.com/tenderlove/rails_autolink - - [tenderlove] - -* Added streaming support, you can enable it with: [José Valim] - - class PostsController < ActionController::Base - stream :only => :index - end - - Please read the docs at `ActionController::Streaming` for more information. - -* Added `ActionDispatch::Request.ignore_accept_header` to ignore accept headers and only consider the format given as parameter [José Valim] - -* Created `ActionView::Renderer` and specified an API for `ActionView::Context`, check those objects for more information [José Valim] - -* Added `ActionController::ParamsWrapper` to wrap parameters into a nested hash, and will be turned on for JSON request in new applications by default [Prem Sichanugrist] - - This can be customized by setting `ActionController::Base.wrap_parameters` in `config/initializer/wrap_parameters.rb` - -* RJS has been extracted out to a gem. [fxn] - -* Implicit actions named not_implemented can be rendered. [Santiago Pastorino] - -* Wildcard route will always match the optional format segment by default. [Prem Sichanugrist] - - For example if you have this route: - - match '*pages' => 'pages#show' - - by requesting '/foo/bar.json', your `params[:pages]` will be equals to "foo/bar" with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `:format => false` like this: - - match '*pages' => 'pages#show', :format => false - -* Added Base.http_basic_authenticate_with to do simple http basic authentication with a single class method call [DHH] - - class PostsController < ApplicationController - USER_NAME, PASSWORD = "dhh", "secret" - - before_filter :authenticate, :except => [ :index ] - - def index - render :text => "Everyone can see me!" - end - - def edit - render :text => "I'm only accessible if you know the password" - end - - private - def authenticate - authenticate_or_request_with_http_basic do |user_name, password| - user_name == USER_NAME && password == PASSWORD - end - end - end - - ..can now be written as - - class PostsController < ApplicationController - http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index - - def index - render :text => "Everyone can see me!" - end - - def edit - render :text => "I'm only accessible if you know the password" - end - end - -* Allow you to add `force_ssl` into controller to force browser to transfer data via HTTPS protocol on that particular controller. You can also specify `:only` or `:except` to specific it to particular action. [DHH and Prem Sichanugrist] - -* Allow FormHelper#form_for to specify the :method as a direct option instead of through the :html hash [DHH] - - form_for(@post, remote: true, method: :delete) instead of form_for(@post, remote: true, html: { method: :delete }) - -* Make JavaScriptHelper#j() an alias for JavaScriptHelper#escape_javascript() -- note this then supersedes the Object#j() method that the JSON gem adds within templates using the JavaScriptHelper [DHH] - -* Sensitive query string parameters (specified in config.filter_parameters) will now be filtered out from the request paths in the log file. [Prem Sichanugrist, fxn] - -* URL parameters which return false for to_param now appear in the query string (previously they were removed) [Andrew White] - -* URL parameters which return nil for to_param are now removed from the query string [Andrew White] - -* ActionDispatch::MiddlewareStack now uses composition over inheritance. It is -no longer an array which means there may be methods missing that were not -tested. - -* Add an :authenticity_token option to form_tag for custom handling or to omit the token (pass :authenticity_token => false). [Jakub Kuźma, Igor Wiedler] - -* HTML5 button_tag helper. [Rizwan Reza] - -* Template lookup now searches further up in the inheritance chain. [Artemave] - -* Brought back config.action_view.cache_template_loading, which allows to decide whether templates should be cached or not. [Piotr Sarnacki] - -* url_for and named url helpers now accept :subdomain and :domain as options, [Josh Kalderimis] - -* The redirect route method now also accepts a hash of options which will only change the parts of the url in question, or an object which responds to call, allowing for redirects to be reused (check the documentation for examples). [Josh Kalderimis] - -* Added config.action_controller.include_all_helpers. By default 'helper :all' is done in ActionController::Base, which includes all the helpers by default. Setting include_all_helpers to false will result in including only application_helper and helper corresponding to controller (like foo_helper for foo_controller). [Piotr Sarnacki] - -* Added a convenience idiom to generate HTML5 data-* attributes in tag helpers from a :data hash of options: - - tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)}) - # =>
- - Keys are dasherized. Values are JSON-encoded, except for strings and symbols. [Stephen Celis] - -* Deprecate old template handler API. The new API simply requires a template handler to respond to call. [José Valim] - -* :rhtml and :rxml were finally removed as template handlers. [José Valim] - -* Moved etag responsibility from ActionDispatch::Response to the middleware stack. [José Valim] - -* Rely on Rack::Session stores API for more compatibility across the Ruby world. This is backwards incompatible since Rack::Session expects #get_session to accept 4 arguments and requires #destroy_session instead of simply #destroy. [José Valim] - -* file_field automatically adds :multipart => true to the enclosing form. [Santiago Pastorino] - -* Renames csrf_meta_tag -> csrf_meta_tags, and aliases csrf_meta_tag for backwards compatibility. [fxn] - -* Add Rack::Cache to the default stack. Create a Rails store that delegates to the Rails cache, so by default, whatever caching layer you are using will be used for HTTP caching. Note that Rack::Cache will be used if you use #expires_in, #fresh_when or #stale with :public => true. Otherwise, the caching rules will apply to the browser only. [Yehuda Katz, Carl Lerche] - - -*Rails 3.0.7 (April 18, 2011)* - -*No changes. - - -*Rails 3.0.6 (April 5, 2011) - -* Fixed XSS vulnerability in `auto_link`. `auto_link` no longer marks input as - html safe. Please make sure that calls to auto_link() are wrapped in a - sanitize(), or a raw() depending on the type of input passed to auto_link(). - For example: - - <%= sanitize(auto_link(some_user_input)) %> - - Thanks to Torben Schulz for reporting this. The fix can be found here: - 61ee3449674c591747db95f9b3472c5c3bd9e84d - -* Fixes the output of `rake routes` to be correctly match to the behavior of the application, as the regular expression used to match the path is greedy and won't capture the format part by default [Prem Sichanugrist] - -* Fixes an issue with number_to_human when converting values which are less than 1 but greater than -1 [Josh Kalderimis] - -* Sensitive query string parameters (specified in config.filter_parameters) will now be filtered out from the request paths in the log file. [Prem Sichanugrist, fxn] - -* URL parameters which return nil for to_param are now removed from the query string [Andrew White] - -* Don't allow i18n to change the minor version, version now set to ~> 0.5.0 [Santiago Pastorino] - -* Make TranslationHelper#translate use the :rescue_format option in I18n 0.5.0 [Sven Fuchs] - -* Fix regression: javascript_include_tag shouldn't raise if you register an expansion key with nil or [] value [Santiago Pastorino] - -* Fix Action caching bug where an action that has a non-cacheable response always renders a nil response body. It now correctly renders the response body. [Cheah Chu Yeow] - - -*Rails 3.0.5 (February 26, 2011)* - -* No changes. - - -*Rails 3.0.4 (February 8, 2011)* - -* No changes. - - -*Rails 3.0.3 (November 16, 2010)* - -* When ActiveRecord::Base objects are sent to predicate methods, the id of the object should be sent to ARel, not the ActiveRecord::Base object. - -* :constraints routing should only do sanity checks against regular expressions. String arguments are OK. - - -*Rails 3.0.2 (November 15, 2010)* - -* The helper number_to_currency accepts a new :negative_format option to be able to configure how to render negative amounts. [Don Wilson] - - -*Rails 3.0.1 (October 15, 2010)* - -* No Changes, just a version bump. - - -*Rails 3.0.0 (August 29, 2010)* - -* password_field renders with nil value by default making the use of passwords secure by default, if you want to render you should do for instance f.password_field(:password, :value => @user.password) [Santiago Pastorino] - -* Symbols and strings in routes should yield the same behavior. Note this may break existing apps that were using symbols with the new routes API. [José Valim] - -* Add clear_helpers as a way to clean up all helpers added to this controller, maintaining just the helper with the same name as the controller. [José Valim] - -* Support routing constraints in functional tests. [Andrew White] - -* Add a header that tells Internet Explorer (all versions) to use the best available standards support. [Yehuda Katz] - -* Allow stylesheet/javascript extensions to be changed through railties. [Josh Kalderimis] - -* link_to, button_to, and tag/tag_options now rely on html_escape instead of escape_once. [fxn] - -* url_for returns always unescaped strings, and the :escape option is gone. [fxn] - -* Added accept-charset parameter and _snowman hidden field to force the contents - of Rails POSTed forms to be in UTF-8 [Yehuda Katz] - -* Upgrade to Rack 1.2.1 [Jeremy Kemper] - -* Allow :path to be given to match/get/post/put/delete instead of :path_names in the new router [Carlos Antônio da Silva] - -* Added resources_path_names to the new router DSL [José Valim] - -* Allow options to be given to the namespace method in the new router [Carlos Antônio da Silva] - -* Deprecate :name_prefix in the new router DSL [José Valim] - -* Add shallow routes back to the new router [Diego Carrion, Andrew White] - - resources :posts do - shallow do - resources :comments - end - end - - You can now use comment_path for /comments/1 instead of post_comment_path for /posts/1/comments/1. - -* Add support for multi-subdomain session by setting cookie host in session cookie so you can share session between www.example.com, example.com and user.example.com. #4818 [Guillermo Álvarez] - -* Removed textilize, textilize_without_paragraph and markdown helpers. [Santiago Pastorino] - -* Remove middleware laziness [José Valim] - -* Make session stores rely on request.cookie_jar and change set_session semantics to return the cookie value instead of a boolean. [José Valim] - -* OAuth 2: HTTP Token Authorization support to complement Basic and Digest Authorization. [Rick Olson] - -* Fixed inconsistencies in form builder and view helpers #4432 [Neeraj Singh] - -* Both :xml and :json renderers now forwards the given options to the model, allowing you to invoke them as render :xml => @projects, :include => :tasks [José Valim, Yehuda Katz] - -* Renamed the field error CSS class from fieldWithErrors to field_with_errors for consistency. [Jeremy Kemper] - -* Add support for shorthand routes like /projects/status(.:format) #4423 [Diego Carrion] - -* Changed translate helper so that it doesn’t mark every translation as safe HTML. Only keys with a "_html" suffix and keys named "html" are considered to be safe HTML. All other translations are left untouched. [Craig Davey] - -* New option :as added to form_for allows to change the object name. The old <% form_for :client, @post %> becomes <% form_for @post, :as => :client %> [spastorino] - -* Removed verify method in controllers. [JV] - It's now available as a plugin at http://github.com/rails/verification - -* Removed input, form, error_messages_for and error_message_on from views. [JV] - It's now available as a plugin at http://github.com/rails/dynamic_form - -* Routes can be scoped by controller module. [Jeremy Kemper] - - # /session => Auth::SessionsController - scope :module => 'auth' do - resource :session - end - -* Added #favicon_link_tag, it uses #image_path so in particular the favicon gets an asset ID [fxn] - -* Fixed that default locale templates should be used if the current locale template is missing [DHH] - -* Added all the new HTML5 form types as individual form tag methods (search, url, number, etc) #3646 [Stephen Celis] - -* Changed the object used in routing constraints to be an instance of - ActionDispatch::Request rather than Rack::Request [YK] - -* Changed ActionDispatch::Request#method to return a String, to be compatible - with Rack::Request. Added ActionDispatch::Request#method_symbol to - return a symbol form of the request method. [YK] - -* Changed ActionDispatch::Request#method to return the original - method and #request_method to return the overridden method in the - case of methodoverride being used (this means that #method returns - "HEAD" and #request_method returns "GET" in HEAD requests). This - is for compatibility with Rack::Request [YK] - -* #concat is now deprecated in favor of using <%= %> helpers [YK] - -* Block helpers now return Strings, so you can use <%= form_for @foo do |f| %>. - <% form_for do |f| %> still works with deprecation notices [YK] - -* Add a new #mount method on the router that does not anchor the PATH_INFO - at the end [YK & CL] - -* Create a new LookupContext object that is responsible for performantly - finding a template for a given pattern [JV] - -* Removed relative_url_for in favor of respecting SCRIPT_NAME [YK & CL] - -* Changed file streaming to use Rack::Sendfile middleware [YK] - -* ActionDispatch::Request#content_type returns a String to be compatible with - Rack::Request. Use #content_mime_type for the Mime::Type instance [YK] - -* Updated Prototype to 1.6.1 and Scriptaculous to 1.8.3 [ML] - -* Change the preferred way that URL helpers are included into a class[YK & CL] - - # for all helpers including named routes - include Rails.application.router.url_helpers - - # for just url_for - include Rails.application.router.url_for - -* Fixed that PrototypeHelper#update_page should return html_safe [DHH] - -* Fixed that much of DateHelper wouldn't return html_safe? strings [DHH] - -* Fixed that fragment caching should return a cache hit as html_safe (or it would all just get escaped) [DHH] - -* Added that ActionController::Base now does helper :all instead of relying on the default ApplicationController in Rails to do it [DHH] - -* Added ActionDispatch::Request#authorization to access the http authentication header regardless of its proxy hiding [DHH] - -* Added :alert, :notice, and :flash as options to ActionController::Base#redirect_to that'll automatically set the proper flash before the redirection [DHH]. Examples: - - flash[:notice] = 'Post was created' - redirect_to(@post) - - ...becomes: - - redirect_to(@post, :notice => 'Post was created') - -* Added ActionController::Base#notice/= and ActionController::Base#alert/= as a convenience accessors in both the controller and the view for flash[:notice]/= and flash[:alert]/= [DHH] - - -* Introduce grouped_collection_select helper. #1249 [Dan Codeape, Erik Ostrom] - -* Make sure javascript_include_tag/stylesheet_link_tag does not append ".js" or ".css" onto external urls. #1664 [Matthew Rudy Jacobs] - -* Ruby 1.9: fix Content-Length for multibyte send_data streaming. #2661 [Sava Chankov] - -* Ruby 1.9: ERB template encoding using a magic comment at the top of the file. [Jeremy Kemper] - <%# encoding: utf-8 %> - -* Change integration test helpers to accept Rack environment instead of just HTTP Headers [Pratik Naik] - - Before : get '/path', {}, 'Accept' => 'text/javascript' - After : get '/path', {}, 'HTTP_ACCEPT' => 'text/javascript' - -* Instead of checking Rails.env.test? in Failsafe middleware, check env["rails.raise_exceptions"] [Bryan Helmkamp] - -* Fixed that TestResponse.cookies was returning cookies unescaped #1867 [Doug McInnes] - - -*2.3.2 [Final] (March 15, 2009)* - -* Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #") [DHH] - -* Don't check authenticity tokens for any AJAX requests [Ross Kaffenberger/Bryan Helmkamp] - -* Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable #2095 [Gregg Pollack] - -* Fixed that passing a custom form builder would be forwarded to nested fields_for calls #2023 [Eloy Duran/Nate Wiger] - -* Form option helpers now support disabled option tags and the use of lambdas for selecting/disabling option tags from collections #837 [Tekin] - -* Added partial scoping to TranslationHelper#translate, so if you call translate(".foo") from the people/index.html.erb template, you'll actually be calling I18n.translate("people.index.foo") [DHH] - -* Fix a syntax error in current_page?() that was prevent matches against URL's with multiple query parameters #1385, #1868 [chris finne/Andrew White] - -* Added localized rescue template when I18n.locale is set (ex: public/404.da.html) #1835 [José Valim] - -* Make the form_for and fields_for helpers support the new Active Record nested update options. #1202 [Eloy Duran] - - <% form_for @person do |person_form| %> - ... - <% person_form.fields_for :projects do |project_fields| %> - <% if project_fields.object.active? %> - Name: <%= project_fields.text_field :name %> - <% end %> - <% end %> - <% end %> - - -* Added grouped_options_for_select helper method for wrapping option tags in optgroups. #977 [Jon Crawford] - -* Implement HTTP Digest authentication. #1230 [Gregg Kellogg, Pratik Naik] Example : - - class DummyDigestController < ActionController::Base - USERS = { "lifo" => 'world' } - - before_filter :authenticate - - def index - render :text => "Hello Secret" - end - - private - - def authenticate - authenticate_or_request_with_http_digest("Super Secret") do |username| - # Return the user's password - USERS[username] - end - end - end - -* Improved i18n support for the number_to_human_size helper. Changes the storage_units translation data; update your translations accordingly. #1634 [Yaroslav Markin] - storage_units: - # %u is the storage unit, %n is the number (default: 2 MB) - format: "%n %u" - units: - byte: - one: "Byte" - other: "Bytes" - kb: "KB" - mb: "MB" - gb: "GB" - tb: "TB" - -* Added :silence option to BenchmarkHelper#benchmark and turned log_level into a hash parameter and deprecated the old use [DHH] - -* Fixed the AssetTagHelper cache to use the computed asset host as part of the cache key instead of just assuming the its a string #1299 [DHH] - -* Make ActionController#render(string) work as a shortcut for render :file/:template/:action => string. [#1435] [Pratik Naik] Examples: - - # Instead of render(:action => 'other_action') - render('other_action') # argument has no '/' - render(:other_action) - - # Instead of render(:template => 'controller/action') - render('controller/action') # argument must not begin with a '/', but contain a '/' - - # Instead of render(:file => '/Users/lifo/home.html.erb') - render('/Users/lifo/home.html.erb') # argument must begin with a '/' - -* Add :prompt option to date/time select helpers. #561 [Sam Oliver] - -* Fixed that send_file shouldn't set an etag #1578 [Hongli Lai] - -* Allow users to opt out of the spoofing checks in Request#remote_ip. Useful for sites whose traffic regularly triggers false positives. [Darren Boyd] - -* Deprecated formatted_polymorphic_url. [Jeremy Kemper] - -* Added the option to declare an asset_host as an object that responds to call (see http://github.com/dhh/asset-hosting-with-minimum-ssl for an example) [David Heinemeier Hansson] - -* Added support for multiple routes.rb files (useful for plugin engines). This also means that draw will no longer clear the route set, you have to do that by hand (shouldn't make a difference to you unless you're doing some funky stuff) [David Heinemeier Hansson] - -* Dropped formatted_* routes in favor of just passing in :format as an option. This cuts resource routes generation in half #1359 [aaronbatalion] - -* Remove support for old double-encoded cookies from the cookie store. These values haven't been generated since before 2.1.0, and any users who have visited the app in the intervening 6 months will have had their cookie upgraded. [Michael Koziarski] - -* Allow helpers directory to be overridden via ActionController::Base.helpers_dir #1424 [Sam Pohlenz] - -* Remove deprecated ActionController::Base#assign_default_content_type_and_charset - -* Changed the default of ActionView#render to assume partials instead of files when not given an options hash [David Heinemeier Hansson]. Examples: - - # Instead of <%= render :partial => "account" %> - <%= render "account" %> - - # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %> - <%= render "account", :account => @buyer %> - - # @account is an Account instance, so it uses the RecordIdentifier to replace - # <%= render :partial => "accounts/account", :locals => { :account => @account } %> - <%= render(@account) %> - - # @posts is an array of Post instances, so it uses the RecordIdentifier to replace - # <%= render :partial => "posts/post", :collection => @posts %> - <%= render(@posts) %> - -* Remove deprecated render_component. Please use the plugin from http://github.com/rails/render_component/tree/master [Pratik Naik] - -* Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that they're available if you want to use textilize and markdown and let autoload require them [David Heinemeier Hansson] - - -*2.2.2 (November 21st, 2008)* - -* I18n: translate number_to_human_size. Add storage_units: [Bytes, KB, MB, GB, TB] to your translations. #1448 [Yaroslav Markin] - -* Restore backwards compatible functionality for setting relative_url_root. Include deprecation - -* Switched the CSRF module to use the request content type to decide if the request is forgeable. #1145 [Jeff Cohen] - -* Added :only and :except to map.resources to let people cut down on the number of redundant routes in an application. Typically only useful for huge routesets. #1215 [Tom Stuart] - - map.resources :products, :only => :show do |product| - product.resources :images, :except => :destroy - end - -* Added render :js for people who want to render inline JavaScript replies without using RJS [David Heinemeier Hansson] - -* Fixed that polymorphic_url should compact given array #1317 [hiroshi] - -* Fixed the sanitize helper to avoid double escaping already properly escaped entities #683 [antonmos/Ryan McGeary] - -* Fixed that FormTagHelper generated illegal html if name contained square brackets #1238 [Vladimir Dobriakov] - -* Fix regression bug that made date_select and datetime_select raise a Null Pointer Exception when a nil date/datetime was passed and only month and year were displayed #1289 [Bernardo Padua/Tor Erik] - -* Simplified the logging format for parameters (don't include controller, action, and format as duplicates) [David Heinemeier Hansson] - -* Remove the logging of the Session ID when the session store is CookieStore [David Heinemeier Hansson] - -* Fixed regex in redirect_to to fully support URI schemes #1247 [Seth Fitzsimmons] - -* Fixed bug with asset timestamping when using relative_url_root #1265 [Joe Goldwasser] - - -*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 [David Heinemeier Hansson]. Example: - - class ArticlesController < ApplicationController - def show_with_respond_to_block - @article = Article.find(params[:id]) - - - # If the request sends headers that differs from the options provided to stale?, then - # the request is indeed stale and the respond_to block is triggered (and the options - # to the stale? call is set on the response). - # - # If the request headers match, then the request is fresh and the respond_to block is - # not triggered. Instead the default render will occur, which will check the last-modified - # and etag headers and conclude that it only needs to send a "304 Not Modified" instead - # of rendering the template. - if stale?(:last_modified => @article.published_at.utc, :etag => @article) - respond_to do |wants| - # normal response processing - end - end - end - - def show_with_implied_render - @article = Article.find(params[:id]) - - # Sets the response headers and checks them against the request, if the request is stale - # (i.e. no match of either etag or last-modified), then the default render of the template happens. - # If the request is fresh, then the default render will return a "304 Not Modified" - # instead of rendering the template. - fresh_when(:last_modified => @article.published_at.utc, :etag => @article) - end - end - - -* Added inline builder yield to atom_feed_helper tags where appropriate [Sam Ruby]. Example: - - entry.summary :type => 'xhtml' do |xhtml| - xhtml.p pluralize(order.line_items.count, "line item") - xhtml.p "Shipped to #{order.address}" - xhtml.p "Paid by #{order.pay_type}" - end - -* Make PrototypeHelper#submit_to_remote a wrapper around PrototypeHelper#button_to_remote. [Tarmo Tänav] - -* Set HttpOnly for the cookie session store's cookie. #1046 - -* Added FormTagHelper#image_submit_tag confirm option #784 [Alastair Brunton] - -* Fixed FormTagHelper#submit_tag with :disable_with option wouldn't submit the button's value when was clicked #633 [Jose Fernandez] - -* Stopped logging template compiles as it only clogs up the log [David Heinemeier Hansson] - -* Changed the X-Runtime header to report in milliseconds [David Heinemeier Hansson] - -* Changed BenchmarkHelper#benchmark to report in milliseconds [David Heinemeier Hansson] - -* Changed logging format to be millisecond based and skip misleading stats [David Heinemeier Hansson]. Went from: - - Completed in 0.10000 (4 reqs/sec) | Rendering: 0.04000 (40%) | DB: 0.00400 (4%) | 200 OK [http://example.com] - - ...to: - - Completed in 100ms (View: 40, DB: 4) | 200 OK [http://example.com] - -* Add support for shallow nesting of routes. #838 [S. Brent Faulkner] - - Example : - - map.resources :users, :shallow => true do |user| - user.resources :posts - end - - - GET /users/1/posts (maps to PostsController#index action as usual) - named route "user_posts" is added as usual. - - - GET /posts/2 (maps to PostsController#show action as if it were not nested) - Additionally, named route "post" is added too. - -* Added button_to_remote helper. #3641 [Donald Piret, Tarmo Tänav] - -* Deprecate render_component. Please use render_component plugin from http://github.com/rails/render_component/tree/master [Pratik Naik] - -* Routes may be restricted to lists of HTTP methods instead of a single method or :any. #407 [Brennan Dunn, Gaius Centus Novus] - map.resource :posts, :collection => { :search => [:get, :post] } - map.session 'session', :requirements => { :method => [:get, :post, :delete] } - -* Deprecated implicit local assignments when rendering partials [Josh Peek] - -* Introduce current_cycle helper method to return the current value without bumping the cycle. #417 [Ken Collins] - -* Allow polymorphic_url helper to take url options. #880 [Tarmo Tänav] - -* Switched integration test runner to use Rack processor instead of CGI [Josh Peek] - -* Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck] - -* Added back ActionController::Base.allow_concurrency flag [Josh Peek] - -* AbstractRequest.relative_url_root is no longer automatically configured by a HTTP header. It can now be set in your configuration environment with config.action_controller.relative_url_root [Josh Peek] - -* Update Prototype to 1.6.0.2 #599 [Patrick Joyce] - -* Conditional GET utility methods. [Jeremy Kemper] - response.last_modified = @post.updated_at - response.etag = [:admin, @post, current_user] - - if request.fresh?(response) - head :not_modified - else - # render ... - end - -* All 2xx requests are considered successful [Josh Peek] - -* Fixed that AssetTagHelper#compute_public_path shouldn't cache the asset_host along with the source or per-request proc's won't run [David Heinemeier Hansson] - -* Removed config.action_view.cache_template_loading, use config.cache_classes instead [Josh Peek] - -* Get buffer for fragment cache from template's @output_buffer [Josh Peek] - -* Set config.action_view.warn_cache_misses = true to receive a warning if you perform an action that results in an expensive disk operation that could be cached [Josh Peek] - -* Refactor template preloading. New abstractions include Renderable mixins and a refactored Template class [Josh Peek] - -* Changed ActionView::TemplateHandler#render API method signature to render(template, local_assigns = {}) [Josh Peek] - -* Changed PrototypeHelper#submit_to_remote to PrototypeHelper#button_to_remote to stay consistent with link_to_remote (submit_to_remote still works as an alias) #8994 [clemens] - -* Add :recursive option to javascript_include_tag and stylesheet_link_tag to be used along with :all. #480 [Damian Janowski] - -* Allow users to disable the use of the Accept header [Michael Koziarski] - - The accept header is poorly implemented by browsers and causes strange - errors when used on public sites where crawlers make requests too. You - can use formatted urls (e.g. /people/1.xml) to support API clients in a - much simpler way. - - To disable the header you need to set: - - config.action_controller.use_accept_header = false - -* Do not stat template files in production mode before rendering. You will no longer be able to modify templates in production mode without restarting the server [Josh Peek] - -* Deprecated TemplateHandler line offset [Josh Peek] - -* Allow caches_action to accept cache store options. #416. [José Valim]. Example: - - caches_action :index, :redirected, :if => Proc.new { |c| !c.request.format.json? }, :expires_in => 1.hour - -* Remove define_javascript_functions, javascript_include_tag and friends are far superior. [Michael Koziarski] - -* Deprecate :use_full_path render option. The supplying the option no longer has an effect [Josh Peek] - -* Add :as option to render a collection of partials with a custom local variable name. #509 [Simon Jefford, Pratik Naik] - - render :partial => 'other_people', :collection => @people, :as => :person - - This will let you access objects of @people as 'person' local variable inside 'other_people' partial template. - -* time_zone_select: support for regexp matching of priority zones. Resolves #195 [Ernie Miller] - -* Made ActionView::Base#render_file private [Josh Peek] - -* Refactor and simplify the implementation of assert_redirected_to. Arguments are now normalised relative to the controller being tested, not the root of the application. [Michael Koziarski] - - This could cause some erroneous test failures if you were redirecting between controllers - in different namespaces and wrote your assertions relative to the root of the application. - -* Remove follow_redirect from controller functional tests. - - If you want to follow redirects you can use integration tests. The functional test - version was only useful if you were using redirect_to :id=>... - -* Fix polymorphic_url with singleton resources. #461 [Tammer Saleh] - -* Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek] - -* Added block-call style to link_to [Sam Stephenson/David Heinemeier Hansson]. Example: - - <% link_to(@profile) do %> - <%= @profile.name %> -- Check it out!! - <% end %> - -* Performance: integration test benchmarking and profiling. [Jeremy Kemper] - -* Make caching more aware of mime types. Ensure request format is not considered while expiring cache. [Jonathan del Strother] - -* Drop ActionController::Base.allow_concurrency flag [Josh Peek] - -* More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper] - -* Added page.reload functionality. Resolves #277. [Sean Huber] - -* Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens] - -* Allow caches_action to accept a layout option [José Valim] - -* Added Rack processor [Ezra Zygmuntowicz, Josh Peek] - - -*2.1.0 (May 31st, 2008)* - -* InstanceTag#default_time_from_options overflows to DateTime [Geoff Buesing] - -* Fixed that forgery protection can be used without session tracking (Peter Jones) [#139] - -* Added session(:on) to turn session management back on in a controller subclass if the superclass turned it off (Peter Jones) [#136] - -* Change the request forgery protection to go by Content-Type instead of request.format so that you can't bypass it by POSTing to "#{request.uri}.xml" [Rick Olson] -* InstanceTag#default_time_from_options with hash args uses Time.current as default; respects hash settings when time falls in system local spring DST gap [Geoff Buesing] - -* select_date defaults to Time.zone.today when config.time_zone is set [Geoff Buesing] - -* Fixed that TextHelper#text_field would corrypt when raw HTML was used as the value (mchenryc, Kevin Glowacz) [#80] - -* Added ActionController::TestCase#rescue_action_in_public! to control whether the action under test should use the regular rescue_action path instead of simply raising the exception inline (great for error testing) [David Heinemeier Hansson] - -* Reduce number of instance variables being copied from controller to view. [Pratik Naik] - -* select_datetime and select_time default to Time.zone.now when config.time_zone is set [Geoff Buesing] - -* datetime_select defaults to Time.zone.now when config.time_zone is set [Geoff Buesing] - -* Remove ActionController::Base#view_controller_internals flag. [Pratik Naik] - -* Add conditional options to caches_page method. [Paul Horsfall] - -* Move missing template logic to ActionView. [Pratik Naik] - -* Introduce ActionView::InlineTemplate class. [Pratik Naik] - -* Automatically parse posted JSON content for Mime::JSON requests. [Rick Olson] - - POST /posts - {"post": {"title": "Breaking News"}} - - def create - @post = Post.create params[:post] - # ... - end - -* add json_escape ERB util to escape html entities in json strings that are output in HTML pages. [Rick Olson] - -* Provide a helper proxy to access helper methods from outside views. Closes #10839 [Josh Peek] - e.g. ApplicationController.helpers.simple_format(text) - -* Improve documentation. [Xavier Noria, leethal, jerome] - -* Ensure RJS redirect_to doesn't html-escapes string argument. Closes #8546 [Josh Peek, eventualbuddha, Pratik Naik] - -* Support render :partial => collection of heterogeneous elements. #11491 [Zach Dennis] - -* Avoid remote_ip spoofing. [Brian Candler] - -* Added support for regexp flags like ignoring case in the :requirements part of routes declarations #11421 [NeilW] - -* Fixed that ActionController::Base#read_multipart would fail if boundary was exactly 10240 bytes #10886 [ariejan] - -* Fixed HTML::Tokenizer (used in sanitize helper) didn't handle unclosed CDATA tags #10071 [esad, packagethief] - -* Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert] - -* Fixed that FormHelper#radio_button would produce invalid ids #11298 [harlancrystal] - -* Added :confirm option to submit_tag #11415 [Emilio Tagua] - -* Fixed NumberHelper#number_with_precision to properly round in a way that works equally on Mac, Windows, Linux (closes #11409, #8275, #10090, #8027) [zhangyuanyi] - -* Allow the #simple_format text_helper to take an html_options hash for each paragraph. #2448 [François Beausoleil, Chris O'Sullivan] - -* Fix regression from filter refactoring where re-adding a skipped filter resulted in it being called twice. [Rick Olson] - -* Refactor filters to use Active Support callbacks. #11235 [Josh Peek] - -* Fixed that polymorphic routes would modify the input array #11363 [thomas.lee] - -* Added :format option to NumberHelper#number_to_currency to enable better localization support #11149 [lylo] - -* Fixed that TextHelper#excerpt would include one character too many #11268 [Irfy] - -* Fix more obscure nested parameter hash parsing bug. #10797 [thomas.lee] - -* Added ActionView::Helpers::register_javascript/stylesheet_expansion to make it easier for plugin developers to inject multiple assets. #10350 [lotswholetime] - -* Fix nested parameter hash parsing bug. #10797 [thomas.lee] - -* Allow using named routes in ActionController::TestCase before any request has been made. Closes #11273 [Eloy Duran] - -* Fixed that sweepers defined by cache_sweeper will be added regardless of the perform_caching setting. Instead, control whether the sweeper should be run with the perform_caching setting. This makes testing easier when you want to turn perform_caching on/off [David Heinemeier Hansson] - -* Make MimeResponds::Responder#any work without explicit types. Closes #11140 [jaw6] - -* Better error message for type conflicts when parsing params. Closes #7962 [spicycode, matt] - -* Remove unused ActionController::Base.template_class. Closes #10787 [Pratik Naik] - -* Moved template handlers related code from ActionView::Base to ActionView::Template. [Pratik Naik] - -* Tests for div_for and content_tag_for helpers. Closes #11223 [Chris O'Sullivan] - -* Allow file uploads in Integration Tests. Closes #11091 [RubyRedRick] - -* Refactor partial rendering into a PartialTemplate class. [Pratik Naik] - -* Added that requests with JavaScript as the priority mime type in the accept header and no format extension in the parameters will be treated as though their format was :js when it comes to determining which template to render. This makes it possible for JS requests to automatically render action.js.rjs files without an explicit respond_to block [David Heinemeier Hansson] - -* Tests for distance_of_time_in_words with TimeWithZone instances. Closes #10914 [Ernesto Jimenez] - -* Remove support for multivalued (e.g., '&'-delimited) cookies. [Jamis Buck] - -* Fix problem with render :partial collections, records, and locals. #11057 [lotswholetime] - -* Added support for naming concrete classes in sweeper declarations [David Heinemeier Hansson] - -* Remove ERB trim variables from trace template in case ActionView::Base.erb_trim_mode is changed in the application. #10098 [Tim Pope, Chris Kampmeier] - -* Fix typo in form_helper documentation. #10650 [Xavier Shay, Chris Kampmeier] - -* Fix bug with setting Request#format= after the getter has cached the value. #10889 [cch1] - -* Correct inconsistencies in RequestForgeryProtection docs. #11032 [Mislav Marohnić] - -* Introduce a Template class to ActionView. #11024 [Pratik Naik] - -* Introduce the :index option for form_for and fields_for to simplify multi-model forms (see http://railscasts.com/episodes/75). #9883 [rmm5t] - -* Introduce map.resources :cards, :as => 'tarjetas' to use a custom resource name in the URL: cards_path == '/tarjetas'. #10578 [blj] - -* TestSession supports indifferent access. #7372 [tamc, Arsen7, mhackett, julik, jean.helou] - -* Make assert_routing aware of the HTTP method used. #8039 [mpalmer] - e.g. assert_routing({ :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" }) - -* Make map.root accept a single symbol as an argument to declare an alias. #10818 [bscofield] - - e.g. map.dashboard '/dashboard', :controller=>'dashboard' - map.root :dashboard - -* Handle corner case with image_tag when passed 'messed up' image names. #9018 [Duncan Beevers, mpalmer] - -* Add label_tag helper for generating elements. #10802 [DefV] - -* Introduce TemplateFinder to handle view paths and lookups. #10800 [Pratik Naik] - -* Performance: optimize route recognition. Large speedup for apps with many resource routes. #10835 [oleganza] - -* Make render :partial recognise form builders and use the _form partial. #10814 [Damian Janowski] - -* Allow users to declare other namespaces when using the atom feed helpers. #10304 [david.calavera] - -* Introduce send_file :x_sendfile => true to send an X-Sendfile response header. [Jeremy Kemper] - -* Fixed ActionView::Helpers::ActiveRecordHelper::form for when protect_from_forgery is used #10739 [Jeremy Evans] - -* Provide nicer access to HTTP Headers. Instead of request.env["HTTP_REFERRER"] you can now use request.headers["Referrer"]. [Michael Koziarski] - -* UrlWriter respects relative_url_root. #10748 [Cheah Chu Yeow] - -* The asset_host block takes the controller request as an optional second argument. Example: use a single asset host for SSL requests. #10549 [Cheah Chu Yeow, Peter B, Tom Taylor] - -* Support render :text => nil. #6684 [tjennings, PotatoSalad, Cheah Chu Yeow] - -* assert_response failures include the exception message. #10688 [Seth Rasmussen] - -* All fragment cache keys are now by default prefixed with the "views/" namespace [David Heinemeier Hansson] - -* Moved the caching stores from ActionController::Caching::Fragments::* to ActiveSupport::Cache::*. If you're explicitly referring to a store, like ActionController::Caching::Fragments::MemoryStore, you need to update that reference with ActiveSupport::Cache::MemoryStore [David Heinemeier Hansson] - -* Deprecated ActionController::Base.fragment_cache_store for ActionController::Base.cache_store [David Heinemeier Hansson] - -* Made fragment caching in views work for rjs and builder as well #6642 [Dee Zsombor] - -* Fixed rendering of partials with layout when done from site layout #9209 [antramm] - -* Fix atom_feed_helper to comply with the atom spec. Closes #10672 [Xavier Shay] - - * The tags created do not contain a date (http://feedvalidator.org/docs/error/InvalidTAG.html) - * IDs are not guaranteed unique - * A default self link was not provided, contrary to the documentation - * NOTE: This changes tags for existing atom entries, but at least they validate now. - -* Correct indentation in tests. Closes #10671 [Luca Guidi] - -* Fix that auto_link looks for ='s in url paths (Amazon urls have them). Closes #10640 [Brad Greenlee] - -* Ensure that test case setup is run even if overridden. #10382 [Josh Peek] - -* Fix HTML Sanitizer to allow trailing spaces in CSS style attributes. Closes #10566 [wesley.moxam] - -* Add :default option to time_zone_select. #10590 [Matt Aimonetti] - - -*2.0.2* (December 16th, 2007) - -* Added delete_via_redirect and put_via_redirect to integration testing #10497 [philodespotos] - -* Allow headers['Accept'] to be set by hand when calling xml_http_request #10461 [BMorearty] - -* Added OPTIONS to list of default accepted HTTP methods #10449 [holoway] - -* Added option to pass proc to ActionController::Base.asset_host for maximum configurability #10521 [Cheah Chu Yeow]. Example: - - ActionController::Base.asset_host = Proc.new { |source| - if source.starts_with?('/images') - "http://images.example.com" - else - "http://assets.example.com" - end - } - -* Fixed that ActionView#file_exists? would be incorrect if @first_render is set #10569 [dbussink] - -* Added that Array#to_param calls to_param on all it's elements #10473 [brandon] - -* Ensure asset cache directories are automatically created. #10337 [Josh Peek, Cheah Chu Yeow] - -* render :xml and :json preserve custom content types. #10388 [jmettraux, Cheah Chu Yeow] - -* Refactor Action View template handlers. #10437, #10455 [Josh Peek] - -* Fix DoubleRenderError message and leave out mention of returning false from filters. Closes #10380 [Frederick Cheung] - -* Clean up some cruft around ActionController::Base#head. Closes #10417 [ssoroka] - - -*2.0.1* (December 7th, 2007) - -* Fixed send_file/binary_content for testing #8044 [tolsen] - -* When a NonInferrableControllerError is raised, make the proposed fix clearer in the error message. Closes #10199 [Jack Danger Canty] - -* Update Prototype to 1.6.0.1. [sam] - -* Update script.aculo.us to 1.8.0.1. [madrobby] - -* Add 'disabled' attribute to Hello world - - Any method that calls url_for on its parameters will automatically benefit from this. - -* Removed deprecated parameters_for_method_reference concept (legacy from before named routes) [David Heinemeier Hansson] - -* Add ActionController::Routing::Helpers, a module to contain common URL helpers such as polymorphic_url. [Nicholas Seckar] - -* Included the HttpAuthentication plugin as part of core (ActionController::HttpAuthentication::Basic) [David Heinemeier Hansson] - -* Modernize documentation for form helpers. [Jeremy McAnally] - -* Add brief introduction to REST to the resources documentation. [fearoffish] - -* Fix various documentation typos throughout ActionPack. [Henrik N] - -* Enhance documentation and add examples for url_for. [Jeremy McAnally] - -* Fix documentation typo in routes. [Norbert Crombach, pam] - -* Sweep flash when filter chain is halted. [Caio Chassot ] - -* Fixed that content_tag with a block will just return the result instead of concate it if not used in a ERb view #7857, #7432 [michael.niessner] - -* Replace the current block/continuation filter chain handling by an implementation based on a simple loop. #8226 [Stefan Kaes] - -* Update UrlWriter to accept :anchor parameter. Closes #6771. [Chris McGrath] - -* Added RecordTagHelper for using RecordIdentifier conventions on divs and other container elements [David Heinemeier Hansson]. Example: - - <% div_for(post) do %>
- <%= post.body %> What a wonderful world! - <% end %>
- -* Added page[record] accessor to JavaScriptGenerator that relies on RecordIdentifier to find the right dom id [David Heinemeier Hansson]. Example: - - format.js do - # Calls: new Effect.fade('post_45'); - render(:update) { |page| page[post].visual_effect(:fade) } - end - -* Added RecordIdentifier to enforce view conventions on records for dom ids, classes, and partial paths [David Heinemeier Hansson] - -* Added map.namespace to deal with the common situation of admin sections and the like [David Heinemeier Hansson] - - Before: - - map.resources :products, :path_prefix => "admin", :controller => "admin/products", :collection => { :inventory => :get }, :member => { :duplicate => :post } - map.resources :tags, :name_prefix => 'admin_product_', :path_prefix => "admin/products/:product_id", :controller => "admin/product_tags" - map.resources :images, :name_prefix => 'admin_product_', :path_prefix => "admin/products/:product_id", :controller => "admin/product_images" - map.resources :variants, :name_prefix => 'admin_product_', :path_prefix => "admin/products/:product_id", :controller => "admin/product_variants" - - After: - - map.namespace(:admin) do |admin| - admin.resources :products, - :collection => { :inventory => :get }, - :member => { :duplicate => :post }, - :has_many => [ :tags, :images, :variants ] - end - -* Added :name_prefix as standard for nested resources [David Heinemeier Hansson]. WARNING: May be backwards incompatible with your app - - Before: - - map.resources :emails do |emails| - emails.resources :comments, :name_prefix => "email_" - emails.resources :attachments, :name_prefix => "email_" - end - - After: - - map.resources :emails do |emails| - emails.resources :comments - emails.resources :attachments - end - - This does mean that if you intended to have comments_url go to /emails/5/comments, then you'll have to set :name_prefix to nil explicitly. - -* Added :has_many and :has_one for declaring plural and singular resources beneath the current [David Heinemeier Hansson] - - Before: - - map.resources :notes do |notes| - notes.resources :comments - notes.resources :attachments - notes.resource :author - end - - After: - - map.resources :notes, :has_many => [ :comments, :attachments ], :has_one => :author - -* Added that render :xml will try to call to_xml if it can [David Heinemeier Hansson]. Makes these work: - - render :xml => post - render :xml => comments - -* Added :location option to render so that the common pattern of rendering a response after creating a new resource is now a 1-liner [David Heinemeier Hansson] - - render :xml => post.to_xml, :status => :created, :location => post_url(post) - -* Ensure that render_text only adds string content to the body of the response [David Heinemeier Hansson] - -* Return the string representation from an Xml Builder when rendering a partial. Closes #5044 [Tim Pope] - -* Fixed that parameters from XML should also be presented in a hash with indifferent access [David Heinemeier Hansson] - -* Tweak template format rules so that the ACCEPT header is only used if it's text/javascript. This is so ajax actions without a :format param get recognized as Mime::JS. [Rick Olson] - -* The default respond_to blocks don't set a specific extension anymore, so that both 'show.rjs' and 'show.js.rjs' will work. [Rick Olson] - -* Allow layouts with extension of .html.erb. Closes #8032 [Josh Knowles] - -* Change default respond_to templates for xml and rjs formats. [Rick Olson] - - * Default xml template goes from #{action_name}.rxml => #{action_name}.xml.builder. - * Default rjs template goes from #{action_name}.rjs => #{action_name}.js.rjs. - - You can still specify your old templates: - - respond_to do |format| - format.xml do - render :action => "#{action_name}.rxml" - end - end - -* Fix WSOD due to modification of a formatted template extension so that requests to templates like 'foo.html.erb' fail on the second hit. [Rick Olson] - -* Fix WSOD when template compilation fails [Rick Olson] - -* Change ActionView template defaults. Look for templates using the request format first, such as "show.html.erb" or "show.xml.builder", before looking for the old defaults like "show.erb" or "show.builder" [Rick Olson] - -* Highlight helper highlights one or many terms in a single pass. [Jeremy Kemper] - -* Dropped the use of ; as a separator of non-crud actions on resources and went back to the vanilla slash. It was a neat idea, but lots of the non-crud actions turned out not to be RPC (as the ; was primarily intended to discourage), but legitimate sub-resources, like /parties/recent, which didn't deserve the uglification of /parties;recent. Further more, the semicolon caused issues with caching and HTTP authentication in Safari. Just Not Worth It [David Heinemeier Hansson] - -* Added that FormTagHelper#submit_tag will return to its original state if the submit fails and you're using :disable_with [David Heinemeier Hansson] - -* Cleaned up, corrected, and mildly expanded ActionPack documentation. Closes #7190 [Jeremy McAnally] - -* Small collection of ActionController documentation cleanups. Closes #7319 [Jeremy McAnally] - -* Make sure the route expiry hash is constructed by comparing the to_param-ized values of each hash. [Jamis Buck] - -* Allow configuration of the default action cache path for #caches_action calls. [Rick Olson] - - class ListsController < ApplicationController - caches_action :index, :cache_path => Proc.new { |controller| - controller.params[:user_id] ? - controller.send(:user_lists_url, c.params[:user_id]) : - controller.send(:lists_url) } - end - -* Performance: patch cgi/session/pstore to require digest/md5 once rather than per #initialize. #7583 [Stefan Kaes] - -* Cookie session store: ensure that new sessions doesn't reuse data from a deleted session in the same request. [Jeremy Kemper] - -* Deprecation: verification with :redirect_to => :named_route shouldn't be deprecated. #7525 [Justin French] - -* Cookie session store: raise ArgumentError when :session_key is blank. [Jeremy Kemper] - -* Deprecation: remove deprecated request, redirect, and dependency methods. Remove deprecated instance variables. Remove deprecated url_for(:symbol, *args) and redirect_to(:symbol, *args) in favor of named routes. Remove uses_component_template_root for toplevel components directory. Privatize deprecated render_partial and render_partial_collection view methods. Remove deprecated link_to_image, link_image_to, update_element_function, start_form_tag, and end_form_tag helper methods. Remove deprecated human_size helper alias. [Jeremy Kemper] - -* Consistent public/protected/private visibility for chained methods. #7813 [Dan Manges] - -* Prefer MIME constants to strings. #7707 [Dan Kubb] - -* Allow array and hash query parameters. Array route parameters are converted/to/a/path as before. #6765, #7047, #7462 [bgipsy, Jeremy McAnally, Dan Kubb, brendan] - -# Add a #dbman attr_reader for CGI::Session and make CGI::Session::CookieStore#generate_digest public so it's easy to generate digests -using the cookie store's secret. [Rick Olson] - -* Added Request#url that returns the complete URL used for the request [David Heinemeier Hansson] - -* Extract dynamic scaffolding into a plugin. #7700 [Josh Peek] - -* Added user/password options for url_for to add http authentication in a URL [David Heinemeier Hansson] - -* Fixed that FormTagHelper#text_area_tag should disregard :size option if it's not a string [Brendon Davidson] - -* Set the original button value in an attribute of the button when using the :disable_with key with submit_tag, so that the original can be restored later. [Jamis Buck] - -* session_enabled? works with session :off. #6680 [Jonathan del Strother] - -* Added :port and :host handling to UrlRewriter (which unified url_for usage, regardless of whether it's called in view or controller) #7616 [alancfrancis] - -* Allow send_file/send_data to use a registered mime type as the :type parameter #7620 [jonathan] - -* Allow routing requirements on map.resource(s) #7633 [quixoten]. Example: - - map.resources :network_interfaces, :requirements => { :id => /^\d+\.\d+\.\d+\.\d+$/ } - -* Cookie session store: empty and unchanged sessions don't write a cookie. [Jeremy Kemper] - -* Added helper(:all) as a way to include all helpers from app/helpers/**/*.rb in ApplicationController [David Heinemeier Hansson] - -* Integration tests: introduce methods for other HTTP methods. #6353 [caboose] - -* Routing: better support for escaped values in route segments. #7544 [Chris -Roos] - -* Introduce a cookie-based session store as the Rails default. Sessions typically contain at most a user_id and flash message; both fit within the 4K cookie size limit. A secure message digest is included with the cookie to ensure data integrity (a user cannot alter his user_id without knowing the secret key included in the digest). If you have more than 4K of session data or don't want your data to be visible to the user, pick another session store. Cookie-based sessions are dramatically faster than the alternatives. [Jeremy Kemper] - - Example config/environment.rb: - # Use an application-wide secret key and the default SHA1 message digest. - config.action_controller.session = { :secret => "can't touch this" } - - # Store a secret key per user and employ a stronger message digest. - config.action_controller.session = { - :digest => 'SHA512', - :secret => Proc.new { User.current.secret_key } - } - -* Added .erb and .builder as preferred aliases to the now deprecated .rhtml and .rxml extensions [Chad Fowler]. This is done to separate the renderer from the mime type. .erb templates are often used to render emails, atom, csv, whatever. So labeling them .rhtml doesn't make too much sense. The same goes for .rxml, which can be used to build everything from HTML to Atom to whatever. .rhtml and .rxml will continue to work until Rails 3.0, though. So this is a slow phasing out. All generators and examples will start using the new aliases, though. - -* Added caching option to AssetTagHelper#stylesheet_link_tag and AssetTagHelper#javascript_include_tag [David Heinemeier Hansson]. Examples: - - stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is false => - - - - - stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is true => - - - ...when caching is on, all.css is the concatenation of style1.css, styleB.css, and styleX2.css. - Same deal for JavaScripts. - -* Work around the two connection per host browser limit: use asset%d.myapp.com to distribute asset requests among asset[0123].myapp.com. Use a DNS wildcard or CNAMEs to map these hosts to your asset server. See http://www.die.net/musings/page_load_time/ for background. [Jeremy Kemper] - -* Added default mime type for CSS (Mime::CSS) [David Heinemeier Hansson] - -* Added that rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified and the response body will be set to an empty string. [David Heinemeier Hansson] - -* Added X-Runtime to all responses with the request run time [David Heinemeier Hansson] - -* Add Mime::Type convenience methods to check the current mime type. [Rick Olson] - - request.format.html? # => true if Mime::HTML - request.format.jpg? # => true if Mime::JPG - - # ActionController sample usage: - # the session will be disabled for non html/ajax requests - session :off, :if => Proc.new { |req| !(req.format.html? || req.format.js?) } - -* Performance: patch cgi/session to require digest/md5 once rather than per #create_new_id. [Stefan Kaes] - -* Add a :url_based_filename => true option to ActionController::Streaming::send_file, which allows URL-based filenames. [Thomas Fuchs] - -* Fix that FormTagHelper#submit_tag using :disable_with should trigger the onsubmit handler of its form if available [David Heinemeier Hansson] - -* Fix #render_file so that TemplateError is called with the correct params and you don't get the WSOD. [Rick Olson] - -* Fix issue with deprecation messing up #template_root= usage. Add #prepend_view_path and #append_view_path to allow modification of a copy of the -superclass' view_paths. [Rick Olson] - -* Allow Controllers to have multiple view_paths instead of a single template_root. Closes #2754 [John Long] - -* Add much-needed html-scanner tests. Fixed CDATA parsing bug. [Rick Olson] - -* improve error message for Routing for named routes. Closes #7346 [Rob Sanheim] - -* Added enhanced docs to routing assertions. Closes #7359 [Rob Sanheim] - -* fix form_for example in ActionController::Resources documentation. Closes #7362 [gnarg] - -* Make sure that the string returned by TextHelper#truncate is actually a string, not a char proxy -- that should only be used internally while working on a multibyte-safe way of truncating [David Heinemeier Hansson] - -* Added FormBuilder#submit as a delegate for FormTagHelper#submit_tag [David Heinemeier Hansson] - -* Allow Routes to generate all urls for a set of options by specifying :generate_all => true. Allows caching to properly set or expire all paths for a resource. References #1739. [Nicholas Seckar] - -* Change the query parser to map empty GET params to "" rather than nil. Closes #5694. [Nicholas Seckar] - -* date_select and datetime_select take a :default option. #7052 [Nik Wakelin] - date_select "post", "written_on", :default => 3.days.from_now - date_select "credit_card", "bill_due", :default => { :day => 20 } - -* select :multiple => true suffixes the attribute name with [] unless already suffixed. #6977 [nik.kakelin, ben, julik] - -* Improve routes documentation. #7095 [zackchandler] - -* mail_to :encode => 'hex' also encodes the mailto: part of the href attribute as well as the linked email when no name is given. #2061 [Jarkko Laine, pfc.pille@gmx.net] - -* Resource member routes require :id, eliminating the ambiguous overlap with collection routes. #7229 [dkubb] - -* Remove deprecated assertions. [Jeremy Kemper] - -* Change session restoration to allow namespaced models to be autoloaded. Closes #6348. [Nicholas Seckar] - -* Fix doubly appearing parameters due to string and symbol mixups. Closes #2551. [Anthony Eden] - -* Fix overly greedy rescues when loading helpers. Fixes #6268. [Nicholas Seckar] - -* Fixed NumberHelper#number_with_delimiter to use "." always for splitting the original number, not the delimiter parameter #7389 [ceefour] - -* Autolinking recognizes trailing and embedded . , : ; #7354 [Jarkko Laine] - -* Make TextHelper::auto_link recognize URLs with colons in path correctly, fixes #7268. [imajes] - -* Update to script.aculo.us 1.7.0. [Thomas Fuchs] - -* Modernize cookie testing code, and increase coverage (Heckle++) #7101 [Kevin Clark] - -* Improve Test Coverage for ActionController::Routing::Route#matches_controller_and_action? (Heckle++) #7115 [Kevin Clark] - -* Heckling ActionController::Resources::Resource revealed that set_prefixes didn't break when :name_prefix was munged. #7081 [Kevin Clark] - -* Fix #distance_of_time_in_words to report accurately against the Duration class. #7114 [eventualbuddha] - -* Refactor #form_tag to allow easy extending. [Rick Olson] - -* Update to Prototype 1.5.0. [Sam Stephenson] - -* RecordInvalid, RecordNotSaved => 422 Unprocessable Entity, StaleObjectError => 409 Conflict. #7097 [dkubb] - -* Allow fields_for to be nested inside form_for, so that the name and id get properly constructed [Jamis Buck] - -* Allow inGroupsOf and eachSlice to be called through rjs. #7046 [Cody Fauser] - -* Allow exempt_from_layout :rhtml. #6742, #7026 [Dan Manges, Squeegy] - -* Recognize the .txt extension as Mime::TEXT [Rick Olson] - -* Fix parsing of array[] CGI parameters so extra empty values aren't included. #6252 [Nicholas Seckar, aiwilliams, brentrowland] - -* link_to_unless_current works with full URLs as well as paths. #6891 [Jarkko Laine, Manfred Stienstra, idrifter] - -* Lookup the mime type for #auto_discovery_link_tag in the Mime::Type class. Closes #6941 [Josh Peek] - -* Fix bug where nested resources ignore a parent singleton parent's path prefix. Closes #6940 [Dan Kubb] - -* Fix no method error with error_messages_on. Closes #6935 [nik.wakelin Koz] - -* Slight doc tweak to the ActionView::Helpers::PrototypeHelper#replace docs. Closes #6922 [Steven Bristol] - -* Slight doc tweak to #prepend_filter. Closes #6493 [Jeremy Voorhis] - -* Add more extensive documentation to the AssetTagHelper. Closes #6452 [Bob Silva] - -* Clean up multiple calls to #stringify_keys in TagHelper, add better documentation and testing for TagHelper. Closes #6394 [Bob Silva] - -* [DOCS] fix reference to ActionController::Macros::AutoComplete for #text_field_with_auto_complete. Closes #2578 [Jan Prill] - -* Make sure html_document is reset between integration test requests. [ctm] - -* Set session to an empty hash if :new_session => false and no session cookie or param is present. CGI::Session was raising an unrescued ArgumentError. [Josh Susser] - -* Routing uses URI escaping for path components and CGI escaping for query parameters. [darix, Jeremy Kemper] - -* Fix assert_redirected_to bug where redirecting from a nested to to a top-level controller incorrectly added the current controller's nesting. Closes #6128. [Rick Olson] - -* Singleton resources: POST /singleton => create, GET /singleton/new => new. [Jeremy Kemper] - -* Use 400 Bad Request status for unrescued ActiveRecord::RecordInvalid exceptions. [Jeremy Kemper] - -* Silence log_error deprecation warnings from inspecting deprecated instance variables. [Nate Wiger] - -* Only cache GET requests with a 200 OK response. #6514, #6743 [RSL, anamba] - -* Add a 'referer' attribute to TestRequest. [Jamis Buck] - -* Ensure render :json => ... skips the layout. Closes #6808 [Josh Peek] - -* Fix HTML::Node to output double quotes instead of single quotes. Closes #6845 [mitreandy] - -* Correctly report which filter halted the chain. #6699 [Martin Emde] - -* Fix a bug in Routing where a parameter taken from the path of the current request could not be used as a query parameter for the next. Closes #6752. [Nicholas Seckar] - -* Unrescued ActiveRecord::RecordNotFound responds with 404 instead of 500. [Jeremy Kemper] - -* Improved auto_link to match more valid urls correctly [Tobias Lütke] - -* Add singleton resources. [Rick Olson] - - map.resource :account - - GET /account - GET /account;edit - UPDATE /account - DELETE /account - -* respond_to recognizes JSON. render :json => @person.to_json automatically sets the content type and takes a :callback option to specify a client-side function to call using the rendered JSON as an argument. #4185 [Scott Raymond, eventualbuddha] - # application/json response with body 'Element.show({:name: "David"})' - respond_to do |format| - format.json { render :json => { :name => "David" }.to_json, :callback => 'Element.show' } - end - -* Makes :discard_year work without breaking multi-attribute parsing in AR. #1260, #3800 [sean@ardismg.com, jmartin@desertflood.com, stephen@touset.org, Bob Silva] - -* Adds html id attribute to date helper elements. #1050, #1382 [mortonda@dgrmm.net, David North, Bob Silva] - -* Add :index and @auto_index capability to model driven date/time selects. #847, #2655 [moriq, Doug Fales, Bob Silva] - -* Add :order to datetime_select, select_datetime, and select_date. #1427 [Timothee Peignier, Patrick Lenz, Bob Silva] - -* Added time_select to work with time values in models. Update scaffolding. #2489, #2833 [Justin Palmer, Andre Caum, Bob Silva] - -* Added :include_seconds to select_datetime, datetime_select and time_select. #2998 [csn, Bob Silva] - -* All date/datetime selects can now accept an array of month names with :use_month_names. Allows for localization. #363 [tomasj, Bob Silva] - -* Adds :time_separator to select_time and :date_separator to select_datetime. Preserves BC. #3811 [Bob Silva] - -* Added map.root as an alias for map.connect '' [David Heinemeier Hansson] - -* Added Request#format to return the format used for the request as a mime type. If no format is specified, the first Request#accepts type is used. This means you can stop using respond_to for anything else than responses [David Heinemeier Hansson]. Examples: - - GET /posts/5.xml | request.format => Mime::XML - GET /posts/5.xhtml | request.format => Mime::HTML - GET /posts/5 | request.format => request.accepts.first (usually Mime::HTML for browsers) - -* Added the option for extension aliases to mime type registration [David Heinemeier Hansson]. Example (already in the default routes): - - Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml ) - - ...will respond on both .html and .xhtml. - -* @response.redirect_url works with 201 Created responses: just return headers['Location'] rather than checking the response status. [Jeremy Kemper] - -* Added CSV to Mime::SET so that respond_to csv will work [Cody Fauser] - -* Fixed that HEAD should return the proper Content-Length header (that is, actually use @body.size, not just 0) [David Heinemeier Hansson] - -* Added GET-masquarading for HEAD, so request.method will return :get even for HEADs. This will help anyone relying on case request.method to automatically work with HEAD and map.resources will also allow HEADs to all GET actions. Rails automatically throws away the response content in a reply to HEAD, so you don't even need to worry about that. If you, for whatever reason, still need to distinguish between GET and HEAD in some edge case, you can use Request#head? and even Request.headers["REQUEST_METHOD"] for get the "real" answer. Closes #6694 [David Heinemeier Hansson] - -* Update Routing to complain when :controller is not specified by a route. Closes #6669. [Nicholas Seckar] - -* Ensure render_to_string cleans up after itself when an exception is raised. #6658 [Rob Sanheim] - -* Extract template_changed_since? from compile_template? so plugins may override its behavior for non-file-based templates. #6651 [Jeff Barczewski] - -* Update to Prototype and script.aculo.us [5579]. [Thomas Fuchs] - -* simple_format helper doesn't choke on nil. #6644 [jerry426] - -* Update to Prototype 1.5.0_rc2 [5550] which makes it work in Opera again [Thomas Fuchs] - -* Reuse named route helper module between Routing reloads. Use remove_method to delete named route methods after each load. Since the module is never collected, this fixes a significant memory leak. [Nicholas Seckar] - -* ActionView::Base.erb_variable accessor names the buffer variable used to render templates. Defaults to _erbout; use _buf for erubis. [Rick Olson] - -* assert_select_rjs :remove. [Dylan Egan] - -* Always clear model associations from session. #4795 [sd@notso.net, andylien@gmail.com] - -* Update to Prototype 1.5.0_rc2. [Sam Stephenson] - -* Remove JavaScriptLiteral in favor of ActiveSupport::JSON::Variable. [Sam Stephenson] - -* Sync ActionController::StatusCodes::STATUS_CODES with http://www.iana.org/assignments/http-status-codes. #6586 [dkubb] - -* Multipart form values may have a content type without being treated as uploaded files if they do not provide a filename. #6401 [Andreas Schwarz, Jeremy Kemper] - -* assert_response supports symbolic status codes. #6569 [Kevin Clark] - assert_response :ok - assert_response :not_found - assert_response :forbidden - -* Cache parsed query parameters. #6559 [Stefan Kaes] - -* Deprecate JavaScriptHelper#update_element_function, which is superseeded by RJS [Thomas Fuchs] - -* pluralize helper interprets nil as zero. #6474 [Tim Pope] - -* Fix invalid test fixture exposed by stricter Ruby 1.8.5 multipart parsing. #6524 [Bob Silva] - -* Set ActionView::Base.default_form_builder once rather than passing the :builder option to every form or overriding the form helper methods. [Jeremy Kemper] - -* Deprecate expire_matched_fragments. Use expire_fragment instead. #6535 [Bob Silva] - -* Update to latest Prototype, which doesn't serialize disabled form elements, adds clone() to arrays, empty/non-string Element.update() and adds a fixes excessive error reporting in WebKit beta versions [Thomas Fuchs] - -* Deprecate start_form_tag and end_form_tag. Use form_tag / '' from now on. [Rick Olson] - -* Added block-usage to PrototypeHelper#form_remote_tag, document block-usage of FormTagHelper#form_tag [Rick Olson] - -* Add a 0 margin/padding div around the hidden _method input tag that form_tag outputs. [Rick Olson] - -* Added block-usage to TagHelper#content_tag [David Heinemeier Hansson]. Example: - - <% content_tag :div, :class => "strong" %> - Hello world! - <% end %> - - Will output: -
Hello world!
- -* Deprecated UrlHelper#link_to_image and UrlHelper#link_to :post => true #6409 [Bob Silva] - -* Upgraded NumberHelper with number_to_phone support international formats to comply with ITU E.123 by supporting area codes with less than 3 digits, added precision argument to number_to_human_size (defaults to 1) #6421 [Bob Silva] - -* Fixed that setting RAILS_ASSET_ID to "" should not add a trailing slash after assets #6454 [Bob Silva/chrismear] - -* Force *_url named routes to show the host in ActionView [Rick Olson] - - <%= url_for ... %> # no host - <%= foo_path %> # no host - <%= foo_url %> # host! - -* Add support for converting blocks into function arguments to JavaScriptGenerator#call and JavaScriptProxy#call. [Sam Stephenson] - -* Add JavaScriptGenerator#literal for wrapping a string in an object whose #to_json is the string itself. [Sam Stephenson] - -* Add <%= escape_once html %> to escape html while leaving any currently escaped entities alone. Fix button_to double-escaping issue. [Rick Olson] - -* Fix double-escaped entities, such as &amp;, &#123;, etc. [Rick Olson] - -* Fix deprecation warnings when rendering the template error template. [Nicholas Seckar] - -* Fix routing to correctly determine when generation fails. Closes #6300. [psross]. - -* Fix broken assert_generates when extra keys are being checked. [Jamis Buck] - -* Replace KCODE checks with String#chars for truncate. Closes #6385 [Manfred Stienstra] - -* Make page caching respect the format of the resource that is being requested even if the current route is the default route so that, e.g. posts.rss is not transformed by url_for to '/' and subsequently cached as '/index.html' when it should be cached as '/posts.rss'. [Marcel Molina Jr.] - -* Use String#chars in TextHelper::excerpt. Closes #6386 [Manfred Stienstra] - -* Install named routes into ActionView::Base instead of proxying them to the view via helper_method. Closes #5932. [Nicholas Seckar] - -* Update to latest Prototype and script.aculo.us trunk versions [Thomas Fuchs] - -* Fix relative URL root matching problems. [Mark Imbriaco] - -* Fix filter skipping in controller subclasses. #5949, #6297, #6299 [Martin Emde] - -* render_text may optionally append to the response body. render_javascript appends by default. This allows you to chain multiple render :update calls by setting @performed_render = false between them (awaiting a better public API). [Jeremy Kemper] - -* Rename test assertion to prevent shadowing. Closes #6306. [psross] - -* Fixed that NumberHelper#number_to_delimiter should respect precision of higher than two digits #6231 [Philip Hallstrom] - -* Fixed that FormHelper#radio_button didn't respect an :id being passed in #6266 [evansj] - -* Added an html_options hash parameter to javascript_tag() and update_page_tag() helpers #6311 [tzaharia]. Example: - - update_page_tag :defer => 'true' { |page| ... } - - Gives: - - - - Which is needed for dealing with the IE6 DOM when it's not yet fully loaded. - -* Fixed that rescue template path shouldn't be hardcoded, then it's easier to hook in your own #6295 [Mike Naberezny] - -* Fixed escaping of backslashes in JavaScriptHelper#escape_javascript #6302 [sven@c3d2.de] - -* Fixed that some 500 rescues would cause 500's themselves because the response had not yet been generated #6329 [cmselmer] - -* respond_to :html doesn't assume .rhtml. #6281 [Hampton Catlin] - -* Fixed some deprecation warnings in ActionPack [Rick Olson] - -* assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. #6240 [japgolly] - -* Deprecation: @cookies, @headers, @request, @response will be removed after 1.2. Use the corresponding method instead. [Jeremy Kemper] - -* Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples: - - head :status => 404 # expands to "404 Not Found" - head :status => :not_found # expands to "404 Not Found" - head :status => :created # expands to "201 Created" - -* Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples: - - head :status => 404 # return an empty response with a 404 status - head :location => person_path(@person), :status => 201 - -* Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. [Rick Olson] - -* strip_links is case-insensitive. #6285 [tagoh, Bob Silva] - -* Clear the cache of possible controllers whenever Routes are reloaded. [Nicholas Seckar] - -* Filters overhaul including meantime filter support using around filters + blocks. #5949 [Martin Emde, Roman Le Negrate, Stefan Kaes, Jeremy Kemper] - -* Update RJS render tests. [sam] - -* Update CGI process to allow sessions to contain namespaced models. Closes #4638. [dfelstead@site5.com] - -* Fix routing to respect user provided requirements and defaults when assigning default routing options (such as :action => 'index'). Closes #5950. [Nicholas Seckar] - -* Rescue Errno::ECONNRESET to handle an unexpectedly closed socket connection. Improves SCGI reliability. #3368, #6226 [sdsykes, fhanshaw@vesaria.com] - -* Added that respond_to blocks will automatically set the content type to be the same as is requested [David Heinemeier Hansson]. Examples: - - respond_to do |format| - format.html { render :text => "I'm being sent as text/html" } - format.rss { render :text => "I'm being sent as application/rss+xml" } - format.atom { render :text => "I'm being sent as application/xml", :content_type => Mime::XML } - end - -* Added utf-8 as the default charset for all renders. You can change this default using ActionController::Base.default_charset=(encoding) [David Heinemeier Hansson] - -* Added proper getters and setters for content type and charset [David Heinemeier Hansson]. Example of what we used to do: - - response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" - - ...now: - - response.content_type = Mime::ATOM - response.charset = "utf-8" - -* Updated prototype.js to 1.5.0_rc1 with latest fixes. [Rick Olson] - - - XPATH support - - Make Form.getElements() return elements in the correct order - - fix broken Form.serialize return - -* Declare file extensions exempt from layouts. #6219 [brandon] - Example: ActionController::Base.exempt_from_layout 'rpdf' - -* Add chained replace/update support for assert_select_rjs [Rick Olson] - - Given RJS like... - - page['test1'].replace "
foo
" - page['test2'].replace_html "
foo
" - - Test it with... - - assert_select_rjs :chained_replace - assert_select_rjs :chained_replace, "test1" - - assert_select_rjs :chained_replace_html - assert_select_rjs :chained_replace_html, "test2" - -* Load helpers in alphabetical order for consistency. Resolve cyclic javascript_helper dependency. #6132, #6178 [choonkeat@gmail.com] - -* Skip params with empty names, such as the &=Save query string from . #2569 [Manfred Stienstra, raphinou@yahoo.com] - -* Fix assert_tag so that :content => "foo" does not match substrings, but only exact strings. Use :content => /foo/ to match substrings. #2799 [Eric Hodel] - -* Add descriptive messages to the exceptions thrown by cgi_methods. #6091, #6103 [Nicholas Seckar, Bob Silva] - -* Update JavaScriptGenerator#show/hide/toggle/remove to new Prototype syntax for multiple ids, #6068 [petermichaux@gmail.com] - -* Update UrlWriter to support :only_path. [Nicholas Seckar, Dave Thomas] - -* Fixed JavaScriptHelper#link_to_function and JavaScriptHelper#button_to_function to have the script argument be optional [David Heinemeier Hansson]. So what used to require a nil, like this: - - link_to("Hider", nil, :class => "hider_link") { |p| p[:something].hide } - - ...can be written like this: - - link_to("Hider", :class => "hider_link") { |p| p[:something].hide } - -* Update to script.aculo.us 1.6.3 [Thomas Fuchs] - -* Update to Prototype 1.5.0_rc1 [sam] - -* Added access to nested attributes in RJS #4548 [richcollins@gmail.com]. Examples: - - page['foo']['style'] # => $('foo').style; - page['foo']['style']['color'] # => $('blank_slate').style.color; - page['foo']['style']['color'] = 'red' # => $('blank_slate').style.color = 'red'; - page['foo']['style'].color = 'red' # => $('blank_slate').style.color = 'red'; - -* Fixed that AssetTagHelper#image_tag and others using compute_public_path should not modify the incoming source argument (closes #5102) [eule@space.ch] - -* Deprecated the auto-appending of .png to AssetTagHelper#image_tag calls that doesn't have an extension [David Heinemeier Hansson] - -* Fixed FormOptionsHelper#select to respect :selected value #5813 - -* Fixed TextHelper#simple_format to deal with multiple single returns within a single paragraph #5835 [moriq@moriq.com] - -* Fixed TextHelper#pluralize to handle 1 as a string #5909 [rails@bencurtis.com] - -* Improved resolution of DateHelper#distance_of_time_in_words for better precision #5994 [Bob Silva] - -* Changed that uncaught exceptions raised any where in the application will cause RAILS_ROOT/public/500.html to be read and shown instead of just the static "Application error (Rails)" [David Heinemeier Hansson] - -* Integration tests: thoroughly test ActionController::Integration::Session. #6022 [Kevin Clark] - (tests skipped unless you `gem install mocha`) - -* Added deprecation language for pagination which will become a plugin by Rails 2.0 [David Heinemeier Hansson] - -* Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 [David Heinemeier Hansson] - -* Deprecated all of ActionController::Dependencies. All dependency loading is now handled from Active Support [David Heinemeier Hansson] - -* Added assert_select* for CSS selector-based testing (deprecates assert_tag) #5936 [assaf.arkin@gmail.com] - -* radio_button_tag generates unique id attributes. #3353 [Bob Silva, somekool@gmail.com] - -* strip_tags passes through blank args such as nil or "". #2229, #6702 [duncan@whomwah.com, dharana] - -* Cleanup assert_tag :children counting. #2181 [jamie@bravenet.com] - -* button_to accepts :method so you can PUT and DELETE with it. #6005 [Dan Webb] - -* Update sanitize text helper to strip plaintext tags, and . [Rick Olson] - -* Update routing documentation. Closes #6017 [Nathan Witmer] - -* Add routing tests to assert that RoutingError is raised when conditions aren't met. Closes #6016 [Nathan Witmer] - -* Deprecation: update docs. #5998 [Jakob Skjerning, Kevin Clark] - -* Make auto_link parse a greater subset of valid url formats. [Jamis Buck] - -* Integration tests: headers beginning with X aren't excluded from the HTTP_ prefix, so X-Requested-With becomes HTTP_X_REQUESTED_WITH as expected. [Mike Clark] - -* Tighten rescue clauses. #5985 [james@grayproductions.net] - -* Fix send_data documentation typo. #5982 [brad@madriska.com] - -* Switch to using FormEncodedPairParser for parsing request parameters. [Nicholas Seckar, David Heinemeier Hansson] - -* respond_to .html now always renders #{action_name}.rhtml so that registered custom template handlers do not override it in priority. Custom mime types require a block and throw proper error now. [Tobias Lütke] - -* Deprecation: test deprecated instance vars in partials. [Jeremy Kemper] - -* Add UrlWriter to allow writing urls from Mailers and scripts. [Nicholas Seckar] - -* Clean up and run the Active Record integration tests by default. #5854 [Kevin Clark, Jeremy Kemper] - -* Correct example in cookies docs. #5832 [jessemerriman@warpmail.net] - -* Updated to script.aculo.us 1.6.2 [Thomas Fuchs] - -* Relax Routing's anchor pattern warning; it was preventing use of [^/] inside restrictions. [Nicholas Seckar] - -* Add controller_paths variable to Routing. [Nicholas Seckar] - -* Fix assert_redirected_to issue with named routes for module controllers. [Rick Olson] - -* Tweak RoutingError message to show option diffs, not just missing named route significant keys. [Rick Olson] - -* Invoke method_missing directly on hidden actions. Closes #3030. [Nicholas Seckar] - -* Require Tempfile explicitly for TestUploadedFile due to changes in class auto loading. [Rick Olson] - -* Add RoutingError exception when RouteSet fails to generate a path from a Named Route. [Rick Olson] - -* Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar] - -* Deprecation: check whether instance variables have been monkeyed with before assigning them to deprecation proxies. Raises a RuntimeError if so. [Jeremy Kemper] - -* Add support for the param_name parameter to the auto_complete_field helper. #5026 [david.a.williams@gmail.com] - -* Deprecation! @params, @session, @flash will be removed after 1.2. Use the corresponding instance methods instead. You'll get printed warnings during tests and logged warnings in dev mode when you access either instance variable directly. [Jeremy Kemper] - -* Make Routing noisy when an anchor regexp is assigned to a segment. #5674 [François Beausoleil] - -* Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" #5611 [pjhyett@gmail.com] - -* Short documentation to mention use of Mime::Type.register. #5710 [choonkeat@gmail.com] - -* Make controller_path available as an instance method. #5724 [jmckible@gmail.com] - -* Update query parser to support adjacent hashes. [Nicholas Seckar] - -* Make action caching aware of different formats for the same action so that, e.g. foo.xml is cached separately from foo.html. Implicitly set content type when reading in cached content with mime revealing extensions so the entire onous isn't on the webserver. [Marcel Molina Jr.] - -* Restrict Request Method hacking with ?_method to POST requests. [Rick Olson] - -* Fix bug when passing multiple options to SimplyRestful, like :new => { :preview => :get, :draft => :get }. [Rick Olson, Josh Susser, Lars Pind] - -* Dup the options passed to map.resources so that multiple resources get the same options. [Rick Olson] - -* Fixed the new_#{resource}_url route and added named route tests for Simply Restful. [Rick Olson] - -* Added map.resources from the Simply Restful plugin [David Heinemeier Hansson]. Examples (the API has changed to use plurals!): - - map.resources :messages - map.resources :messages, :comments - map.resources :messages, :new => { :preview => :post } - -* Fixed that integration simulation of XHRs should set Accept header as well [Edward Frederick] - -* TestRequest#reset_session should restore a TestSession, not a hash [Michael Koziarski] - -* Don't search a load-path of '.' for controller files [Jamis Buck] - -* Update integration.rb to require test_process explicitly instead of via Dependencies. [Nicholas Seckar] - -* Fixed that you can still access the flash after the flash has been reset in reset_session. Closes #5584 [lmarlow] - -* Allow form_for and fields_for to work with indexed form inputs. [Jeremy Kemper, Matt Lyon] - - <% form_for 'post[]', @post do |f| -%> - <% end -%> - -* Remove leak in development mode by replacing define_method with module_eval. [Nicholas Seckar] - -* Provide support for decimal columns to form helpers. Closes #5672. [Dave Thomas] - -* Update documentation for erb trim syntax. #5651 [matt@mattmargolis.net] - -* Pass :id => nil or :class => nil to error_messages_for to supress that html attribute. #3586 [olivier_ansaldi@yahoo.com] - -* Reset @html_document between requests so assert_tag works. #4810 [Jarkko Laine, easleydp@gmail.com] - -* Update render :partial documentation. #5646 [matt@mattmargolis.net] - -* Integration tests behave well with render_component. #4632 [edward.frederick@revolution.com, dev.rubyonrails@maxdunn.com] - -* Added exception handling of missing layouts #5373 [chris@ozmm.org] - -* Fixed that real files and symlinks should be treated the same when compiling templates #5438 [zachary@panandscan.com] - -* Fixed that the flash should be reset when reset_session is called #5584 [Shugo Maeda] - -* Added special case for "1 Byte" in NumberHelper#number_to_human_size #5593 [murpyh@rubychan.de] - -* Fixed proper form-encoded parameter parsing for requests with "Content-Type: application/x-www-form-urlencoded; charset=utf-8" (note the presence of a charset directive) [David Heinemeier Hansson] - -* Add route_name_path method to generate only the path for a named routes. For example, map.person will add person_path. [Nicholas Seckar] - -* Avoid naming collision among compiled view methods. [Jeremy Kemper] - -* Fix CGI extensions when they expect string but get nil in Windows. Closes #5276 [Mislav Marohnić] - -* Determine the correct template_root for deeply nested components. #2841 [s.brink@web.de] - -* Fix that routes with *path segments in the recall can generate URLs. [Rick Olson] - -* Fix strip_links so that it doesn't hang on multiline tags [Jamis Buck] - -* Remove problematic control chars in rescue template. #5316 [Stefan Kaes] - -* Make sure passed routing options are not mutated by routing code. #5314 [Blair Zajac] - -* Make sure changing the controller from foo/bar to bing/bang does not change relative to foo. [Jamis Buck] - -* Escape the path before routing recognition. #3671 - -* Make sure :id and friends are unescaped properly. #5275 [me@julik.nl] - -* Fix documentation for with_routing to reflect new reality. #5281 [rramdas@gmail.com] - -* Rewind readable CGI params so others may reread them (such as CGI::Session when passing the session id in a multipart form). #210 [mklame@atxeu.com, matthew@walker.wattle.id.au] - -* Added Mime::TEXT (text/plain) and Mime::ICS (text/calendar) as new default types [David Heinemeier Hansson] - -* Added Mime::Type.register(string, symbol, synonyms = []) for adding new custom mime types [David Heinemeier Hansson]. Example: Mime::Type.register("image/gif", :gif) - -* Added support for Mime objects in render :content_type option [David Heinemeier Hansson]. Example: render :text => some_atom, :content_type => Mime::ATOM - -* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 [Manfred Stienstra ] - -* Routing rewrite. Simpler, faster, easier to understand. The published API for config/routes.rb is unchanged, but nearly everything else is different, so expect breakage in plugins and libs that try to fiddle with routes. [Nicholas Seckar, Jamis Buck] - - map.connect '/foo/:id', :controller => '...', :action => '...' - map.connect '/foo/:id.:format', :controller => '...', :action => '...' - map.connect '/foo/:id', ..., :conditions => { :method => :get } - -* Cope with missing content type and length headers. Parse parameters from multipart and urlencoded request bodies only. [Jeremy Kemper] - -* Accept multipart PUT parameters. #5235 [guy.naor@famundo.com] - -* Added interrogation of params[:format] to determine Accept type. If :format is specified and matches a declared extension, like "rss" or "xml", that mime type will be put in front of the accept handler. This means you can link to the same action from different extensions and use that fact to determine output [David Heinemeier Hansson]. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.find :all - - respond_to do |format| - format.html - format.xml { render :xml => @posts.to_xml } - format.rss { render :action => "feed.rxml" } - end - end - end - - # returns HTML when requested by a browser, since the browser - # has the HTML mimetype at the top of its priority list - Accept: text/html - GET /weblog - - # returns the XML - Accept: application/xml - GET /weblog - - # returns the HTML - Accept: application/xml - GET /weblog.html - - # returns the XML - Accept: text/html - GET /weblog.xml - - All this relies on the fact that you have a route that includes .:format. - -* Expanded :method option in FormTagHelper#form_tag, FormHelper#form_for, PrototypeHelper#remote_form_for, PrototypeHelper#remote_form_tag, and PrototypeHelper#link_to_remote to allow for verbs other than GET and POST by automatically creating a hidden form field named _method, which will simulate the other verbs over post [David Heinemeier Hansson] - -* Added :method option to UrlHelper#link_to, which allows for using other verbs than GET for the link. This replaces the :post option, which is now deprecated. Example: link_to "Destroy", person_url(:id => person), :method => :delete [David Heinemeier Hansson] - -* follow_redirect doesn't complain about being redirected to the same controller. #5153 [dymo@mk.ukrtelecom.ua] - -* Add layout attribute to response object with the name of the layout that was rendered, or nil if none rendered. [Kevin Clark] - -* Fix NoMethodError when parsing params like &&. [Adam Greenfield] - -* Fix flip flopped logic in docs for url_for's :only_path option. Closes #4998. [esad@esse.at] - -* form.text_area handles the :size option just like the original text_area (:size => '60x10' becomes cols="60" rows="10"). [Jeremy Kemper] - -* Excise ingrown code from FormOptionsHelper#options_for_select. #5008 [anonymous] - -* Small fix in routing to allow dynamic routes (broken after [4242]) [Rick Olson] - - map.connect '*path', :controller => 'files', :action => 'show' - -* Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.] - -* Replace Ruby's deprecated append_features in favor of included. [Marcel Molina Jr.] - -* Use #flush between switching from #write to #syswrite. Closes #4907. [Blair Zajac ] - -* Documentation fix: integration test scripts don't require integration_test. Closes #4914. [Frederick Ros ] - -* ActionController::Base Summary documentation rewrite. Closes #4900. [Kevin Clark] - -* Fix text_helper.rb documentation rendering. Closes #4725. [Frederick Ros] - -* Fixes bad rendering of JavaScriptMacrosHelper rdoc (closes #4910) [Frederick Ros] - -* Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes #4186. [andrew@redlinesoftware.com, Marcel Molina Jr.] - - error_messages_for :account, :user, :subscription, :object_name => :account - -* Enhance documentation for setting headers in integration tests. Skip auto HTTP prepending when its already there. Closes #4079. [Rick Olson] - -* Documentation for AbstractRequest. Closes #4895. [Kevin Clark] - -* Refactor various InstanceTag instance method to class methods. Closes #4800. [Stefan Kaes] - -* Remove all remaining references to @params in the documentation. [Marcel Molina Jr.] - -* Add documentation for redirect_to :back's RedirectBackError exception. [Marcel Molina Jr.] - -* Update layout and content_for documentation to use yield rather than magic @content_for instance variables. [Marcel Molina Jr.] - -* Fix assert_redirected_to tests according to real-world usage. Also, don't fail if you add an extra :controller option: [Rick Olson] - - redirect_to :action => 'new' - assert_redirected_to :controller => 'monkeys', :action => 'new' - -* Cache CgiRequest#request_parameters so that multiple calls don't re-parse multipart data. [Rick Olson] - -* Diff compared routing options. Allow #assert_recognizes to take a second arg as a hash to specify optional request method [Rick Olson] - - assert_recognizes({:controller => 'users', :action => 'index'}, 'users') - assert_recognizes({:controller => 'users', :action => 'create'}, {:path => 'users', :method => :post}) - -* Diff compared options with #assert_redirected_to [Rick Olson] - -* Add support in routes for semicolon delimited "subpaths", like /books/:id;:action [Jamis Buck] - -* Change link_to_function and button_to_function to (optionally) take an update_page block instead of a JavaScript string. Closes #4804. [zraii@comcast.net, Sam Stephenson] - -* Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for [David Heinemeier Hansson] - -* Modify routing so that you can say :require => { :method => :post } for a route, and the route will never be selected unless the request method is POST. Only works for route recognition, not for route generation. [Jamis Buck] - -* Added :add_headers option to verify which merges a hash of name/value pairs into the response's headers hash if the prerequisites cannot be satisfied. [Sam Stephenson] - ex. verify :only => :speak, :method => :post, - :render => { :status => 405, :text => "Must be post" }, - :add_headers => { "Allow" => "POST" } - -* Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled #1897 [jeremye@bsa.ca.gov] - - -*1.13.3* (March 12th, 2007) - -* Apply [5709] to stable. - -* session_enabled? works with session :off. #6680 [Jonathan del Strother] - -* Performance: patch cgi/session to require digest/md5 once rather than per #create_new_id. [Stefan Kaes] - - -*1.13.2* (February 5th, 2007) - -* Add much-needed html-scanner tests. Fixed CDATA parsing bug. [Rick Olson] - -* improve error message for Routing for named routes. [Rob Sanheim] - -* Added enhanced docs to routing assertions. [Rob Sanheim] - -* fix form_for example in ActionController::Resources documentation. [gnarg] - -* Add singleton resources from trunk [Rick Olson] - -* select :multiple => true suffixes the attribute name with [] unless already suffixed. #6977 [nik.kakelin, ben, julik] - -* Improve routes documentation. #7095 [zackchandler] - -* Resource member routes require :id, eliminating the ambiguous overlap with collection routes. #7229 [dkubb] - -* Fixed NumberHelper#number_with_delimiter to use "." always for splitting the original number, not the delimiter parameter #7389 [ceefour] - -* Autolinking recognizes trailing and embedded . , : ; #7354 [Jarkko Laine] - -* Make TextHelper::auto_link recognize URLs with colons in path correctly, fixes #7268. [imajes] - -* Improved auto_link to match more valid urls correctly [Tobias Lütke] - - -*1.13.1* (January 18th, 2007) - -* Fixed content-type bug in Prototype [sam] - - -*1.13.0* (January 16th, 2007) - -* Modernize cookie testing code, and increase coverage (Heckle++) #7101 [Kevin Clark] - -* Heckling ActionController::Resources::Resource revealed that set_prefixes didn't break when :name_prefix was munged. #7081 [Kevin Clark] - -* Update to Prototype 1.5.0. [Sam Stephenson] - -* Allow exempt_from_layout :rhtml. #6742, #7026 [Dan Manges, Squeegy] - -* Fix parsing of array[] CGI parameters so extra empty values aren't included. #6252 [Nicholas Seckar, aiwilliams, brentrowland] - -* link_to_unless_current works with full URLs as well as paths. #6891 [Jarkko Laine, Manfred Stienstra, idrifter] - -* Fix HTML::Node to output double quotes instead of single quotes. Closes #6845 [mitreandy] - -* Fix no method error with error_messages_on. Closes #6935 [nik.wakelin Koz] - -* Slight doc tweak to the ActionView::Helpers::PrototypeHelper#replace docs. Closes #6922 [Steven Bristol] - -* Slight doc tweak to #prepend_filter. Closes #6493 [Jeremy Voorhis] - -* Add more extensive documentation to the AssetTagHelper. Closes #6452 [Bob Silva] - -* Clean up multiple calls to #stringify_keys in TagHelper, add better documentation and testing for TagHelper. Closes #6394 [Bob Silva] - -* [DOCS] fix reference to ActionController::Macros::AutoComplete for #text_field_with_auto_complete. Closes #2578 [Jan Prill] - -* Make sure html_document is reset between integration test requests. [ctm] - -* Set session to an empty hash if :new_session => false and no session cookie or param is present. CGI::Session was raising an unrescued ArgumentError. [Josh Susser] - -* Fix assert_redirected_to bug where redirecting from a nested to to a top-level controller incorrectly added the current controller's nesting. Closes #6128. [Rick Olson] - -* Ensure render :json => ... skips the layout. #6808 [Josh Peek] - -* Silence log_error deprecation warnings from inspecting deprecated instance variables. [Nate Wiger] - -* Only cache GET requests with a 200 OK response. #6514, #6743 [RSL, anamba] - -* Correctly report which filter halted the chain. #6699 [Martin Emde] - -* respond_to recognizes JSON. render :json => @person.to_json automatically sets the content type and takes a :callback option to specify a client-side function to call using the rendered JSON as an argument. #4185 [Scott Raymond, eventualbuddha] - # application/json response with body 'Element.show({:name: "David"})' - respond_to do |format| - format.json { render :json => { :name => "David" }.to_json, :callback => 'Element.show' } - end - -* Makes :discard_year work without breaking multi-attribute parsing in AR. #1260, #3800 [sean@ardismg.com, jmartin@desertflood.com, stephen@touset.org, Bob Silva] - -* Adds html id attribute to date helper elements. #1050, #1382 [mortonda@dgrmm.net, David North, Bob Silva] - -* Add :index and @auto_index capability to model driven date/time selects. #847, #2655 [moriq, Doug Fales, Bob Silva] - -* Add :order to datetime_select, select_datetime, and select_date. #1427 [Timothee Peignier, Patrick Lenz, Bob Silva] - -* Added time_select to work with time values in models. Update scaffolding. #2489, #2833 [Justin Palmer, Andre Caum, Bob Silva] - -* Added :include_seconds to select_datetime, datetime_select and time_select. #2998 [csn, Bob Silva] - -* All date/datetime selects can now accept an array of month names with :use_month_names. Allows for localization. #363 [tomasj, Bob Silva] - -* Adds :time_separator to select_time and :date_separator to select_datetime. Preserves BC. #3811 [Bob Silva] - -* @response.redirect_url works with 201 Created responses: just return headers['Location'] rather than checking the response status. [Jeremy Kemper] - -* Fixed that HEAD should return the proper Content-Length header (that is, actually use @body.size, not just 0) [David Heinemeier Hansson] - -* Added GET-masquarading for HEAD, so request.method will return :get even for HEADs. This will help anyone relying on case request.method to automatically work with HEAD and map.resources will also allow HEADs to all GET actions. Rails automatically throws away the response content in a reply to HEAD, so you don't even need to worry about that. If you, for whatever reason, still need to distinguish between GET and HEAD in some edge case, you can use Request#head? and even Request.headers["REQUEST_METHOD"] for get the "real" answer. Closes #6694 [David Heinemeier Hansson] - - -*1.13.0 RC1* (r5619, November 22nd, 2006) - -* Update Routing to complain when :controller is not specified by a route. Closes #6669. [Nicholas Seckar] - -* Ensure render_to_string cleans up after itself when an exception is raised. #6658 [rsanheim] - -* Update to Prototype and script.aculo.us [5579]. [Sam Stephenson, Thomas Fuchs] - -* simple_format helper doesn't choke on nil. #6644 [jerry426] - -* Reuse named route helper module between Routing reloads. Use remove_method to delete named route methods after each load. Since the module is never collected, this fixes a significant memory leak. [Nicholas Seckar] - -* Deprecate standalone components. [Jeremy Kemper] - -* Always clear model associations from session. #4795 [sd@notso.net, andylien@gmail.com] - -* Remove JavaScriptLiteral in favor of ActiveSupport::JSON::Variable. [Sam Stephenson] - -* Sync ActionController::StatusCodes::STATUS_CODES with http://www.iana.org/assignments/http-status-codes. #6586 [dkubb] - -* Multipart form values may have a content type without being treated as uploaded files if they do not provide a filename. #6401 [Andreas Schwarz, Jeremy Kemper] - -* assert_response supports symbolic status codes. #6569 [Kevin Clark] - assert_response :ok - assert_response :not_found - assert_response :forbidden - -* Cache parsed query parameters. #6559 [Stefan Kaes] - -* Deprecate JavaScriptHelper#update_element_function, which is superseeded by RJS [Thomas Fuchs] - -* Fix invalid test fixture exposed by stricter Ruby 1.8.5 multipart parsing. #6524 [Bob Silva] - -* Set ActionView::Base.default_form_builder once rather than passing the :builder option to every form or overriding the form helper methods. [Jeremy Kemper] - -* Deprecate expire_matched_fragments. Use expire_fragment instead. #6535 [Bob Silva] - -* Deprecate start_form_tag and end_form_tag. Use form_tag / '' from now on. [Rick Olson] - -* Added block-usage to PrototypeHelper#form_remote_tag, document block-usage of FormTagHelper#form_tag [Rick Olson] - -* Add a 0 margin/padding div around the hidden _method input tag that form_tag outputs. [Rick Olson] - -* Added block-usage to TagHelper#content_tag [David Heinemeier Hansson]. Example: - - <% content_tag :div, :class => "strong" %> - Hello world! - <% end %> - - Will output: -
Hello world!
- -* Deprecated UrlHelper#link_to_image and UrlHelper#link_to :post => true #6409 [Bob Silva] - -* Upgraded NumberHelper with number_to_phone support international formats to comply with ITU E.123 by supporting area codes with less than 3 digits, added precision argument to number_to_human_size (defaults to 1) #6421 [Bob Silva] - -* Fixed that setting RAILS_ASSET_ID to "" should not add a trailing slash after assets #6454 [Bob Silva/chrismear] - -* Force *_url named routes to show the host in ActionView [Rick Olson] - - <%= url_for ... %> # no host - <%= foo_path %> # no host - <%= foo_url %> # host! - -* Add support for converting blocks into function arguments to JavaScriptGenerator#call and JavaScriptProxy#call. [Sam Stephenson] - -* Add JavaScriptGenerator#literal for wrapping a string in an object whose #to_json is the string itself. [Sam Stephenson] - -* Add <%= escape_once html %> to escape html while leaving any currently escaped entities alone. Fix button_to double-escaping issue. [Rick Olson] - -* Fix double-escaped entities, such as &amp;, &#123;, etc. [Rick Olson] - -* Fix routing to correctly determine when generation fails. Closes #6300. [psross]. - -* Fix broken assert_generates when extra keys are being checked. [Jamis Buck] - -* Replace KCODE checks with String#chars for truncate. Closes #6385 [Manfred Stienstra] - -* Make page caching respect the format of the resource that is being requested even if the current route is the default route so that, e.g. posts.rss is not transformed by url_for to '/' and subsequently cached as '/index.html' when it should be cached as '/posts.rss'. [Marcel Molina Jr.] - -* Use String#chars in TextHelper::excerpt. Closes #6386 [Manfred Stienstra] - -* Fix relative URL root matching problems. [Mark Imbriaco] - -* Fix filter skipping in controller subclasses. #5949, #6297, #6299 [Martin Emde] - -* render_text may optionally append to the response body. render_javascript appends by default. This allows you to chain multiple render :update calls by setting @performed_render = false between them (awaiting a better public API). [Jeremy Kemper] - -* Rename test assertion to prevent shadowing. Closes #6306. [psross] - -* Fixed that NumberHelper#number_to_delimiter should respect precision of higher than two digits #6231 [Philip Hallstrom] - -* Fixed that FormHelper#radio_button didn't respect an :id being passed in #6266 [evansj] - -* Added an html_options hash parameter to javascript_tag() and update_page_tag() helpers #6311 [tzaharia]. Example: - - update_page_tag :defer => 'true' { |page| ... } - - Gives: - - - - Which is needed for dealing with the IE6 DOM when it's not yet fully loaded. - -* Fixed that rescue template path shouldn't be hardcoded, then it's easier to hook in your own #6295 [Mike Naberezny] - -* Fixed escaping of backslashes in JavaScriptHelper#escape_javascript #6302 [sven@c3d2.de] - -* Fixed that some 500 rescues would cause 500's themselves because the response had not yet been generated #6329 [cmselmer] - -* respond_to :html doesn't assume .rhtml. #6281 [Hampton Catlin] - -* Fixed some deprecation warnings in ActionPack [Rick Olson] - -* assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. #6240 [japgolly] - -* Deprecation: @cookies, @headers, @request, @response will be removed after 1.2. Use the corresponding method instead. [Jeremy Kemper] - -* Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples: - - head :status => 404 # expands to "404 Not Found" - head :status => :not_found # expands to "404 Not Found" - head :status => :created # expands to "201 Created" - -* Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples: - - head :status => 404 # return an empty response with a 404 status - head :location => person_path(@person), :status => 201 - -* Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. [Rick Olson] - -* strip_links is case-insensitive. #6285 [tagoh, Bob Silva] - -* Clear the cache of possible controllers whenever Routes are reloaded. [Nicholas Seckar] - -* Filters overhaul including meantime filter support using around filters + blocks. #5949 [Martin Emde, Roman Le Negrate, Stefan Kaes, Jeremy Kemper] - -* Update CGI process to allow sessions to contain namespaced models. Closes #4638. [dfelstead@site5.com] - -* Fix routing to respect user provided requirements and defaults when assigning default routing options (such as :action => 'index'). Closes #5950. [Nicholas Seckar] - -* Rescue Errno::ECONNRESET to handle an unexpectedly closed socket connection. Improves SCGI reliability. #3368, #6226 [sdsykes, fhanshaw@vesaria.com] - -* Added that respond_to blocks will automatically set the content type to be the same as is requested [David Heinemeier Hansson]. Examples: - - respond_to do |format| - format.html { render :text => "I'm being sent as text/html" } - format.rss { render :text => "I'm being sent as application/rss+xml" } - format.atom { render :text => "I'm being sent as application/xml", :content_type => Mime::XML } - end - -* Added utf-8 as the default charset for all renders. You can change this default using ActionController::Base.default_charset=(encoding) [David Heinemeier Hansson] - -* Added proper getters and setters for content type and charset [David Heinemeier Hansson]. Example of what we used to do: - - response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" - - ...now: - - response.content_type = Mime::ATOM - response.charset = "utf-8" - -* Declare file extensions exempt from layouts. #6219 [brandon] - Example: ActionController::Base.exempt_from_layout 'rpdf' - -* Add chained replace/update support for assert_select_rjs [Rick Olson] - - Given RJS like... - - page['test1'].replace "
foo
" - page['test2'].replace_html "
foo
" - - Test it with... - - assert_select_rjs :chained_replace - assert_select_rjs :chained_replace, "test1" - - assert_select_rjs :chained_replace_html - assert_select_rjs :chained_replace_html, "test2" - -* Load helpers in alphabetical order for consistency. Resolve cyclic javascript_helper dependency. #6132, #6178 [choonkeat@gmail.com] - -* Skip params with empty names, such as the &=Save query string from . #2569 [Manfred Stienstra, raphinou@yahoo.com] - -* Fix assert_tag so that :content => "foo" does not match substrings, but only exact strings. Use :content => /foo/ to match substrings. #2799 [Eric Hodel] - -* Update JavaScriptGenerator#show/hide/toggle/remove to new Prototype syntax for multiple ids, #6068 [petermichaux@gmail.com] - -* Update UrlWriter to support :only_path. [Nicholas Seckar, Dave Thomas] - -* Fixed JavaScriptHelper#link_to_function and JavaScriptHelper#button_to_function to have the script argument be optional [David Heinemeier Hansson]. So what used to require a nil, like this: - - link_to("Hider", nil, :class => "hider_link") { |p| p[:something].hide } - - ...can be written like this: - - link_to("Hider", :class => "hider_link") { |p| p[:something].hide } - -* Added access to nested attributes in RJS #4548 [richcollins@gmail.com]. Examples: - - page['foo']['style'] # => $('foo').style; - page['foo']['style']['color'] # => $('blank_slate').style.color; - page['foo']['style']['color'] = 'red' # => $('blank_slate').style.color = 'red'; - page['foo']['style'].color = 'red' # => $('blank_slate').style.color = 'red'; - -* Fixed that AssetTagHelper#image_tag and others using compute_public_path should not modify the incoming source argument (closes #5102) [eule@space.ch] - -* Deprecated the auto-appending of .png to AssetTagHelper#image_tag calls that doesn't have an extension [David Heinemeier Hansson] - -* Fixed FormOptionsHelper#select to respect :selected value #5813 - -* Fixed TextHelper#simple_format to deal with multiple single returns within a single paragraph #5835 [moriq@moriq.com] - -* Fixed TextHelper#pluralize to handle 1 as a string #5909 [rails@bencurtis.com] - -* Improved resolution of DateHelper#distance_of_time_in_words for better precision #5994 [Bob Silva] - -* Changed that uncaught exceptions raised any where in the application will cause RAILS_ROOT/public/500.html to be read and shown instead of just the static "Application error (Rails)" [David Heinemeier Hansson] - -* Added deprecation language for pagination which will become a plugin by Rails 2.0 [David Heinemeier Hansson] - -* Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 [David Heinemeier Hansson] - -* Deprecated all of ActionController::Dependencies. All dependency loading is now handled from Active Support [David Heinemeier Hansson] - -* Added assert_select* for CSS selector-based testing (deprecates assert_tag) #5936 [assaf.arkin@gmail.com] - -* radio_button_tag generates unique id attributes. #3353 [Bob Silva, somekool@gmail.com] - -* strip_tags passes through blank args such as nil or "". #2229, #6702 [duncan@whomwah.com, dharana] - -* Cleanup assert_tag :children counting. #2181 [jamie@bravenet.com] - -* button_to accepts :method so you can PUT and DELETE with it. #6005 [Dan Webb] - -* Update sanitize text helper to strip plaintext tags, and . [Rick Olson] - -* Add routing tests to assert that RoutingError is raised when conditions aren't met. Closes #6016 [Nathan Witmer] - -* Make auto_link parse a greater subset of valid url formats. [Jamis Buck] - -* Integration tests: headers beginning with X aren't excluded from the HTTP_ prefix, so X-Requested-With becomes HTTP_X_REQUESTED_WITH as expected. [Mike Clark] - -* Switch to using FormEncodedPairParser for parsing request parameters. [Nicholas Seckar, David Heinemeier Hansson] - -* respond_to .html now always renders #{action_name}.rhtml so that registered custom template handlers do not override it in priority. Custom mime types require a block and throw proper error now. [Tobias Lütke] - -* Deprecation: test deprecated instance vars in partials. [Jeremy Kemper] - -* Add UrlWriter to allow writing urls from Mailers and scripts. [Nicholas Seckar] - -* Relax Routing's anchor pattern warning; it was preventing use of [^/] inside restrictions. [Nicholas Seckar] - -* Add controller_paths variable to Routing. [Nicholas Seckar] - -* Fix assert_redirected_to issue with named routes for module controllers. [Rick Olson] - -* Tweak RoutingError message to show option diffs, not just missing named route significant keys. [Rick Olson] - -* Invoke method_missing directly on hidden actions. Closes #3030. [Nicholas Seckar] - -* Add RoutingError exception when RouteSet fails to generate a path from a Named Route. [Rick Olson] - -* Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar] - -* Deprecation: check whether instance variables have been monkeyed with before assigning them to deprecation proxies. Raises a RuntimeError if so. [Jeremy Kemper] - -* Add support for the param_name parameter to the auto_complete_field helper. #5026 [david.a.williams@gmail.com] - -* Deprecation! @params, @session, @flash will be removed after 1.2. Use the corresponding instance methods instead. You'll get printed warnings during tests and logged warnings in dev mode when you access either instance variable directly. [Jeremy Kemper] - -* Make Routing noisy when an anchor regexp is assigned to a segment. #5674 [François Beausoleil] - -* Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" #5611 [pjhyett@gmail.com] - -* Make controller_path available as an instance method. #5724 [jmckible@gmail.com] - -* Update query parser to support adjacent hashes. [Nicholas Seckar] - -* Make action caching aware of different formats for the same action so that, e.g. foo.xml is cached separately from foo.html. Implicitly set content type when reading in cached content with mime revealing extensions so the entire onous isn't on the webserver. [Marcel Molina Jr.] - -* Restrict Request Method hacking with ?_method to POST requests. [Rick Olson] - -* Fixed the new_#{resource}_url route and added named route tests for Simply Restful. [Rick Olson] - -* Added map.resources from the Simply Restful plugin [David Heinemeier Hansson]. Examples (the API has changed to use plurals!): - - map.resources :messages - map.resources :messages, :comments - map.resources :messages, :new => { :preview => :post } - -* Fixed that integration simulation of XHRs should set Accept header as well [Edward Frederick] - -* TestRequest#reset_session should restore a TestSession, not a hash [Michael Koziarski] - -* Don't search a load-path of '.' for controller files [Jamis Buck] - -* Update integration.rb to require test_process explicitly instead of via Dependencies. [Nicholas Seckar] - -* Fixed that you can still access the flash after the flash has been reset in reset_session. Closes #5584 [lmarlow] - -* Allow form_for and fields_for to work with indexed form inputs. [Jeremy Kemper, Matt Lyon] - - <% form_for 'post[]', @post do |f| -%> - <% end -%> - -* Remove leak in development mode by replacing define_method with module_eval. [Nicholas Seckar] - -* Provide support for decimal columns to form helpers. Closes #5672. [Dave Thomas] - -* Pass :id => nil or :class => nil to error_messages_for to supress that html attribute. #3586 [olivier_ansaldi@yahoo.com] - -* Reset @html_document between requests so assert_tag works. #4810 [Jarkko Laine, easleydp@gmail.com] - -* Integration tests behave well with render_component. #4632 [edward.frederick@revolution.com, dev.rubyonrails@maxdunn.com] - -* Added exception handling of missing layouts #5373 [chris@ozmm.org] - -* Fixed that real files and symlinks should be treated the same when compiling templates #5438 [zachary@panandscan.com] - -* Fixed that the flash should be reset when reset_session is called #5584 [Shugo Maeda] - -* Added special case for "1 Byte" in NumberHelper#number_to_human_size #5593 [murpyh@rubychan.de] - -* Fixed proper form-encoded parameter parsing for requests with "Content-Type: application/x-www-form-urlencoded; charset=utf-8" (note the presence of a charset directive) [David Heinemeier Hansson] - -* Add route_name_path method to generate only the path for a named routes. For example, map.person will add person_path. [Nicholas Seckar] - -* Avoid naming collision among compiled view methods. [Jeremy Kemper] - -* Fix CGI extensions when they expect string but get nil in Windows. Closes #5276 [Mislav Marohnić] - -* Determine the correct template_root for deeply nested components. #2841 [s.brink@web.de] - -* Fix that routes with *path segments in the recall can generate URLs. [Rick Olson] - -* Fix strip_links so that it doesn't hang on multiline tags [Jamis Buck] - -* Remove problematic control chars in rescue template. #5316 [Stefan Kaes] - -* Make sure passed routing options are not mutated by routing code. #5314 [Blair Zajac] - -* Make sure changing the controller from foo/bar to bing/bang does not change relative to foo. [Jamis Buck] - -* Escape the path before routing recognition. #3671 - -* Make sure :id and friends are unescaped properly. #5275 [me@julik.nl] - -* Rewind readable CGI params so others may reread them (such as CGI::Session when passing the session id in a multipart form). #210 [mklame@atxeu.com, matthew@walker.wattle.id.au] - -* Added Mime::TEXT (text/plain) and Mime::ICS (text/calendar) as new default types [David Heinemeier Hansson] - -* Added Mime::Type.register(string, symbol, synonyms = []) for adding new custom mime types [David Heinemeier Hansson]. Example: Mime::Type.register("image/gif", :gif) - -* Added support for Mime objects in render :content_type option [David Heinemeier Hansson]. Example: render :text => some_atom, :content_type => Mime::ATOM - -* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 [Manfred Stienstra ] - -* Routing rewrite. Simpler, faster, easier to understand. The published API for config/routes.rb is unchanged, but nearly everything else is different, so expect breakage in plugins and libs that try to fiddle with routes. [Nicholas Seckar, Jamis Buck] - - map.connect '/foo/:id', :controller => '...', :action => '...' - map.connect '/foo/:id.:format', :controller => '...', :action => '...' - map.connect '/foo/:id', ..., :conditions => { :method => :get } - -* Cope with missing content type and length headers. Parse parameters from multipart and urlencoded request bodies only. [Jeremy Kemper] - -* Accept multipart PUT parameters. #5235 [guy.naor@famundo.com] - -* Added interrogation of params[:format] to determine Accept type. If :format is specified and matches a declared extension, like "rss" or "xml", that mime type will be put in front of the accept handler. This means you can link to the same action from different extensions and use that fact to determine output [David Heinemeier Hansson]. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.find :all - - respond_to do |format| - format.html - format.xml { render :xml => @posts.to_xml } - format.rss { render :action => "feed.rxml" } - end - end - end - - # returns HTML when requested by a browser, since the browser - # has the HTML mimetype at the top of its priority list - Accept: text/html - GET /weblog - - # returns the XML - Accept: application/xml - GET /weblog - - # returns the HTML - Accept: application/xml - GET /weblog.html - - # returns the XML - Accept: text/html - GET /weblog.xml - - All this relies on the fact that you have a route that includes .:format. - -* Expanded :method option in FormTagHelper#form_tag, FormHelper#form_for, PrototypeHelper#remote_form_for, PrototypeHelper#remote_form_tag, and PrototypeHelper#link_to_remote to allow for verbs other than GET and POST by automatically creating a hidden form field named _method, which will simulate the other verbs over post [David Heinemeier Hansson] - -* Added :method option to UrlHelper#link_to, which allows for using other verbs than GET for the link. This replaces the :post option, which is now deprecated. Example: link_to "Destroy", person_url(:id => person), :method => :delete [David Heinemeier Hansson] - -* follow_redirect doesn't complain about being redirected to the same controller. #5153 [dymo@mk.ukrtelecom.ua] - -* Add layout attribute to response object with the name of the layout that was rendered, or nil if none rendered. [Kevin Clark] - -* Fix NoMethodError when parsing params like &&. [Adam Greenfield] - -* form.text_area handles the :size option just like the original text_area (:size => '60x10' becomes cols="60" rows="10"). [Jeremy Kemper] - -* Excise ingrown code from FormOptionsHelper#options_for_select. #5008 [anonymous] - -* Small fix in routing to allow dynamic routes (broken after [4242]) [Rick Olson] - - map.connect '*path', :controller => 'files', :action => 'show' - -* Use #flush between switching from #write to #syswrite. Closes #4907. [Blair Zajac ] - -* Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes #4186. [andrew@redlinesoftware.com, Marcel Molina Jr.] - - error_messages_for :account, :user, :subscription, :object_name => :account - -* Fix assert_redirected_to tests according to real-world usage. Also, don't fail if you add an extra :controller option: [Rick Olson] - - redirect_to :action => 'new' - assert_redirected_to :controller => 'monkeys', :action => 'new' - -* Diff compared routing options. Allow #assert_recognizes to take a second arg as a hash to specify optional request method [Rick Olson] - - assert_recognizes({:controller => 'users', :action => 'index'}, 'users') - assert_recognizes({:controller => 'users', :action => 'create'}, {:path => 'users', :method => :post}) - -* Diff compared options with #assert_redirected_to [Rick Olson] - -* Add support in routes for semicolon delimited "subpaths", like /books/:id;:action [Jamis Buck] - -* Change link_to_function and button_to_function to (optionally) take an update_page block instead of a JavaScript string. Closes #4804. [zraii@comcast.net, Sam Stephenson] - -* Modify routing so that you can say :require => { :method => :post } for a route, and the route will never be selected unless the request method is POST. Only works for route recognition, not for route generation. [Jamis Buck] - -* Added :add_headers option to verify which merges a hash of name/value pairs into the response's headers hash if the prerequisites cannot be satisfied. [Sam Stephenson] - ex. verify :only => :speak, :method => :post, - :render => { :status => 405, :text => "Must be post" }, - :add_headers => { "Allow" => "POST" } - - -*1.12.5* (August 10th, 2006) - -* Updated security fix - - -*1.12.4* (August 8th, 2006) - -* Cache CgiRequest#request_parameters so that multiple calls don't re-parse multipart data. [Rick Olson] - -* Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for [David Heinemeier Hansson] - -* Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled. #1897 [jeremye@bsa.ca.gov] - -* Fixed that real files and symlinks should be treated the same when compiling templates. #5438 [zachary@panandscan.com] - -* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 [Manfred Stienstra ] - -* Update documentation for erb trim syntax. #5651 [matt@mattmargolis.net] - -* Short documentation to mention use of Mime::Type.register. #5710 [choonkeat@gmail.com] - - -*1.12.3* (June 28th, 2006) - -* Fix broken traverse_to_controller. We now: - Look for a _controller.rb file under RAILS_ROOT to load. - If we find it, we require_dependency it and return the controller it defined. (If none was defined we stop looking.) - If we don't find it, we look for a .rb file under RAILS_ROOT to load. If we find it, and it loads a constant we keep looking. - Otherwise we check to see if a directory of the same name exists, and if it does we create a module for it. - - -*1.12.2* (June 27th, 2006) - -* Refinement to avoid exceptions in traverse_to_controller. - -* (Hackish) Fix loading of arbitrary files in Ruby's load path by traverse_to_controller. [Nicholas Seckar] - - -*1.12.1* (April 6th, 2006) - -* Fixed that template extensions would be cached development mode #4624 [Stefan Kaes] - -* Update to Prototype 1.5.0_rc0 [Sam Stephenson] - -* Honor skipping filters conditionally for only certain actions even when the parent class sets that filter to conditionally be executed only for the same actions. #4522 [Marcel Molina Jr.] - -* Delegate xml_http_request in integration tests to the session instance. [Jamis Buck] - -* Update the diagnostics template skip the useless '' text. [Nicholas Seckar] - -* CHANGED DEFAULT: Don't parse YAML input by default, but keep it available as an easy option [David Heinemeier Hansson] - -* Add additional autocompleter options [aballai, Thomas Fuchs] - -* Fixed fragment caching of binary data on Windows #4493 [bellis@deepthought.org] - -* Applied Prototype $() performance patches (#4465, #4477) and updated script.aculo.us [Sam Stephenson, Thomas Fuchs] - -* Added automated timestamping to AssetTagHelper methods for stylesheets, javascripts, and images when Action Controller is run under Rails [David Heinemeier Hansson]. Example: - - image_tag("rails.png") # => 'Rails' - - ...to avoid frequent stats (not a problem for most people), you can set RAILS_ASSET_ID in the ENV to avoid stats: - - ENV["RAILS_ASSET_ID"] = "2345" - image_tag("rails.png") # => 'Rails' - - This can be used by deployment managers to set the asset id by application revision - - -*1.12.0* (March 27th, 2006) - -* Add documentation for respond_to. [Jamis Buck] - -* Fixed require of bluecloth and redcloth when gems haven't been loaded #4446 [murphy@cYcnus.de] - -* Update to Prototype 1.5.0_pre1 [Sam Stephenson] - -* Change #form_for and #fields_for so that the second argument is not required [Dave Thomas] - - <% form_for :post, @post, :url => { :action => 'create' } do |f| -%> - - becomes... - - <% form_for :post, :url => { :action => 'create' } do |f| -%> - -* Update to script.aculo.us 1.6 [Thomas Fuchs] - -* Enable application/x-yaml processing by default [Jamis Buck] - -* Fix double url escaping of remote_function. Add :escape => false option to ActionView's url_for. [Nicholas Seckar] - -* Add :script option to in_place_editor to support evalScripts (closes #4194) [Cody Fauser] - -* Fix mixed case enumerable methods in the JavaScript Collection Proxy (closes #4314) [Cody Fauser] - -* Undo accidental escaping for mail_to; add regression test. [Nicholas Seckar] - -* Added nicer message for assert_redirected_to (closes #4294) [court3nay] - - assert_redirected_to :action => 'other_host', :only_path => false - - when it was expecting... - - redirected_to :action => 'other_host', :only_path => true, :host => 'other.test.host' - - gives the error message... - - response is not a redirection to all of the options supplied (redirection is <{:only_path=>false, :host=>"other.test.host", :action=>"other_host"}>), difference: <{:only_path=>"true", :host=>"other.test.host"}> - -* Change url_for to escape the resulting URLs when called from a view. [Nicholas Seckar, coffee2code] - -* Added easy support for testing file uploads with fixture_file_upload #4105 [turnip@turnipspatch.com]. Example: - - # Looks in Test::Unit::TestCase.fixture_path + '/files/spongebob.png' - post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png') - -* Fixed UrlHelper#current_page? to behave even when url-escaped entities are present #3929 [jeremy@planetargon.com] - -* Add ability for relative_url_root to be specified via an environment variable RAILS_RELATIVE_URL_ROOT. [isaac@reuben.com, Nicholas Seckar] - -* Fixed link_to "somewhere", :post => true to produce valid XHTML by using the parentnode instead of document.body for the instant form #3007 [Bob Silva] - -* Added :function option to PrototypeHelper#observe_field/observe_form that allows you to call a function instead of submitting an ajax call as the trigger #4268 [jonathan@daikini.com] - -* Make Mime::Type.parse consider q values (if any) [Jamis Buck] - -* XML-formatted requests are typecast according to "type" attributes for :xml_simple [Jamis Buck] - -* Added protection against proxy setups treating requests as local even when they're not #3898 [Steve Purcell] - -* Added TestRequest#raw_post that simulate raw_post from CgiRequest #3042 [François Beausoleil] - -* Underscore dasherized keys in formatted requests [Jamis Buck] - -* Add MimeResponds::Responder#any for managing multiple types with identical responses [Jamis Buck] - -* Make the xml_http_request testing method set the HTTP_ACCEPT header [Jamis Buck] - -* Add Verification to scaffolds. Prevent destructive actions using GET [Michael Koziarski] - -* Avoid hitting the filesystem when using layouts by using a File.directory? cache. [Stefan Kaes, Nicholas Seckar] - -* Simplify ActionController::Base#controller_path [Nicholas Seckar] - -* Added simple alert() notifications for RJS exceptions when config.action_view.debug_rjs = true. [Sam Stephenson] - -* Added :content_type option to render, so you can change the content type on the fly [David Heinemeier Hansson]. Example: render :action => "atom.rxml", :content_type => "application/atom+xml" - -* CHANGED DEFAULT: The default content type for .rxml is now application/xml instead of type/xml, see http://www.xml.com/pub/a/2004/07/21/dive.html for reason [David Heinemeier Hansson] - -* Added option to render action/template/file of a specific extension (and here by template type). This means you can have multiple templates with the same name but a different extension [David Heinemeier Hansson]. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.find :all - - respond_to do |type| - type.html # using defaults, which will render weblog/index.rhtml - type.xml { render :action => "index.rxml" } - type.js { render :action => "index.rjs" } - end - end - end - -* Added better support for using the same actions to output for different sources depending on the Accept header [David Heinemeier Hansson]. Example: - - class WeblogController < ActionController::Base - def create - @post = Post.create(params[:post]) - - respond_to do |type| - type.js { render } # renders create.rjs - type.html { redirect_to :action => "index" } - type.xml do - headers["Location"] = url_for(:action => "show", :id => @post) - render(:nothing, :status => "201 Created") - end - end - end - end - -* Added Base#render(:xml => xml) that works just like Base#render(:text => text), but sets the content-type to text/xml and the charset to UTF-8 [David Heinemeier Hansson] - -* Integration test's url_for now runs in the context of the last request (if any) so after post /products/show/1 url_for :action => 'new' will yield /product/new [Tobias Lütke] - -* Re-added mixed-in helper methods for the JavascriptGenerator. Moved JavascriptGenerators methods to a module that is mixed in after the helpers are added. Also fixed that variables set in the enumeration methods like #collect are set correctly. Documentation added for the enumeration methods [Rick Olson]. Examples: - - page.select('#items li').collect('items') do |element| - element.hide - end - # => var items = $$('#items li').collect(function(value, index) { return value.hide(); }); - -* Added plugin support for parameter parsers, which allows for better support for REST web services. By default, posts submitted with the application/xml content type is handled by creating a XmlSimple hash with the same name as the root element of the submitted xml. More handlers can easily be registered like this: - - # Assign a new param parser to a new content type - ActionController::Base.param_parsers['application/atom+xml'] = Proc.new do |data| - node = REXML::Document.new(post) - { node.root.name => node.root } - end - - # Assign the default XmlSimple to a new content type - ActionController::Base.param_parsers['application/backpack+xml'] = :xml_simple - -Default YAML web services were retired, ActionController::Base.param_parsers carries an example which shows how to get this functionality back. As part of this new plugin support, request.[formatted_post?, xml_post?, yaml_post? and post_format] were all deprecated in favor of request.content_type [Tobias Lütke] - -* Fixed Effect.Appear in effects.js to work with floats in Safari #3524, #3813, #3044 [Thomas Fuchs] - -* Fixed that default image extension was not appended when using a full URL with AssetTagHelper#image_tag #4032, #3728 [rubyonrails@beautifulpixel.com] - -* Added that page caching will only happen if the response code is less than 400 #4033 [g.bucher@teti.ch] - -* Add ActionController::IntegrationTest to allow high-level testing of the way the controllers and routes all work together [Jamis Buck] - -* Added support to AssetTagHelper#javascript_include_tag for having :defaults appear anywhere in the list, so you can now make one call ala javascript_include_tag(:defaults, "my_scripts") or javascript_include_tag("my_scripts", :defaults) depending on how you want the load order #3506 [Bob Silva] - -* Added support for visual effects scoped queues to the visual_effect helper #3530 [Abdur-Rahman Advany] - -* Added .rxml (and any non-rhtml template, really) supportfor CaptureHelper#content_for and CaptureHelper#capture #3287 [Brian Takita] - -* Added script.aculo.us drag and drop helpers to RJS [Thomas Fuchs]. Examples: - - page.draggable 'product-1' - page.drop_receiving 'wastebasket', :url => { :action => 'delete' } - page.sortable 'todolist', :url => { action => 'change_order' } - -* Fixed that form elements would strip the trailing [] from the first parameter #3545 [ruby@bobsilva.com] - -* During controller resolution, update the NameError suppression to check for the expected constant. [Nicholas Seckar] - -* Update script.aculo.us to V1.5.3 [Thomas Fuchs] - -* Added various InPlaceEditor options, #3746, #3891, #3896, #3906 [Bill Burcham, ruairi, sl33p3r] - -* Added :count option to pagination that'll make it possible for the ActiveRecord::Base.count call to using something else than * for the count. Especially important for count queries using DISTINCT #3839 [Stefan Kaes] - -* Update script.aculo.us to V1.5.2 [Thomas Fuchs] - -* Added element and collection proxies to RJS [David Heinemeier Hansson]. Examples: - - page['blank_slate'] # => $('blank_slate'); - page['blank_slate'].show # => $('blank_slate').show(); - page['blank_slate'].show('first').up # => $('blank_slate').show('first').up(); - - page.select('p') # => $$('p'); - page.select('p.welcome b').first # => $$('p.welcome b').first(); - page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide(); - -* Add JavaScriptGenerator#replace for replacing an element's "outer HTML". #3246 [tom@craz8.com, Sam Stephenson] - -* Remove over-engineered form_for code for a leaner implementation. [Nicholas Seckar] - -* Document form_for's :html option. [Nicholas Seckar] - -* Major components cleanup and speedup. #3527 [Stefan Kaes] - -* Fix problems with pagination and :include. [Kevin Clark] - -* Add ActiveRecordTestCase for testing AR integration. [Kevin Clark] - -* Add Unit Tests for pagination [Kevin Clark] - -* Add :html option for specifying form tag options in form_for. [Sam Stephenson] - -* Replace dubious controller parent class in filter docs. #3655, #3722 [info@rhalff.com, eigentone@gmail.com] - -* Don't interpret the :value option on text_area as an html attribute. Set the text_area's value. #3752 [gabriel@gironda.org] - -* Fix remote_form_for creates a non-ajax form. [Rick Olson] - -* Don't let arbitrary classes match as controllers -- a potentially dangerous bug. [Nicholas Seckar] - -* Fix Routing tests. Fix routing where failing to match a controller would prevent the rest of routes from being attempted. [Nicholas Seckar] - -* Add :builder => option to form_for and friends. [Nicholas Seckar, Rick Olson] - -* Fix controller resolution to avoid accidentally inheriting a controller from a parent module. [Nicholas Seckar] - -* Set sweeper's @controller to nil after a request so that the controller may be collected between requests. [Nicholas Seckar] - -* Subclasses of ActionController::Caching::Sweeper should be Reloadable. [Rick Olson] - -* Document the :xhr option for verifications. #3666 [leeo] - -* Added :only and :except controls to skip_before/after_filter just like for when you add filters [David Heinemeier Hansson] - -* Ensure that the instance variables are copied to the template when performing render :update. [Nicholas Seckar] - -* Add the ability to call JavaScriptGenerator methods from helpers called in update blocks. [Sam Stephenson] Example: - module ApplicationHelper - def update_time - page.replace_html 'time', Time.now.to_s(:db) - page.visual_effect :highlight, 'time' - end - end - - class UserController < ApplicationController - def poll - render :update { |page| page.update_time } - end - end - -* Add render(:update) to ActionView::Base. [Sam Stephenson] - -* Fix render(:update) to not render layouts. [Sam Stephenson] - -* Fixed that SSL would not correctly be detected when running lighttpd/fcgi behind lighttpd w/mod_proxy #3548 [Steve Purcell] - -* Added the possibility to specify atomatic expiration for the memcachd session container #3571 [Stefan Kaes] - -* Change layout discovery to take into account the change in semantics with File.join and nil arguments. [Marcel Molina Jr.] - -* Raise a RedirectBackError if redirect_to :back is called when there's no HTTP_REFERER defined #3049 [Kevin Clark] - -* Treat timestamps like datetimes for scaffolding purposes #3388 [Maik Schmidt] - -* Fix IE bug with link_to "something", :post => true #3443 [Justin Palmer] - -* Extract Test::Unit::TestCase test process behavior into an ActionController::TestProcess module. [Sam Stephenson] - -* Pass along blocks from render_to_string to render. [Sam Stephenson] - -* Add render :update for inline RJS. [Sam Stephenson] Example: - class UserController < ApplicationController - def refresh - render :update do |page| - page.replace_html 'user_list', :partial => 'user', :collection => @users - page.visual_effect :highlight, 'user_list' - end - end - end - -* allow nil objects for error_messages_for [Michael Koziarski] - -* Refactor human_size to exclude decimal place if it is zero. [Marcel Molina Jr.] - -* Update to Prototype 1.5.0_pre0 [Sam Stephenson] - -* Automatically discover layouts when a controller is namespaced. #2199, #3424 [me@jonnii.com rails@jeffcole.net Marcel Molina Jr.] - -* Add support for multiple proxy servers to CgiRequest#host [gaetanot@comcast.net] - -* Documentation typo fix. #2367 [Blair Zajac] - -* Remove Upload Progress. #2871 [Sean Treadway] - -* Fix typo in function name mapping in auto_complete_field. #2929 #3446 [doppler@gmail.com phil.ross@gmail.com] - -* Allow auto-discovery of third party template library layouts. [Marcel Molina Jr.] - -* Have the form builder output radio button, not check box, when calling the radio button helper. #3331 [LouisStAmour@gmail.com] - -* Added assignment of the Autocompleter object created by JavaScriptMacroHelper#auto_complete_field to a local javascript variables [David Heinemeier Hansson] - -* Added :on option for PrototypeHelper#observe_field that allows you to specify a different callback hook to have the observer trigger on [David Heinemeier Hansson] - -* Added JavaScriptHelper#button_to_function that works just like JavaScriptHelper#link_to_function but uses a button instead of a href [David Heinemeier Hansson] - -* Added that JavaScriptHelper#link_to_function will honor existing :onclick definitions when adding the function call [David Heinemeier Hansson] - -* Added :disable_with option to FormTagHelper#submit_tag to allow for easily disabled submit buttons with different text [David Heinemeier Hansson] - -* Make auto_link handle nil by returning quickly if blank? [Scott Barron] - -* Make auto_link match urls with a port number specified. [Marcel Molina Jr.] - -* Added support for toggling visual effects to ScriptaculousHelper::visual_effect, #3323. [Thomas Fuchs] - -* Update to script.aculo.us to 1.5.0 rev. 3343 [Thomas Fuchs] - -* Added :select option for JavaScriptMacroHelper#auto_complete_field that makes it easier to only use part of the auto-complete suggestion as the value for insertion [Thomas Fuchs] - -* Added delayed execution of Javascript from within RJS #3264 [devslashnull@gmail.com]. Example: - - page.delay(20) do - page.visual_effect :fade, 'notice' - end - -* Add session ID to default logging, but remove the verbose description of every step [David Heinemeier Hansson] - -* Add the following RJS methods: [Sam Stephenson] - - * alert - Displays an alert() dialog - * redirect_to - Changes window.location.href to simulate a browser redirect - * call - Calls a JavaScript function - * assign - Assigns to a JavaScript variable - * << - Inserts an arbitrary JavaScript string - -* Fix incorrect documentation for form_for [Nicholas Seckar] - -* Don't include a layout when rendering an rjs template using render's :template option. [Marcel Molina Jr.] - -*1.1.2* (December 13th, 2005) - -* Become part of Rails 1.0 - -* Update to script.aculo.us 1.5.0 final (equals 1.5.0_rc6) [Thomas Fuchs] - -* Update to Prototype 1.4.0 final [Sam Stephenson] - -* Added form_remote_for (form_for meets form_remote_tag) [David Heinemeier Hansson] - -* Update to script.aculo.us 1.5.0_rc6 - -* More robust relative url root discovery for SCGI compatibility. This solves the 'SCGI routes problem' -- you no longer need to prefix all your routes with the name of the SCGI mountpoint. #3070 [Dave Ringoen] - -* Fix docs for text_area_tag. #3083. [Christopher Cotton] - -* Change form_for and fields_for method signatures to take object name and object as separate arguments rather than as a Hash. [David Heinemeier Hansson] - -* Introduce :selected option to the select helper. Allows you to specify a selection other than the current value of object.method. Specify :selected => nil to leave all options unselected. #2991 [Jonathan Viney ] - -* Initialize @optional in routing code to avoid warnings about uninitialized access to an instance variable. [Nicholas Seckar] - -* Make ActionController's render honor the :locals option when rendering a :file. #1665. [Emanuel Borsboom, Marcel Molina Jr.] - -* Allow assert_tag(:conditions) to match the empty string when a tag has no children. Closes #2959. [Jamis Buck] - -* Update html-scanner to handle CDATA sections better. Closes #2970. [Jamis Buck] - -* Don't put flash in session if sessions are disabled. [Jeremy Kemper] - -* Strip out trailing &_= for raw post bodies. Closes #2868. [Sam Stephenson] - -* Pass multiple arguments to Element.show and Element.hide in JavaScriptGenerator instead of using iterators. [Sam Stephenson] - -* Improve expire_fragment documentation. #2966 [court3nay] - -* Correct docs for automatic layout assignment. #2610. [Charles M. Gerungan] - -* Always create new AR sessions rather than trying too hard to avoid database traffic. #2731 [Jeremy Kemper] - -* Update to Prototype 1.4.0_rc4. Closes #2943 (old Array.prototype.reverse behavior can be obtained by passing false as an argument). [Sam Stephenson] - -* Use Element.update('id', 'html') instead of $('id').innerHTML = 'html' in JavaScriptGenerator#replace_html so that script tags are evaluated. [Sam Stephenson] - -* Make rjs templates always implicitly skip out on layouts. [Marcel Molina Jr.] - -* Correct length for the truncate text helper. #2913 [Stefan Kaes] - -* Update to Prototype 1.4.0_rc3. Closes #1893, #2505, #2550, #2748, #2783. [Sam Stephenson] - -* Add support for new rjs templates which wrap an update_page block. [Marcel Molina Jr.] - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - -* Correct time_zone_options_for_select docs. #2892 [pudeyo@rpi.com] - -* Remove the unused, slow response_dump and session_dump variables from error pages. #1222 [lmarlow] - -* Performance tweaks: use Set instead of Array to speed up prototype helper include? calls. Avoid logging code if logger is nil. Inline commonly-called template presence checks. #2880, #2881, #2882, #2883 [Stefan Kaes] - -* MemCache store may be given multiple addresses. #2869 [Ryan Carver ] - -* Handle cookie parsing irregularity for certain Nokia phones. #2530 [zaitzow@gmail.com] - -* Added PrototypeHelper::JavaScriptGenerator and PrototypeHelper#update_page for easily modifying multiple elements in an Ajax response. [Sam Stephenson] Example: - - update_page do |page| - page.insert_html :bottom, 'list', '
  • Last item
  • ' - page.visual_effect :highlight, 'list' - page.hide 'status-indicator', 'cancel-link' - end - - generates the following JavaScript: - - new Insertion.Bottom("list", "
  • Last item
  • "); - new Effect.Highlight("list"); - ["status-indicator", "cancel-link"].each(Element.hide); - -* Refactored JavaScriptHelper into PrototypeHelper and ScriptaculousHelper [Sam Stephenson] - -* Update to latest script.aculo.us version (as of [3031]) - -* Updated docs for in_place_editor, fixes a couple bugs and offers extended support for external controls [Justin Palmer] - -* Update documentation for render :file. #2858 [Tom Werner] - -* Only include builtin filters whose filenames match /^[a-z][a-z_]*_helper.rb$/ to avoid including operating system metadata such as ._foo_helper.rb. #2855 [court3nay] - -* Added FormHelper#form_for and FormHelper#fields_for that makes it easier to work with forms for single objects also if they don't reside in instance variables [David Heinemeier Hansson]. Examples: - - <% form_for :person, @person, :url => { :action => "update" } do |f| %> - First name: <%= f.text_field :first_name %> - Last name : <%= f.text_field :last_name %> - Biography : <%= f.text_area :biography %> - Admin? : <%= f.check_box :admin %> - <% end %> - - <% form_for :person, person, :url => { :action => "update" } do |person_form| %> - First name: <%= person_form.text_field :first_name %> - Last name : <%= person_form.text_field :last_name %> - - <% fields_for :permission => person.permission do |permission_fields| %> - Admin? : <%= permission_fields.check_box :admin %> - <% end %> - <% end %> - -* options_for_select allows any objects which respond_to? :first and :last rather than restricting to Array and Range. #2824 [Jacob Robbins , Jeremy Kemper] - -* The auto_link text helper accepts an optional block to format the link text for each url and email address. Example: auto_link(post.body) { |text| truncate(text, 10) } [Jeremy Kemper] - -* assert_tag uses exact matches for string conditions, instead of partial matches. Use regex to do partial matches. #2799 [Jamis Buck] - -* CGI::Session::ActiveRecordStore.data_column_name = 'foobar' to use a different session data column than the 'data' default. [nbpwie102@sneakemail.com] - -* Do not raise an exception when default helper is missing; log a debug message instead. It's nice to delete empty helpers. [Jeremy Kemper] - -* Controllers with acronyms in their names (e.g. PDFController) require the correct default helper (PDFHelper in file pdf_helper.rb). #2262 [jeff@opendbms.com] - - -*1.11.0* (November 7th, 2005) - -* Added request as instance method to views, so you can do <%= request.env["HTTP_REFERER"] %>, just like you can already access response, session, and the likes [David Heinemeier Hansson] - -* Fix conflict with assert_tag and Glue gem #2255 [david.felstead@gmail.com] - -* Add documentation to assert_tag indicating that it only works with well-formed XHTML #1937, #2570 [Jamis Buck] - -* Added action_pack.rb stub so that ActionPack::Version loads properly [Sam Stephenson] - -* Added short-hand to assert_tag so assert_tag :tag => "span" can be written as assert_tag "span" [David Heinemeier Hansson] - -* Added skip_before_filter/skip_after_filter for easier control of the filter chain in inheritance hierachies [David Heinemeier Hansson]. Example: - - class ApplicationController < ActionController::Base - before_filter :authenticate - end - - class WeblogController < ApplicationController - # will run the :authenticate filter - end - - class SignupController < ActionController::Base - # will not run the :authenticate filter - skip_before_filter :authenticate - end - -* Added redirect_to :back as a short-hand for redirect_to(request.env["HTTP_REFERER"]) [David Heinemeier Hansson] - -* Change javascript_include_tag :defaults to not use script.aculo.us loader, which facilitates the use of plugins for future script.aculo.us and third party javascript extensions, and provide register_javascript_include_default for plugins to specify additional JavaScript files to load. Removed slider.js and builder.js from actionpack. [Thomas Fuchs] - -* Fix problem where redirecting components can cause an infinite loop [Rick Olson] - -* Added support for the queue option on visual_effect [Thomas Fuchs] - -* Update script.aculo.us to V1.5_rc4 [Thomas Fuchs] - -* Fix that render :text didn't interpolate instance variables #2629, #2626 [Stefan Kaes] - -* Fix line number detection and escape RAILS_ROOT in backtrace Regexp [Nicholas Seckar] - -* Fixed document.getElementsByClassName from Prototype to be speedy again [Sam Stephenson] - -* Recognize ./#{RAILS_ROOT} as RAILS_ROOT in error traces [Nicholas Seckar] - -* Remove ARStore session fingerprinting [Nicholas Seckar] - -* Fix obscure bug in ARStore [Nicholas Seckar] - -* Added TextHelper#strip_tags for removing HTML tags from a string (using HTMLTokenizer) #2229 [marcin@junkheap.net] - -* Added a reader for flash.now, so it's possible to do stuff like flash.now[:alert] ||= 'New if not set' #2422 [Caio Chassot] - - -*1.10.2* (October 26th, 2005) - -* Reset template variables after using render_to_string [Stefan Kaes] - -* Expose the session model backing CGI::Session - -* Abbreviate RAILS_ROOT in traces - - -*1.10.1* (October 19th, 2005) - -* Update error trace templates [Nicholas Seckar] - -* Stop showing generated routing code in application traces [Nicholas Seckar] - - -*1.10.0* (October 16th, 2005) - -* Make string-keys locals assigns optional. Add documentation describing depreciated state [Stefan Kaes] - -* Improve line number detection for template errors [Nicholas Seckar] - -* Update/clean up documentation (rdoc) - -* Upgrade to Prototype 1.4.0_rc0 [Sam Stephenson] - -* Added assert_vaild. Reports the proper AR error messages as fail message when the passed record is invalid [Tobias Lütke] - -* Add temporary support for passing locals to render using string keys [Nicholas Seckar] - -* Clean up error pages by providing better backtraces [Nicholas Seckar] - -* Raise an exception if an attempt is made to insert more session data into the ActiveRecordStore data column than the column can hold. #2234. [justin@textdrive.com] - -* Removed references to assertions.rb from actionpack assert's backtraces. Makes error reports in functional unit tests much less noisy. [Tobias Lütke] - -* Updated and clarified documentation for JavaScriptHelper to be more concise about the various options for including the JavaScript libs. [Thomas Fuchs] - -* Hide "Retry with Breakpoint" button on error pages until feature is functional. [David Heinemeier Hansson] - -* Fix Request#host_with_port to use the standard port when Rails is behind a proxy. [Nicholas Seckar] - -* Escape query strings in the href attribute of URLs created by url_helper. #2333 [Michael Schuerig ] - -* Improved line number reporting for template errors [Nicholas Seckar] - -* Added :locals support for render :inline #2463 [mdabney@cavoksolutions.com] - -* Unset the X-Requested-With header when using the xhr wrapper in functional tests so that future requests aren't accidentally xhr'ed #2352 [me@julik.nl, Sam Stephenson] - -* Unescape paths before writing cache to file system. #1877. [Damien Pollet] - -* Wrap javascript_tag contents in a CDATA section and add a cdata_section method to TagHelper #1691 [Michael Schuerig, Sam Stephenson] - -* Misc doc fixes (typos/grammar/etc). #2445. [coffee2code] - -* Speed improvement for session_options. #2287. [Stefan Kaes] - -* Make cacheing binary files friendly with Windows. #1975. [Rich Olson] - -* Convert boolean form options form the tag_helper. #809. [Michael Schuerig ] - -* Fixed that an instance variable with the same name as a partial should be implicitly passed as the partial :object #2269 [court3nay] - -* Update Prototype to V1.4.0_pre11, script.aculo.us to [2502] [Thomas Fuchs] - -* Make assert_tag :children count appropriately. Closes #2181. [jamie@bravenet.com] - -* Forced newer versions of RedCloth to use hard breaks [David Heinemeier Hansson] - -* Added new scriptaculous options for auto_complete_field #2343 [Manfred Stienstra] - -* Don't prepend the asset host if the string is already a fully-qualified URL - -* Updated to script.aculo.us V1.5.0_rc2 and Prototype to V1.4.0_pre7 [Thomas Fuchs] - -* Undo condition change made in [2345] to prevent normal parameters arriving as StringIO. - -* Tolerate consecutive delimiters in query parameters. #2295 [darashi@gmail.com] - -* Streamline render process, code cleaning. Closes #2294. [skae] - -* Keep flash after components are rendered. #2291 [Rick Olson, Scott] - -* Shorten IE file upload path to filename only to match other browsers. #1507 [court3nay] - -* Fix open/save dialog in IE not opening files send with send_file/send_data, #2279 [Thomas Fuchs] - -* Fixed that auto_discovery_link_tag couldn't take a string as the URL [David Heinemeier Hansson] - -* Fixed problem with send_file and WEBrick using stdout #1812 [David Heinemeier Hansson] - -* Optimized tag_options to not sort keys, which is no longer necessary when assert_dom_equal and friend is available #1995 [skae] - -* Added assert_dom_equal and assert_dom_not_equal to compare tags generated by the helpers in an order-indifferent manner #1995 [skae] - -* Fixed that Request#domain caused an exception if the domain header wasn't set in the original http request #1795 [Michael Koziarski] - -* Make the truncate() helper multi-byte safe (assuming $KCODE has been set to something other than "NONE") #2103 - -* Add routing tests from #1945 [ben@groovie.org] - -* Add a routing test case covering #2101 [Nicholas Seckar] - -* Cache relative_url_root for all webservers, not just Apache #2193 [skae] - -* Speed up cookie use by decreasing string copying #2194 [skae] - -* Fixed access to "Host" header with requests made by crappy old HTTP/1.0 clients #2124 [Marcel Molina Jr.] - -* Added easy assignment of fragment cache store through use of symbols for included stores (old way still works too) - - Before: - ActionController::Base.fragment_cache_store = - ActionController::Base::Caching::Fragments::FileStore.new("/path/to/cache/directory") - - After: - ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory" - -* Added ActionController::Base.session_store=, session_store, and session_options to make it easier to tweak the session options (instead of going straight to ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS) - -* Added TextHelper#cycle to cycle over an array of values on each hit (useful for alternating row colors etc) #2154 [dave-ml@dribin.org] - -* Ensure that request.path never returns nil. Closes #1675 [Nicholas Seckar] - -* Add ability to specify Route Regexps for controllers. Closes #1917. [Sebastian Kanthak] - -* Provide Named Route's hash methods as helper methods. Closes #1744. [Nicholas Seckar, Steve Purcell] - -* Added :multipart option to ActiveRecordHelper#form to make it possible to add file input fields #2034 [jstirk@oobleyboo.com] - -* Moved auto-completion and in-place editing into the Macros module and their helper counterparts into JavaScriptMacrosHelper - -* Added in-place editing support in the spirit of auto complete with ActionController::Base.in_place_edit_for, JavascriptHelper#in_place_editor_field, and Javascript support from script.aculo.us #2038 [Jon Tirsen] - -* Added :disabled option to all data selects that'll make the elements inaccessible for change #2167, #253 [eigentone] - -* Fixed that TextHelper#auto_link_urls would include punctuation in the links #2166, #1671 [eigentone] - -* Fixed that number_to_currency(1000, {:precision => 0})) should return "$1,000", instead of "$1,000." #2122 [sd@notso.net] - -* Allow link_to_remote to use any DOM-element as the parent of the form elements to be submitted #2137 [erik@ruby-lang.nl]. Example: - - - - - <%= link_to_remote 'Save', :update => "row023", - :submit => "row023", :url => {:action => 'save_row'} %> - - -* Fixed that render :partial would fail when :object was a Hash (due to backwards compatibility issues) #2148 [Sam Stephenson] - -* Fixed JavascriptHelper#auto_complete_for to only include unique items #2153 [Thomas Fuchs] - -* Fixed all AssetHelper methods to work with relative paths, such that javascript_include_tag('stdlib/standard') will look in /javascripts/stdlib/standard instead of '/stdlib/standard/' #1963 - -* Avoid extending view instance with helper modules each request. Closes #1979 - -* Performance improvements to CGI methods. Closes #1980 [Stefan Kaes] - -* Added :post option to UrlHelper#link_to that makes it possible to do POST requests through normal ahref links using Javascript - -* Fixed overwrite_params - -* Added ActionController::Base.benchmark and ActionController::Base.silence to allow for easy benchmarking and turning off the log - -* Updated vendor copy of html-scanner to support better xml parsing - -* Added :popup option to UrlHelper#link_to #1996 [gabriel.gironda@gmail.com]. Examples: - - link_to "Help", { :action => "help" }, :popup => true - link_to "Busy loop", { :action => "busy" }, :popup => ['new_window', 'height=300,width=600'] - -* Drop trailing \000 if present on RAW_POST_DATA (works around bug in Safari Ajax implementation) #918 - -* Fix observe_field to fall back to event-based observation if frequency <= 0 #1916 [Michael Schubert] - -* Allow use of the :with option for submit_to_remote #1936 [jon@instance-design.co.uk] - -* AbstractRequest#domain returns nil when host is an ip address #2012 [Kevin Clark] - -* ActionController documentation update #2051 [François Beausoleil] - -* Yield @content_for_ variables to templates #2058 [Sam Stephenson] - -* Make rendering an empty partial collection behave like :nothing => true #2080 [Sam Stephenson] - -* Add option to specify the singular name used by pagination. - -* Use string key to obtain action value. Allows indifferent hashes to be disabled. - -* Added ActionView::Base.cache_template_loading back. - -* Rewrote compiled templates to decrease code complexity. Removed template load caching in favour of compiled caching. Fixed template error messages. [Nicholas Seckar] - -* Fix Routing to handle :some_param => nil better. [Nicholas Seckar, Luminas] - -* Add support for :include with pagination (subject to existing constraints for :include with :limit and :offset) #1478 [Michael Schubert] - -* Prevent the benchmark module from blowing up if a non-HTTP/1.1 request is processed - -* Added :use_short_month option to select_month helper to show month names as abbreviations - -* Make link_to escape the javascript in the confirm option #1964 [nicolas.pouillard@gmail.com] - -* Make assert_redirected_to properly check URL's passed as strings #1910 [Scott Barron] - -* Make sure :layout => false is always used when rendering inside a layout - -* Use raise instead of assert_not_nil in Test::Unit::TestCase#process to ensure that the test variables (controller, request, response) have been set - -* Make sure assigns are built for every request when testing #1866 - -* Allow remote_addr to be queried on TestRequest #1668 - -* Fixed bug when a partial render was passing a local with the same name as the partial - -* Improved performance of test app req/sec with ~10% refactoring the render method #1823 [Stefan Kaes] - -* Improved performance of test app req/sec with 5-30% through a series of Action Pack optimizations #1811 [Stefan Kaes] - -* Changed caching/expiration/hit to report using the DEBUG log level and errors to use the ERROR log level instead of both using INFO - -* Added support for per-action session management #1763 - -* Improved rendering speed on complicated templates by up to 100% (the more complex the templates, the higher the speedup) #1234 [Stefan Kaes]. This did necessasitate a change to the internals of ActionView#render_template that now has four parameters. Developers of custom view handlers (like Amrita) need to update for that. - -* Added options hash as third argument to FormHelper#input, so you can do input('person', 'zip', :size=>10) #1719 [jeremye@bsa.ca.gov] - -* Added Base#expires_in(seconds)/Base#expires_now to control HTTP content cache headers #1755 [Thomas Fuchs] - -* Fixed line number reporting for Builder template errors #1753 [piotr] - -* Fixed assert_routing so that testing controllers in modules works as expected [Nicholas Seckar, Rick Olson] - -* Fixed bug with :success/:failure callbacks for the JavaScriptHelper methods #1730 [court3nay/Thomas Fuchs] - -* Added named_route method to RouteSet instances so that RouteSet instance methods do not prevent certain names from being used. [Nicholas Seckar] - -* Fixed routes so that routes which do not specify :action in the path or in the requirements have a default of :action => 'index', In addition, fixed url generation so that :action => 'index' does not need to be provided for such urls. [Nicholas Seckar, Markjuh] - -* Worked around a Safari bug where it wouldn't pass headers through if the response was zero length by having render :nothing return ' ' instead of '' - -* Fixed Request#subdomains to handle "foo.foo.com" correctly - - -*1.9.1* (11 July, 2005) - -* Fixed that auto_complete_for didn't force the input string to lower case even as the db comparison was - -* Fixed that Action View should always use the included Builder, never attempt to require the gem, to ensure compatibility - -* Added that nil options are not included in tags, so tag("p", :ignore => nil) now returns

    not

    but that tag("p", :ignore => "") still includes it #1465 [Michael Schuerig] - -* Fixed that UrlHelper#link_to_unless/link_to_if used html_escape on the name if no link was to be applied. This is unnecessary and breaks its use with images #1649 [joergd@pobox.com] - -* Improved error message for DoubleRenderError - -* Fixed routing to allow for testing of *path components #1650 [Nicholas Seckar] - -* Added :handle as an option to sortable_element to restrict the drag handle to a given class #1642 [thejohnny] - -* Added a bunch of script.aculo.us features #1644, #1677, #1695 [Thomas Fuchs] - * Effect.ScrollTo, to smoothly scroll the page to an element - * Better Firefox flickering handling on SlideUp/SlideDown - * Removed a possible memory leak in IE with draggables - * Added support for cancelling dragging my hitting ESC - * Added capability to remove draggables/droppables and redeclare sortables in dragdrop.js (this makes it possible to call sortable_element on the same element more than once, e.g. in AJAX returns that modify the sortable element. all current sortable 'stuff' on the element will be discarded and the sortable will be rebuilt) - * Always reset background color on Effect.Highlight; this make change backwards-compatibility, to be sure include style="background-color:(target-color)" on your elements or else elements will fall back to their CSS rules (which is a good thing in most circumstances) - * Removed circular references from element to prevent memory leaks (still not completely gone in IE) - * Changes to class extension in effects.js - * Make Effect.Highlight restore any previously set background color when finishing (makes effect work with CSS classes that set a background color) - * Fixed myriads of memory leaks in IE and Gecko-based browsers [David Zülke] - * Added incremental and local autocompleting and loads of documentation to controls.js [Ivan Krstic] - * Extended the auto_complete_field helper to accept tokens option - * Changed object extension mechanism to favor Object.extend to make script.aculo.us easily adaptable to support 3rd party libs like IE7.js [David Zülke] - -* Fixed that named routes didn't use the default values for action and possible other parameters #1534 [Nicholas Seckar] - -* Fixed JavascriptHelper#visual_effect to use camelize such that :blind_up will work #1639 [pelletierm@eastmedia.net] - -* Fixed that a SessionRestoreError was thrown if a model object was placed in the session that wasn't available to all controllers. This means that it's no longer necessary to use the 'model :post' work-around in ApplicationController to have a Post model in your session. - - -*1.9.0* (6 July, 2005) - -* Added logging of the request URI in the benchmark statement (makes it easy to grep for slow actions) - -* Added javascript_include_tag :defaults shortcut that'll include all the default javascripts included with Action Pack (prototype, effects, controls, dragdrop) - -* Cache several controller variables that are expensive to calculate #1229 [Stefan Kaes] - -* The session class backing CGI::Session::ActiveRecordStore may be replaced with any class that duck-types with a subset of Active Record. See docs for details #1238 [Stefan Kaes] - -* Fixed that hashes was not working properly when passed by GET to lighttpd #849 [Nicholas Seckar] - -* Fixed assert_template nil will be true when no template was rendered #1565 [maceywj@telus.net] - -* Added :prompt option to FormOptions#select (and the users of it, like FormOptions#select_country etc) to create "Please select" style descriptors #1181 [Michael Schuerig] - -* Added JavascriptHelper#update_element_function, which returns a Javascript function (or expression) that'll update a DOM element according to the options passed #933 [mortonda@dgrmm.net]. Examples: - - <%= update_element_function("products", :action => :insert, :position => :bottom, :content => "

    New product!

    ") %> - - <% update_element_function("products", :action => :replace, :binding => binding) do %> -

    Product 1

    -

    Product 2

    - <% end %> - -* Added :field_name option to DateHelper#select_(year|month|day) to deviate from the year/month/day defaults #1266 [Marcel Molina Jr.] - -* Added JavascriptHelper#draggable_element and JavascriptHelper#drop_receiving_element to facilitate easy dragging and dropping through the script.aculo.us libraries #1578 [Thomas Fuchs] - -* Added that UrlHelper#mail_to will now also encode the default link title #749 [f.svehla@gmail.com] - -* Removed the default option of wrap=virtual on FormHelper#text_area to ensure XHTML compatibility #1300 [thomas@columbus.rr.com] - -* Adds the ability to include XML CDATA tags using Builder #1563 [Josh Knowles]. Example: - - xml.cdata! "some text" # => - -* Added evaluation of + + Which is needed for dealing with the IE6 DOM when it's not yet fully loaded. + +* Fixed that rescue template path shouldn't be hardcoded, then it's easier to hook in your own #6295 *Mike Naberezny* + +* Fixed escaping of backslashes in JavaScriptHelper#escape_javascript #6302 *sven@c3d2.de* + +* Fixed that some 500 rescues would cause 500's themselves because the response had not yet been generated #6329 *cmselmer* + +* respond_to :html doesn't assume .rhtml. #6281 *Hampton Catlin* + +* Fixed some deprecation warnings in ActionPack *Rick Olson* + +* assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. #6240 *japgolly* + +* Deprecation: @cookies, @headers, @request, @response will be removed after 1.2. Use the corresponding method instead. *Jeremy Kemper* + +* Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples: + + head :status => 404 # expands to "404 Not Found" + head :status => :not_found # expands to "404 Not Found" + head :status => :created # expands to "201 Created" + +* Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples: + + head :status => 404 # return an empty response with a 404 status + head :location => person_path(@person), :status => 201 + +* Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. *Rick Olson* + +* strip_links is case-insensitive. #6285 *tagoh, Bob Silva* + +* Clear the cache of possible controllers whenever Routes are reloaded. *Nicholas Seckar* + +* Filters overhaul including meantime filter support using around filters + blocks. #5949 *Martin Emde, Roman Le Negrate, Stefan Kaes, Jeremy Kemper* + +* Update RJS render tests. *sam* + +* Update CGI process to allow sessions to contain namespaced models. Closes #4638. *dfelstead@site5.com* + +* Fix routing to respect user provided requirements and defaults when assigning default routing options (such as :action => 'index'). Closes #5950. *Nicholas Seckar* + +* Rescue Errno::ECONNRESET to handle an unexpectedly closed socket connection. Improves SCGI reliability. #3368, #6226 *sdsykes, fhanshaw@vesaria.com* + +* Added that respond_to blocks will automatically set the content type to be the same as is requested [David Heinemeier Hansson]. Examples: + + respond_to do |format| + format.html { render :text => "I'm being sent as text/html" } + format.rss { render :text => "I'm being sent as application/rss+xml" } + format.atom { render :text => "I'm being sent as application/xml", :content_type => Mime::XML } + end + +* Added utf-8 as the default charset for all renders. You can change this default using ActionController::Base.default_charset=(encoding) *David Heinemeier Hansson* + +* Added proper getters and setters for content type and charset [David Heinemeier Hansson]. Example of what we used to do: + + response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" + + ...now: + + response.content_type = Mime::ATOM + response.charset = "utf-8" + +* Updated prototype.js to 1.5.0_rc1 with latest fixes. *Rick Olson* + + - XPATH support + - Make Form.getElements() return elements in the correct order + - fix broken Form.serialize return + +* Declare file extensions exempt from layouts. #6219 *brandon* + Example: ActionController::Base.exempt_from_layout 'rpdf' + +* Add chained replace/update support for assert_select_rjs *Rick Olson* + + Given RJS like... + + page['test1'].replace "
    foo
    " + page['test2'].replace_html "
    foo
    " + + Test it with... + + assert_select_rjs :chained_replace + assert_select_rjs :chained_replace, "test1" + + assert_select_rjs :chained_replace_html + assert_select_rjs :chained_replace_html, "test2" + +* Load helpers in alphabetical order for consistency. Resolve cyclic javascript_helper dependency. #6132, #6178 *choonkeat@gmail.com* + +* Skip params with empty names, such as the &=Save query string from . #2569 *Manfred Stienstra, raphinou@yahoo.com* + +* Fix assert_tag so that :content => "foo" does not match substrings, but only exact strings. Use :content => /foo/ to match substrings. #2799 *Eric Hodel* + +* Add descriptive messages to the exceptions thrown by cgi_methods. #6091, #6103 *Nicholas Seckar, Bob Silva* + +* Update JavaScriptGenerator#show/hide/toggle/remove to new Prototype syntax for multiple ids, #6068 *petermichaux@gmail.com* + +* Update UrlWriter to support :only_path. *Nicholas Seckar, Dave Thomas* + +* Fixed JavaScriptHelper#link_to_function and JavaScriptHelper#button_to_function to have the script argument be optional [David Heinemeier Hansson]. So what used to require a nil, like this: + + link_to("Hider", nil, :class => "hider_link") { |p| p[:something].hide } + + ...can be written like this: + + link_to("Hider", :class => "hider_link") { |p| p[:something].hide } + +* Update to script.aculo.us 1.6.3 *Thomas Fuchs* + +* Update to Prototype 1.5.0_rc1 *sam* + +* Added access to nested attributes in RJS #4548 [richcollins@gmail.com]. Examples: + + page['foo']['style'] # => $('foo').style; + page['foo']['style']['color'] # => $('blank_slate').style.color; + page['foo']['style']['color'] = 'red' # => $('blank_slate').style.color = 'red'; + page['foo']['style'].color = 'red' # => $('blank_slate').style.color = 'red'; + +* Fixed that AssetTagHelper#image_tag and others using compute_public_path should not modify the incoming source argument (closes #5102) *eule@space.ch* + +* Deprecated the auto-appending of .png to AssetTagHelper#image_tag calls that doesn't have an extension *David Heinemeier Hansson* + +* Fixed FormOptionsHelper#select to respect :selected value #5813 + +* Fixed TextHelper#simple_format to deal with multiple single returns within a single paragraph #5835 *moriq@moriq.com* + +* Fixed TextHelper#pluralize to handle 1 as a string #5909 *rails@bencurtis.com* + +* Improved resolution of DateHelper#distance_of_time_in_words for better precision #5994 *Bob Silva* + +* Changed that uncaught exceptions raised any where in the application will cause RAILS_ROOT/public/500.html to be read and shown instead of just the static "Application error (Rails)" *David Heinemeier Hansson* + +* Integration tests: thoroughly test ActionController::Integration::Session. #6022 *Kevin Clark* + (tests skipped unless you `gem install mocha`) + +* Added deprecation language for pagination which will become a plugin by Rails 2.0 *David Heinemeier Hansson* + +* Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 *David Heinemeier Hansson* + +* Deprecated all of ActionController::Dependencies. All dependency loading is now handled from Active Support *David Heinemeier Hansson* + +* Added assert_select* for CSS selector-based testing (deprecates assert_tag) #5936 *assaf.arkin@gmail.com* + +* radio_button_tag generates unique id attributes. #3353 *Bob Silva, somekool@gmail.com* + +* strip_tags passes through blank args such as nil or "". #2229, #6702 *duncan@whomwah.com, dharana* + +* Cleanup assert_tag :children counting. #2181 *jamie@bravenet.com* + +* button_to accepts :method so you can PUT and DELETE with it. #6005 *Dan Webb* + +* Update sanitize text helper to strip plaintext tags, and . *Rick Olson* + +* Update routing documentation. Closes #6017 *Nathan Witmer* + +* Add routing tests to assert that RoutingError is raised when conditions aren't met. Closes #6016 *Nathan Witmer* + +* Deprecation: update docs. #5998 *Jakob Skjerning, Kevin Clark* + +* Make auto_link parse a greater subset of valid url formats. *Jamis Buck* + +* Integration tests: headers beginning with X aren't excluded from the HTTP_ prefix, so X-Requested-With becomes HTTP_X_REQUESTED_WITH as expected. *Mike Clark* + +* Tighten rescue clauses. #5985 *james@grayproductions.net* + +* Fix send_data documentation typo. #5982 *brad@madriska.com* + +* Switch to using FormEncodedPairParser for parsing request parameters. *Nicholas Seckar, David Heinemeier Hansson* + +* respond_to .html now always renders #{action_name}.rhtml so that registered custom template handlers do not override it in priority. Custom mime types require a block and throw proper error now. *Tobias Lütke* + +* Deprecation: test deprecated instance vars in partials. *Jeremy Kemper* + +* Add UrlWriter to allow writing urls from Mailers and scripts. *Nicholas Seckar* + +* Clean up and run the Active Record integration tests by default. #5854 *Kevin Clark, Jeremy Kemper* + +* Correct example in cookies docs. #5832 *jessemerriman@warpmail.net* + +* Updated to script.aculo.us 1.6.2 *Thomas Fuchs* + +* Relax Routing's anchor pattern warning; it was preventing use of [^/] inside restrictions. *Nicholas Seckar* + +* Add controller_paths variable to Routing. *Nicholas Seckar* + +* Fix assert_redirected_to issue with named routes for module controllers. *Rick Olson* + +* Tweak RoutingError message to show option diffs, not just missing named route significant keys. *Rick Olson* + +* Invoke method_missing directly on hidden actions. Closes #3030. *Nicholas Seckar* + +* Require Tempfile explicitly for TestUploadedFile due to changes in class auto loading. *Rick Olson* + +* Add RoutingError exception when RouteSet fails to generate a path from a Named Route. *Rick Olson* + +* Replace Reloadable with Reloadable::Deprecated. *Nicholas Seckar* + +* Deprecation: check whether instance variables have been monkeyed with before assigning them to deprecation proxies. Raises a RuntimeError if so. *Jeremy Kemper* + +* Add support for the param_name parameter to the auto_complete_field helper. #5026 *david.a.williams@gmail.com* + +* Deprecation! @params, @session, @flash will be removed after 1.2. Use the corresponding instance methods instead. You'll get printed warnings during tests and logged warnings in dev mode when you access either instance variable directly. *Jeremy Kemper* + +* Make Routing noisy when an anchor regexp is assigned to a segment. #5674 *François Beausoleil* + +* Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" #5611 *pjhyett@gmail.com* + +* Short documentation to mention use of Mime::Type.register. #5710 *choonkeat@gmail.com* + +* Make controller_path available as an instance method. #5724 *jmckible@gmail.com* + +* Update query parser to support adjacent hashes. *Nicholas Seckar* + +* Make action caching aware of different formats for the same action so that, e.g. foo.xml is cached separately from foo.html. Implicitly set content type when reading in cached content with mime revealing extensions so the entire onous isn't on the webserver. *Marcel Molina Jr.* + +* Restrict Request Method hacking with ?_method to POST requests. *Rick Olson* + +* Fix bug when passing multiple options to SimplyRestful, like :new => { :preview => :get, :draft => :get }. *Rick Olson, Josh Susser, Lars Pind* + +* Dup the options passed to map.resources so that multiple resources get the same options. *Rick Olson* + +* Fixed the new_#{resource}_url route and added named route tests for Simply Restful. *Rick Olson* + +* Added map.resources from the Simply Restful plugin [David Heinemeier Hansson]. Examples (the API has changed to use plurals!): + + map.resources :messages + map.resources :messages, :comments + map.resources :messages, :new => { :preview => :post } + +* Fixed that integration simulation of XHRs should set Accept header as well *Edward Frederick* + +* TestRequest#reset_session should restore a TestSession, not a hash *Michael Koziarski* + +* Don't search a load-path of '.' for controller files *Jamis Buck* + +* Update integration.rb to require test_process explicitly instead of via Dependencies. *Nicholas Seckar* + +* Fixed that you can still access the flash after the flash has been reset in reset_session. Closes #5584 *lmarlow* + +* Allow form_for and fields_for to work with indexed form inputs. *Jeremy Kemper, Matt Lyon* + + <% form_for 'post[]', @post do |f| -%> + <% end -%> + +* Remove leak in development mode by replacing define_method with module_eval. *Nicholas Seckar* + +* Provide support for decimal columns to form helpers. Closes #5672. *Dave Thomas* + +* Update documentation for erb trim syntax. #5651 *matt@mattmargolis.net* + +* Pass :id => nil or :class => nil to error_messages_for to supress that html attribute. #3586 *olivier_ansaldi@yahoo.com* + +* Reset @html_document between requests so assert_tag works. #4810 *Jarkko Laine, easleydp@gmail.com* + +* Update render :partial documentation. #5646 *matt@mattmargolis.net* + +* Integration tests behave well with render_component. #4632 *edward.frederick@revolution.com, dev.rubyonrails@maxdunn.com* + +* Added exception handling of missing layouts #5373 *chris@ozmm.org* + +* Fixed that real files and symlinks should be treated the same when compiling templates #5438 *zachary@panandscan.com* + +* Fixed that the flash should be reset when reset_session is called #5584 *Shugo Maeda* + +* Added special case for "1 Byte" in NumberHelper#number_to_human_size #5593 *murpyh@rubychan.de* + +* Fixed proper form-encoded parameter parsing for requests with "Content-Type: application/x-www-form-urlencoded; charset=utf-8" (note the presence of a charset directive) *David Heinemeier Hansson* + +* Add route_name_path method to generate only the path for a named routes. For example, map.person will add person_path. *Nicholas Seckar* + +* Avoid naming collision among compiled view methods. *Jeremy Kemper* + +* Fix CGI extensions when they expect string but get nil in Windows. Closes #5276 *Mislav Marohnić* + +* Determine the correct template_root for deeply nested components. #2841 *s.brink@web.de* + +* Fix that routes with *path segments in the recall can generate URLs. *Rick Olson* + +* Fix strip_links so that it doesn't hang on multiline tags *Jamis Buck* + +* Remove problematic control chars in rescue template. #5316 *Stefan Kaes* + +* Make sure passed routing options are not mutated by routing code. #5314 *Blair Zajac* + +* Make sure changing the controller from foo/bar to bing/bang does not change relative to foo. *Jamis Buck* + +* Escape the path before routing recognition. #3671 + +* Make sure :id and friends are unescaped properly. #5275 *me@julik.nl* + +* Fix documentation for with_routing to reflect new reality. #5281 *rramdas@gmail.com* + +* Rewind readable CGI params so others may reread them (such as CGI::Session when passing the session id in a multipart form). #210 *mklame@atxeu.com, matthew@walker.wattle.id.au* + +* Added Mime::TEXT (text/plain) and Mime::ICS (text/calendar) as new default types *David Heinemeier Hansson* + +* Added Mime::Type.register(string, symbol, synonyms = []) for adding new custom mime types [David Heinemeier Hansson]. Example: Mime::Type.register("image/gif", :gif) + +* Added support for Mime objects in render :content_type option [David Heinemeier Hansson]. Example: render :text => some_atom, :content_type => Mime::ATOM + +* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 *Manfred Stienstra * + +* Routing rewrite. Simpler, faster, easier to understand. The published API for config/routes.rb is unchanged, but nearly everything else is different, so expect breakage in plugins and libs that try to fiddle with routes. *Nicholas Seckar, Jamis Buck* + + map.connect '/foo/:id', :controller => '...', :action => '...' + map.connect '/foo/:id.:format', :controller => '...', :action => '...' + map.connect '/foo/:id', ..., :conditions => { :method => :get } + +* Cope with missing content type and length headers. Parse parameters from multipart and urlencoded request bodies only. *Jeremy Kemper* + +* Accept multipart PUT parameters. #5235 *guy.naor@famundo.com* + +* Added interrogation of params[:format] to determine Accept type. If :format is specified and matches a declared extension, like "rss" or "xml", that mime type will be put in front of the accept handler. This means you can link to the same action from different extensions and use that fact to determine output [David Heinemeier Hansson]. Example: + + class WeblogController < ActionController::Base + def index + @posts = Post.find :all + + respond_to do |format| + format.html + format.xml { render :xml => @posts.to_xml } + format.rss { render :action => "feed.rxml" } + end + end + end + + \# returns HTML when requested by a browser, since the browser + \# has the HTML mimetype at the top of its priority list + Accept: text/html + GET /weblog + + \# returns the XML + Accept: application/xml + GET /weblog + + \# returns the HTML + Accept: application/xml + GET /weblog.html + + \# returns the XML + Accept: text/html + GET /weblog.xml + + All this relies on the fact that you have a route that includes .:format. + +* Expanded :method option in FormTagHelper#form_tag, FormHelper#form_for, PrototypeHelper#remote_form_for, PrototypeHelper#remote_form_tag, and PrototypeHelper#link_to_remote to allow for verbs other than GET and POST by automatically creating a hidden form field named _method, which will simulate the other verbs over post *David Heinemeier Hansson* + +* Added :method option to UrlHelper#link_to, which allows for using other verbs than GET for the link. This replaces the :post option, which is now deprecated. Example: link_to "Destroy", person_url(:id => person), :method => :delete *David Heinemeier Hansson* + +* follow_redirect doesn't complain about being redirected to the same controller. #5153 *dymo@mk.ukrtelecom.ua* + +* Add layout attribute to response object with the name of the layout that was rendered, or nil if none rendered. *Kevin Clark* + +* Fix NoMethodError when parsing params like &&. *Adam Greenfield* + +* Fix flip flopped logic in docs for url_for's :only_path option. Closes #4998. *esad@esse.at* + +* form.text_area handles the :size option just like the original text_area (:size => '60x10' becomes cols="60" rows="10"). *Jeremy Kemper* + +* Excise ingrown code from FormOptionsHelper#options_for_select. #5008 *anonymous* + +* Small fix in routing to allow dynamic routes (broken after [4242]) *Rick Olson* + + map.connect '*path', :controller => 'files', :action => 'show' + +* Replace alias method chaining with Module#alias_method_chain. *Marcel Molina Jr.* + +* Replace Ruby's deprecated append_features in favor of included. *Marcel Molina Jr.* + +* Use #flush between switching from #write to #syswrite. Closes #4907. *Blair Zajac * + +* Documentation fix: integration test scripts don't require integration_test. Closes #4914. *Frederick Ros * + +* ActionController::Base Summary documentation rewrite. Closes #4900. *Kevin Clark* + +* Fix text_helper.rb documentation rendering. Closes #4725. *Frederick Ros* + +* Fixes bad rendering of JavaScriptMacrosHelper rdoc (closes #4910) *Frederick Ros* + +* Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes #4186. *andrew@redlinesoftware.com, Marcel Molina Jr.* + + error_messages_for :account, :user, :subscription, :object_name => :account + +* Enhance documentation for setting headers in integration tests. Skip auto HTTP prepending when its already there. Closes #4079. *Rick Olson* + +* Documentation for AbstractRequest. Closes #4895. *Kevin Clark* + +* Refactor various InstanceTag instance method to class methods. Closes #4800. *Stefan Kaes* + +* Remove all remaining references to @params in the documentation. *Marcel Molina Jr.* + +* Add documentation for redirect_to :back's RedirectBackError exception. *Marcel Molina Jr.* + +* Update layout and content_for documentation to use yield rather than magic @content_for instance variables. *Marcel Molina Jr.* + +* Fix assert_redirected_to tests according to real-world usage. Also, don't fail if you add an extra :controller option: *Rick Olson* + + redirect_to :action => 'new' + assert_redirected_to :controller => 'monkeys', :action => 'new' + +* Cache CgiRequest#request_parameters so that multiple calls don't re-parse multipart data. *Rick Olson* + +* Diff compared routing options. Allow #assert_recognizes to take a second arg as a hash to specify optional request method *Rick Olson* + + assert_recognizes({:controller => 'users', :action => 'index'}, 'users') + assert_recognizes({:controller => 'users', :action => 'create'}, {:path => 'users', :method => :post}) + +* Diff compared options with #assert_redirected_to *Rick Olson* + +* Add support in routes for semicolon delimited "subpaths", like /books/:id;:action *Jamis Buck* + +* Change link_to_function and button_to_function to (optionally) take an update_page block instead of a JavaScript string. Closes #4804. *zraii@comcast.net, Sam Stephenson* + +* Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for *David Heinemeier Hansson* + +* Modify routing so that you can say :require => { :method => :post } for a route, and the route will never be selected unless the request method is POST. Only works for route recognition, not for route generation. *Jamis Buck* + +* Added :add_headers option to verify which merges a hash of name/value pairs into the response's headers hash if the prerequisites cannot be satisfied. *Sam Stephenson* + ex. verify :only => :speak, :method => :post, + :render => { :status => 405, :text => "Must be post" }, + :add_headers => { "Allow" => "POST" } + +* Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled #1897 *jeremye@bsa.ca.gov* + + +## 1.13.3 (March 12th, 2007) ## + +* Apply [5709] to stable. + +* session_enabled? works with session :off. #6680 *Jonathan del Strother* + +* Performance: patch cgi/session to require digest/md5 once rather than per #create_new_id. *Stefan Kaes* + + +## 1.13.2 (February 5th, 2007) ## + +* Add much-needed html-scanner tests. Fixed CDATA parsing bug. *Rick Olson* + +* improve error message for Routing for named routes. *Rob Sanheim* + +* Added enhanced docs to routing assertions. *Rob Sanheim* + +* fix form_for example in ActionController::Resources documentation. *gnarg* + +* Add singleton resources from trunk *Rick Olson* + +* select :multiple => true suffixes the attribute name with [] unless already suffixed. #6977 *nik.kakelin, ben, julik* + +* Improve routes documentation. #7095 *zackchandler* + +* Resource member routes require :id, eliminating the ambiguous overlap with collection routes. #7229 *dkubb* + +* Fixed NumberHelper#number_with_delimiter to use "." always for splitting the original number, not the delimiter parameter #7389 *ceefour* + +* Autolinking recognizes trailing and embedded . , : ; #7354 *Jarkko Laine* + +* Make TextHelper::auto_link recognize URLs with colons in path correctly, fixes #7268. *imajes* + +* Improved auto_link to match more valid urls correctly *Tobias Lütke* + + +## 1.13.1 (January 18th, 2007) ## + +* Fixed content-type bug in Prototype *sam* + + +## 1.13.0 (January 16th, 2007) ## + +* Modernize cookie testing code, and increase coverage (Heckle++) #7101 *Kevin Clark* + +* Heckling ActionController::Resources::Resource revealed that set_prefixes didn't break when :name_prefix was munged. #7081 *Kevin Clark* + +* Update to Prototype 1.5.0. *Sam Stephenson* + +* Allow exempt_from_layout :rhtml. #6742, #7026 *Dan Manges, Squeegy* + +* Fix parsing of array[] CGI parameters so extra empty values aren't included. #6252 *Nicholas Seckar, aiwilliams, brentrowland* + +* link_to_unless_current works with full URLs as well as paths. #6891 *Jarkko Laine, Manfred Stienstra, idrifter* + +* Fix HTML::Node to output double quotes instead of single quotes. Closes #6845 *mitreandy* + +* Fix no method error with error_messages_on. Closes #6935 *nik.wakelin Koz* + +* Slight doc tweak to the ActionView::Helpers::PrototypeHelper#replace docs. Closes #6922 *Steven Bristol* + +* Slight doc tweak to #prepend_filter. Closes #6493 *Jeremy Voorhis* + +* Add more extensive documentation to the AssetTagHelper. Closes #6452 *Bob Silva* + +* Clean up multiple calls to #stringify_keys in TagHelper, add better documentation and testing for TagHelper. Closes #6394 *Bob Silva* + +* [DOCS] fix reference to ActionController::Macros::AutoComplete for #text_field_with_auto_complete. Closes #2578 *Jan Prill* + +* Make sure html_document is reset between integration test requests. *ctm* + +* Set session to an empty hash if :new_session => false and no session cookie or param is present. CGI::Session was raising an unrescued ArgumentError. *Josh Susser* + +* Fix assert_redirected_to bug where redirecting from a nested to to a top-level controller incorrectly added the current controller's nesting. Closes #6128. *Rick Olson* + +* Ensure render :json => ... skips the layout. #6808 *Josh Peek* + +* Silence log_error deprecation warnings from inspecting deprecated instance variables. *Nate Wiger* + +* Only cache GET requests with a 200 OK response. #6514, #6743 *RSL, anamba* + +* Correctly report which filter halted the chain. #6699 *Martin Emde* + +* respond_to recognizes JSON. render :json => @person.to_json automatically sets the content type and takes a :callback option to specify a client-side function to call using the rendered JSON as an argument. #4185 *Scott Raymond, eventualbuddha* + # application/json response with body 'Element.show({:name: "David"})' + respond_to do |format| + format.json { render :json => { :name => "David" }.to_json, :callback => 'Element.show' } + end + +* Makes :discard_year work without breaking multi-attribute parsing in AR. #1260, #3800 *sean@ardismg.com, jmartin@desertflood.com, stephen@touset.org, Bob Silva* + +* Adds html id attribute to date helper elements. #1050, #1382 *mortonda@dgrmm.net, David North, Bob Silva* + +* Add :index and @auto_index capability to model driven date/time selects. #847, #2655 *moriq, Doug Fales, Bob Silva* + +* Add :order to datetime_select, select_datetime, and select_date. #1427 *Timothee Peignier, Patrick Lenz, Bob Silva* + +* Added time_select to work with time values in models. Update scaffolding. #2489, #2833 *Justin Palmer, Andre Caum, Bob Silva* + +* Added :include_seconds to select_datetime, datetime_select and time_select. #2998 *csn, Bob Silva* + +* All date/datetime selects can now accept an array of month names with :use_month_names. Allows for localization. #363 *tomasj, Bob Silva* + +* Adds :time_separator to select_time and :date_separator to select_datetime. Preserves BC. #3811 *Bob Silva* + +* @response.redirect_url works with 201 Created responses: just return headers['Location'] rather than checking the response status. *Jeremy Kemper* + +* Fixed that HEAD should return the proper Content-Length header (that is, actually use @body.size, not just 0) *David Heinemeier Hansson* + +* Added GET-masquarading for HEAD, so request.method will return :get even for HEADs. This will help anyone relying on case request.method to automatically work with HEAD and map.resources will also allow HEADs to all GET actions. Rails automatically throws away the response content in a reply to HEAD, so you don't even need to worry about that. If you, for whatever reason, still need to distinguish between GET and HEAD in some edge case, you can use Request#head? and even Request.headers["REQUEST_METHOD"] for get the "real" answer. Closes #6694 *David Heinemeier Hansson* + + +## 1.13.0 RC1 (r5619, November 22nd, 2006) ## + +* Update Routing to complain when :controller is not specified by a route. Closes #6669. *Nicholas Seckar* + +* Ensure render_to_string cleans up after itself when an exception is raised. #6658 *rsanheim* + +* Update to Prototype and script.aculo.us [5579]. *Sam Stephenson, Thomas Fuchs* + +* simple_format helper doesn't choke on nil. #6644 *jerry426* + +* Reuse named route helper module between Routing reloads. Use remove_method to delete named route methods after each load. Since the module is never collected, this fixes a significant memory leak. *Nicholas Seckar* + +* Deprecate standalone components. *Jeremy Kemper* + +* Always clear model associations from session. #4795 *sd@notso.net, andylien@gmail.com* + +* Remove JavaScriptLiteral in favor of ActiveSupport::JSON::Variable. *Sam Stephenson* + +* Sync ActionController::StatusCodes::STATUS_CODES with http://www.iana.org/assignments/http-status-codes. #6586 *dkubb* + +* Multipart form values may have a content type without being treated as uploaded files if they do not provide a filename. #6401 *Andreas Schwarz, Jeremy Kemper* + +* assert_response supports symbolic status codes. #6569 *Kevin Clark* + assert_response :ok + assert_response :not_found + assert_response :forbidden + +* Cache parsed query parameters. #6559 *Stefan Kaes* + +* Deprecate JavaScriptHelper#update_element_function, which is superseeded by RJS *Thomas Fuchs* + +* Fix invalid test fixture exposed by stricter Ruby 1.8.5 multipart parsing. #6524 *Bob Silva* + +* Set ActionView::Base.default_form_builder once rather than passing the :builder option to every form or overriding the form helper methods. *Jeremy Kemper* + +* Deprecate expire_matched_fragments. Use expire_fragment instead. #6535 *Bob Silva* + +* Deprecate start_form_tag and end_form_tag. Use form_tag / '' from now on. *Rick Olson* + +* Added block-usage to PrototypeHelper#form_remote_tag, document block-usage of FormTagHelper#form_tag *Rick Olson* + +* Add a 0 margin/padding div around the hidden _method input tag that form_tag outputs. *Rick Olson* + +* Added block-usage to TagHelper#content_tag [David Heinemeier Hansson]. Example: + + <% content_tag :div, :class => "strong" %> + Hello world! + <% end %> + + Will output: +
    Hello world!
    + +* Deprecated UrlHelper#link_to_image and UrlHelper#link_to :post => true #6409 *Bob Silva* + +* Upgraded NumberHelper with number_to_phone support international formats to comply with ITU E.123 by supporting area codes with less than 3 digits, added precision argument to number_to_human_size (defaults to 1) #6421 *Bob Silva* + +* Fixed that setting RAILS_ASSET_ID to "" should not add a trailing slash after assets #6454 *Bob Silva/chrismear* + +* Force *_url named routes to show the host in ActionView *Rick Olson* + + <%= url_for ... %> # no host + <%= foo_path %> # no host + <%= foo_url %> # host! + +* Add support for converting blocks into function arguments to JavaScriptGenerator#call and JavaScriptProxy#call. *Sam Stephenson* + +* Add JavaScriptGenerator#literal for wrapping a string in an object whose #to_json is the string itself. *Sam Stephenson* + +* Add <%= escape_once html %> to escape html while leaving any currently escaped entities alone. Fix button_to double-escaping issue. *Rick Olson* + +* Fix double-escaped entities, such as &amp;, &#123;, etc. *Rick Olson* + +* Fix routing to correctly determine when generation fails. Closes #6300. [psross]. + +* Fix broken assert_generates when extra keys are being checked. *Jamis Buck* + +* Replace KCODE checks with String#chars for truncate. Closes #6385 *Manfred Stienstra* + +* Make page caching respect the format of the resource that is being requested even if the current route is the default route so that, e.g. posts.rss is not transformed by url_for to '/' and subsequently cached as '/index.html' when it should be cached as '/posts.rss'. *Marcel Molina Jr.* + +* Use String#chars in TextHelper::excerpt. Closes #6386 *Manfred Stienstra* + +* Fix relative URL root matching problems. *Mark Imbriaco* + +* Fix filter skipping in controller subclasses. #5949, #6297, #6299 *Martin Emde* + +* render_text may optionally append to the response body. render_javascript appends by default. This allows you to chain multiple render :update calls by setting @performed_render = false between them (awaiting a better public API). *Jeremy Kemper* + +* Rename test assertion to prevent shadowing. Closes #6306. *psross* + +* Fixed that NumberHelper#number_to_delimiter should respect precision of higher than two digits #6231 *Philip Hallstrom* + +* Fixed that FormHelper#radio_button didn't respect an :id being passed in #6266 *evansj* + +* Added an html_options hash parameter to javascript_tag() and update_page_tag() helpers #6311 [tzaharia]. Example: + + update_page_tag :defer => 'true' { |page| ... } + + Gives: + + + + Which is needed for dealing with the IE6 DOM when it's not yet fully loaded. + +* Fixed that rescue template path shouldn't be hardcoded, then it's easier to hook in your own #6295 *Mike Naberezny* + +* Fixed escaping of backslashes in JavaScriptHelper#escape_javascript #6302 *sven@c3d2.de* + +* Fixed that some 500 rescues would cause 500's themselves because the response had not yet been generated #6329 *cmselmer* + +* respond_to :html doesn't assume .rhtml. #6281 *Hampton Catlin* + +* Fixed some deprecation warnings in ActionPack *Rick Olson* + +* assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. #6240 *japgolly* + +* Deprecation: @cookies, @headers, @request, @response will be removed after 1.2. Use the corresponding method instead. *Jeremy Kemper* + +* Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples: + + head :status => 404 # expands to "404 Not Found" + head :status => :not_found # expands to "404 Not Found" + head :status => :created # expands to "201 Created" + +* Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples: + + head :status => 404 # return an empty response with a 404 status + head :location => person_path(@person), :status => 201 + +* Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. *Rick Olson* + +* strip_links is case-insensitive. #6285 *tagoh, Bob Silva* + +* Clear the cache of possible controllers whenever Routes are reloaded. *Nicholas Seckar* + +* Filters overhaul including meantime filter support using around filters + blocks. #5949 *Martin Emde, Roman Le Negrate, Stefan Kaes, Jeremy Kemper* + +* Update CGI process to allow sessions to contain namespaced models. Closes #4638. *dfelstead@site5.com* + +* Fix routing to respect user provided requirements and defaults when assigning default routing options (such as :action => 'index'). Closes #5950. *Nicholas Seckar* + +* Rescue Errno::ECONNRESET to handle an unexpectedly closed socket connection. Improves SCGI reliability. #3368, #6226 *sdsykes, fhanshaw@vesaria.com* + +* Added that respond_to blocks will automatically set the content type to be the same as is requested [David Heinemeier Hansson]. Examples: + + respond_to do |format| + format.html { render :text => "I'm being sent as text/html" } + format.rss { render :text => "I'm being sent as application/rss+xml" } + format.atom { render :text => "I'm being sent as application/xml", :content_type => Mime::XML } + end + +* Added utf-8 as the default charset for all renders. You can change this default using ActionController::Base.default_charset=(encoding) *David Heinemeier Hansson* + +* Added proper getters and setters for content type and charset [David Heinemeier Hansson]. Example of what we used to do: + + response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" + + ...now: + + response.content_type = Mime::ATOM + response.charset = "utf-8" + +* Declare file extensions exempt from layouts. #6219 *brandon* + Example: ActionController::Base.exempt_from_layout 'rpdf' + +* Add chained replace/update support for assert_select_rjs *Rick Olson* + + Given RJS like... + + page['test1'].replace "
    foo
    " + page['test2'].replace_html "
    foo
    " + + Test it with... + + assert_select_rjs :chained_replace + assert_select_rjs :chained_replace, "test1" + + assert_select_rjs :chained_replace_html + assert_select_rjs :chained_replace_html, "test2" + +* Load helpers in alphabetical order for consistency. Resolve cyclic javascript_helper dependency. #6132, #6178 *choonkeat@gmail.com* + +* Skip params with empty names, such as the &=Save query string from . #2569 *Manfred Stienstra, raphinou@yahoo.com* + +* Fix assert_tag so that :content => "foo" does not match substrings, but only exact strings. Use :content => /foo/ to match substrings. #2799 *Eric Hodel* + +* Update JavaScriptGenerator#show/hide/toggle/remove to new Prototype syntax for multiple ids, #6068 *petermichaux@gmail.com* + +* Update UrlWriter to support :only_path. *Nicholas Seckar, Dave Thomas* + +* Fixed JavaScriptHelper#link_to_function and JavaScriptHelper#button_to_function to have the script argument be optional [David Heinemeier Hansson]. So what used to require a nil, like this: + + link_to("Hider", nil, :class => "hider_link") { |p| p[:something].hide } + + ...can be written like this: + + link_to("Hider", :class => "hider_link") { |p| p[:something].hide } + +* Added access to nested attributes in RJS #4548 [richcollins@gmail.com]. Examples: + + page['foo']['style'] # => $('foo').style; + page['foo']['style']['color'] # => $('blank_slate').style.color; + page['foo']['style']['color'] = 'red' # => $('blank_slate').style.color = 'red'; + page['foo']['style'].color = 'red' # => $('blank_slate').style.color = 'red'; + +* Fixed that AssetTagHelper#image_tag and others using compute_public_path should not modify the incoming source argument (closes #5102) *eule@space.ch* + +* Deprecated the auto-appending of .png to AssetTagHelper#image_tag calls that doesn't have an extension *David Heinemeier Hansson* + +* Fixed FormOptionsHelper#select to respect :selected value #5813 + +* Fixed TextHelper#simple_format to deal with multiple single returns within a single paragraph #5835 *moriq@moriq.com* + +* Fixed TextHelper#pluralize to handle 1 as a string #5909 *rails@bencurtis.com* + +* Improved resolution of DateHelper#distance_of_time_in_words for better precision #5994 *Bob Silva* + +* Changed that uncaught exceptions raised any where in the application will cause RAILS_ROOT/public/500.html to be read and shown instead of just the static "Application error (Rails)" *David Heinemeier Hansson* + +* Added deprecation language for pagination which will become a plugin by Rails 2.0 *David Heinemeier Hansson* + +* Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 *David Heinemeier Hansson* + +* Deprecated all of ActionController::Dependencies. All dependency loading is now handled from Active Support *David Heinemeier Hansson* + +* Added assert_select* for CSS selector-based testing (deprecates assert_tag) #5936 *assaf.arkin@gmail.com* + +* radio_button_tag generates unique id attributes. #3353 *Bob Silva, somekool@gmail.com* + +* strip_tags passes through blank args such as nil or "". #2229, #6702 *duncan@whomwah.com, dharana* + +* Cleanup assert_tag :children counting. #2181 *jamie@bravenet.com* + +* button_to accepts :method so you can PUT and DELETE with it. #6005 *Dan Webb* + +* Update sanitize text helper to strip plaintext tags, and . *Rick Olson* + +* Add routing tests to assert that RoutingError is raised when conditions aren't met. Closes #6016 *Nathan Witmer* + +* Make auto_link parse a greater subset of valid url formats. *Jamis Buck* + +* Integration tests: headers beginning with X aren't excluded from the HTTP_ prefix, so X-Requested-With becomes HTTP_X_REQUESTED_WITH as expected. *Mike Clark* + +* Switch to using FormEncodedPairParser for parsing request parameters. *Nicholas Seckar, David Heinemeier Hansson* + +* respond_to .html now always renders #{action_name}.rhtml so that registered custom template handlers do not override it in priority. Custom mime types require a block and throw proper error now. *Tobias Lütke* + +* Deprecation: test deprecated instance vars in partials. *Jeremy Kemper* + +* Add UrlWriter to allow writing urls from Mailers and scripts. *Nicholas Seckar* + +* Relax Routing's anchor pattern warning; it was preventing use of [^/] inside restrictions. *Nicholas Seckar* + +* Add controller_paths variable to Routing. *Nicholas Seckar* + +* Fix assert_redirected_to issue with named routes for module controllers. *Rick Olson* + +* Tweak RoutingError message to show option diffs, not just missing named route significant keys. *Rick Olson* + +* Invoke method_missing directly on hidden actions. Closes #3030. *Nicholas Seckar* + +* Add RoutingError exception when RouteSet fails to generate a path from a Named Route. *Rick Olson* + +* Replace Reloadable with Reloadable::Deprecated. *Nicholas Seckar* + +* Deprecation: check whether instance variables have been monkeyed with before assigning them to deprecation proxies. Raises a RuntimeError if so. *Jeremy Kemper* + +* Add support for the param_name parameter to the auto_complete_field helper. #5026 *david.a.williams@gmail.com* + +* Deprecation! @params, @session, @flash will be removed after 1.2. Use the corresponding instance methods instead. You'll get printed warnings during tests and logged warnings in dev mode when you access either instance variable directly. *Jeremy Kemper* + +* Make Routing noisy when an anchor regexp is assigned to a segment. #5674 *François Beausoleil* + +* Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" #5611 *pjhyett@gmail.com* + +* Make controller_path available as an instance method. #5724 *jmckible@gmail.com* + +* Update query parser to support adjacent hashes. *Nicholas Seckar* + +* Make action caching aware of different formats for the same action so that, e.g. foo.xml is cached separately from foo.html. Implicitly set content type when reading in cached content with mime revealing extensions so the entire onous isn't on the webserver. *Marcel Molina Jr.* + +* Restrict Request Method hacking with ?_method to POST requests. *Rick Olson* + +* Fixed the new_#{resource}_url route and added named route tests for Simply Restful. *Rick Olson* + +* Added map.resources from the Simply Restful plugin [David Heinemeier Hansson]. Examples (the API has changed to use plurals!): + + map.resources :messages + map.resources :messages, :comments + map.resources :messages, :new => { :preview => :post } + +* Fixed that integration simulation of XHRs should set Accept header as well *Edward Frederick* + +* TestRequest#reset_session should restore a TestSession, not a hash *Michael Koziarski* + +* Don't search a load-path of '.' for controller files *Jamis Buck* + +* Update integration.rb to require test_process explicitly instead of via Dependencies. *Nicholas Seckar* + +* Fixed that you can still access the flash after the flash has been reset in reset_session. Closes #5584 *lmarlow* + +* Allow form_for and fields_for to work with indexed form inputs. *Jeremy Kemper, Matt Lyon* + + <% form_for 'post[]', @post do |f| -%> + <% end -%> + +* Remove leak in development mode by replacing define_method with module_eval. *Nicholas Seckar* + +* Provide support for decimal columns to form helpers. Closes #5672. *Dave Thomas* + +* Pass :id => nil or :class => nil to error_messages_for to supress that html attribute. #3586 *olivier_ansaldi@yahoo.com* + +* Reset @html_document between requests so assert_tag works. #4810 *Jarkko Laine, easleydp@gmail.com* + +* Integration tests behave well with render_component. #4632 *edward.frederick@revolution.com, dev.rubyonrails@maxdunn.com* + +* Added exception handling of missing layouts #5373 *chris@ozmm.org* + +* Fixed that real files and symlinks should be treated the same when compiling templates #5438 *zachary@panandscan.com* + +* Fixed that the flash should be reset when reset_session is called #5584 *Shugo Maeda* + +* Added special case for "1 Byte" in NumberHelper#number_to_human_size #5593 *murpyh@rubychan.de* + +* Fixed proper form-encoded parameter parsing for requests with "Content-Type: application/x-www-form-urlencoded; charset=utf-8" (note the presence of a charset directive) *David Heinemeier Hansson* + +* Add route_name_path method to generate only the path for a named routes. For example, map.person will add person_path. *Nicholas Seckar* + +* Avoid naming collision among compiled view methods. *Jeremy Kemper* + +* Fix CGI extensions when they expect string but get nil in Windows. Closes #5276 *Mislav Marohnić* + +* Determine the correct template_root for deeply nested components. #2841 *s.brink@web.de* + +* Fix that routes with *path segments in the recall can generate URLs. *Rick Olson* + +* Fix strip_links so that it doesn't hang on multiline tags *Jamis Buck* + +* Remove problematic control chars in rescue template. #5316 *Stefan Kaes* + +* Make sure passed routing options are not mutated by routing code. #5314 *Blair Zajac* + +* Make sure changing the controller from foo/bar to bing/bang does not change relative to foo. *Jamis Buck* + +* Escape the path before routing recognition. #3671 + +* Make sure :id and friends are unescaped properly. #5275 *me@julik.nl* + +* Rewind readable CGI params so others may reread them (such as CGI::Session when passing the session id in a multipart form). #210 *mklame@atxeu.com, matthew@walker.wattle.id.au* + +* Added Mime::TEXT (text/plain) and Mime::ICS (text/calendar) as new default types *David Heinemeier Hansson* + +* Added Mime::Type.register(string, symbol, synonyms = []) for adding new custom mime types [David Heinemeier Hansson]. Example: Mime::Type.register("image/gif", :gif) + +* Added support for Mime objects in render :content_type option [David Heinemeier Hansson]. Example: render :text => some_atom, :content_type => Mime::ATOM + +* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 *Manfred Stienstra * + +* Routing rewrite. Simpler, faster, easier to understand. The published API for config/routes.rb is unchanged, but nearly everything else is different, so expect breakage in plugins and libs that try to fiddle with routes. *Nicholas Seckar, Jamis Buck* + + map.connect '/foo/:id', :controller => '...', :action => '...' + map.connect '/foo/:id.:format', :controller => '...', :action => '...' + map.connect '/foo/:id', ..., :conditions => { :method => :get } + +* Cope with missing content type and length headers. Parse parameters from multipart and urlencoded request bodies only. *Jeremy Kemper* + +* Accept multipart PUT parameters. #5235 *guy.naor@famundo.com* + +* Added interrogation of params[:format] to determine Accept type. If :format is specified and matches a declared extension, like "rss" or "xml", that mime type will be put in front of the accept handler. This means you can link to the same action from different extensions and use that fact to determine output [David Heinemeier Hansson]. Example: + + class WeblogController < ActionController::Base + def index + @posts = Post.find :all + + respond_to do |format| + format.html + format.xml { render :xml => @posts.to_xml } + format.rss { render :action => "feed.rxml" } + end + end + end + + \# returns HTML when requested by a browser, since the browser + \# has the HTML mimetype at the top of its priority list + Accept: text/html + GET /weblog + + \# returns the XML + Accept: application/xml + GET /weblog + + \# returns the HTML + Accept: application/xml + GET /weblog.html + + \# returns the XML + Accept: text/html + GET /weblog.xml + + All this relies on the fact that you have a route that includes .:format. + +* Expanded :method option in FormTagHelper#form_tag, FormHelper#form_for, PrototypeHelper#remote_form_for, PrototypeHelper#remote_form_tag, and PrototypeHelper#link_to_remote to allow for verbs other than GET and POST by automatically creating a hidden form field named _method, which will simulate the other verbs over post *David Heinemeier Hansson* + +* Added :method option to UrlHelper#link_to, which allows for using other verbs than GET for the link. This replaces the :post option, which is now deprecated. Example: link_to "Destroy", person_url(:id => person), :method => :delete *David Heinemeier Hansson* + +* follow_redirect doesn't complain about being redirected to the same controller. #5153 *dymo@mk.ukrtelecom.ua* + +* Add layout attribute to response object with the name of the layout that was rendered, or nil if none rendered. *Kevin Clark* + +* Fix NoMethodError when parsing params like &&. *Adam Greenfield* + +* form.text_area handles the :size option just like the original text_area (:size => '60x10' becomes cols="60" rows="10"). *Jeremy Kemper* + +* Excise ingrown code from FormOptionsHelper#options_for_select. #5008 *anonymous* + +* Small fix in routing to allow dynamic routes (broken after [4242]) *Rick Olson* + + map.connect '*path', :controller => 'files', :action => 'show' + +* Use #flush between switching from #write to #syswrite. Closes #4907. *Blair Zajac * + +* Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes #4186. *andrew@redlinesoftware.com, Marcel Molina Jr.* + + error_messages_for :account, :user, :subscription, :object_name => :account + +* Fix assert_redirected_to tests according to real-world usage. Also, don't fail if you add an extra :controller option: *Rick Olson* + + redirect_to :action => 'new' + assert_redirected_to :controller => 'monkeys', :action => 'new' + +* Diff compared routing options. Allow #assert_recognizes to take a second arg as a hash to specify optional request method *Rick Olson* + + assert_recognizes({:controller => 'users', :action => 'index'}, 'users') + assert_recognizes({:controller => 'users', :action => 'create'}, {:path => 'users', :method => :post}) + +* Diff compared options with #assert_redirected_to *Rick Olson* + +* Add support in routes for semicolon delimited "subpaths", like /books/:id;:action *Jamis Buck* + +* Change link_to_function and button_to_function to (optionally) take an update_page block instead of a JavaScript string. Closes #4804. *zraii@comcast.net, Sam Stephenson* + +* Modify routing so that you can say :require => { :method => :post } for a route, and the route will never be selected unless the request method is POST. Only works for route recognition, not for route generation. *Jamis Buck* + +* Added :add_headers option to verify which merges a hash of name/value pairs into the response's headers hash if the prerequisites cannot be satisfied. *Sam Stephenson* + ex. verify :only => :speak, :method => :post, + :render => { :status => 405, :text => "Must be post" }, + :add_headers => { "Allow" => "POST" } + + +## 1.12.5 (August 10th, 2006) ## + +* Updated security fix + + +## 1.12.4 (August 8th, 2006) ## + +* Cache CgiRequest#request_parameters so that multiple calls don't re-parse multipart data. *Rick Olson* + +* Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for *David Heinemeier Hansson* + +* Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled. #1897 *jeremye@bsa.ca.gov* + +* Fixed that real files and symlinks should be treated the same when compiling templates. #5438 *zachary@panandscan.com* + +* Add :status option to send_data and send_file. Defaults to '200 OK'. #5243 *Manfred Stienstra * + +* Update documentation for erb trim syntax. #5651 *matt@mattmargolis.net* + +* Short documentation to mention use of Mime::Type.register. #5710 *choonkeat@gmail.com* + + +## 1.12.3 (June 28th, 2006) ## + +* Fix broken traverse_to_controller. We now: + Look for a _controller.rb file under RAILS_ROOT to load. + If we find it, we require_dependency it and return the controller it defined. (If none was defined we stop looking.) + If we don't find it, we look for a .rb file under RAILS_ROOT to load. If we find it, and it loads a constant we keep looking. + Otherwise we check to see if a directory of the same name exists, and if it does we create a module for it. + + +## 1.12.2 (June 27th, 2006) ## + +* Refinement to avoid exceptions in traverse_to_controller. + +* (Hackish) Fix loading of arbitrary files in Ruby's load path by traverse_to_controller. *Nicholas Seckar* + + +## 1.12.1 (April 6th, 2006) ## + +* Fixed that template extensions would be cached development mode #4624 *Stefan Kaes* + +* Update to Prototype 1.5.0_rc0 *Sam Stephenson* + +* Honor skipping filters conditionally for only certain actions even when the parent class sets that filter to conditionally be executed only for the same actions. #4522 *Marcel Molina Jr.* + +* Delegate xml_http_request in integration tests to the session instance. *Jamis Buck* + +* Update the diagnostics template skip the useless '' text. *Nicholas Seckar* + +* CHANGED DEFAULT: Don't parse YAML input by default, but keep it available as an easy option *David Heinemeier Hansson* + +* Add additional autocompleter options *aballai, Thomas Fuchs* + +* Fixed fragment caching of binary data on Windows #4493 *bellis@deepthought.org* + +* Applied Prototype $() performance patches (#4465, #4477) and updated script.aculo.us *Sam Stephenson, Thomas Fuchs* + +* Added automated timestamping to AssetTagHelper methods for stylesheets, javascripts, and images when Action Controller is run under Rails [David Heinemeier Hansson]. Example: + + image_tag("rails.png") # => 'Rails' + + ...to avoid frequent stats (not a problem for most people), you can set RAILS_ASSET_ID in the ENV to avoid stats: + + ENV["RAILS_ASSET_ID"] = "2345" + image_tag("rails.png") # => 'Rails' + + This can be used by deployment managers to set the asset id by application revision + + +## 1.12.0 (March 27th, 2006) ## + +* Add documentation for respond_to. *Jamis Buck* + +* Fixed require of bluecloth and redcloth when gems haven't been loaded #4446 *murphy@cYcnus.de* + +* Update to Prototype 1.5.0_pre1 *Sam Stephenson* + +* Change #form_for and #fields_for so that the second argument is not required *Dave Thomas* + + <% form_for :post, @post, :url => { :action => 'create' } do |f| -%> + + becomes... + + <% form_for :post, :url => { :action => 'create' } do |f| -%> + +* Update to script.aculo.us 1.6 *Thomas Fuchs* + +* Enable application/x-yaml processing by default *Jamis Buck* + +* Fix double url escaping of remote_function. Add :escape => false option to ActionView's url_for. *Nicholas Seckar* + +* Add :script option to in_place_editor to support evalScripts (closes #4194) *Cody Fauser* + +* Fix mixed case enumerable methods in the JavaScript Collection Proxy (closes #4314) *Cody Fauser* + +* Undo accidental escaping for mail_to; add regression test. *Nicholas Seckar* + +* Added nicer message for assert_redirected_to (closes #4294) *court3nay* + + assert_redirected_to :action => 'other_host', :only_path => false + + when it was expecting... + + redirected_to :action => 'other_host', :only_path => true, :host => 'other.test.host' + + gives the error message... + + response is not a redirection to all of the options supplied (redirection is <{:only_path=>false, :host=>"other.test.host", :action=>"other_host"}>), difference: <{:only_path=>"true", :host=>"other.test.host"}> + +* Change url_for to escape the resulting URLs when called from a view. *Nicholas Seckar, coffee2code* + +* Added easy support for testing file uploads with fixture_file_upload #4105 [turnip@turnipspatch.com]. Example: + + # Looks in Test::Unit::TestCase.fixture_path + '/files/spongebob.png' + post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png') + +* Fixed UrlHelper#current_page? to behave even when url-escaped entities are present #3929 *jeremy@planetargon.com* + +* Add ability for relative_url_root to be specified via an environment variable RAILS_RELATIVE_URL_ROOT. *isaac@reuben.com, Nicholas Seckar* + +* Fixed link_to "somewhere", :post => true to produce valid XHTML by using the parentnode instead of document.body for the instant form #3007 *Bob Silva* + +* Added :function option to PrototypeHelper#observe_field/observe_form that allows you to call a function instead of submitting an ajax call as the trigger #4268 *jonathan@daikini.com* + +* Make Mime::Type.parse consider q values (if any) *Jamis Buck* + +* XML-formatted requests are typecast according to "type" attributes for :xml_simple *Jamis Buck* + +* Added protection against proxy setups treating requests as local even when they're not #3898 *Steve Purcell* + +* Added TestRequest#raw_post that simulate raw_post from CgiRequest #3042 *François Beausoleil* + +* Underscore dasherized keys in formatted requests *Jamis Buck* + +* Add MimeResponds::Responder#any for managing multiple types with identical responses *Jamis Buck* + +* Make the xml_http_request testing method set the HTTP_ACCEPT header *Jamis Buck* + +* Add Verification to scaffolds. Prevent destructive actions using GET *Michael Koziarski* + +* Avoid hitting the filesystem when using layouts by using a File.directory? cache. *Stefan Kaes, Nicholas Seckar* + +* Simplify ActionController::Base#controller_path *Nicholas Seckar* + +* Added simple alert() notifications for RJS exceptions when config.action_view.debug_rjs = true. *Sam Stephenson* + +* Added :content_type option to render, so you can change the content type on the fly [David Heinemeier Hansson]. Example: render :action => "atom.rxml", :content_type => "application/atom+xml" + +* CHANGED DEFAULT: The default content type for .rxml is now application/xml instead of type/xml, see http://www.xml.com/pub/a/2004/07/21/dive.html for reason *David Heinemeier Hansson* + +* Added option to render action/template/file of a specific extension (and here by template type). This means you can have multiple templates with the same name but a different extension [David Heinemeier Hansson]. Example: + + class WeblogController < ActionController::Base + def index + @posts = Post.find :all + + respond_to do |type| + type.html # using defaults, which will render weblog/index.rhtml + type.xml { render :action => "index.rxml" } + type.js { render :action => "index.rjs" } + end + end + end + +* Added better support for using the same actions to output for different sources depending on the Accept header [David Heinemeier Hansson]. Example: + + class WeblogController < ActionController::Base + def create + @post = Post.create(params[:post]) + + respond_to do |type| + type.js { render } # renders create.rjs + type.html { redirect_to :action => "index" } + type.xml do + headers["Location"] = url_for(:action => "show", :id => @post) + render(:nothing, :status => "201 Created") + end + end + end + end + +* Added Base#render(:xml => xml) that works just like Base#render(:text => text), but sets the content-type to text/xml and the charset to UTF-8 *David Heinemeier Hansson* + +* Integration test's url_for now runs in the context of the last request (if any) so after post /products/show/1 url_for :action => 'new' will yield /product/new *Tobias Lütke* + +* Re-added mixed-in helper methods for the JavascriptGenerator. Moved JavascriptGenerators methods to a module that is mixed in after the helpers are added. Also fixed that variables set in the enumeration methods like #collect are set correctly. Documentation added for the enumeration methods [Rick Olson]. Examples: + + page.select('#items li').collect('items') do |element| + element.hide + end + # => var items = $$('#items li').collect(function(value, index) { return value.hide(); }); + +* Added plugin support for parameter parsers, which allows for better support for REST web services. By default, posts submitted with the application/xml content type is handled by creating a XmlSimple hash with the same name as the root element of the submitted xml. More handlers can easily be registered like this: + + # Assign a new param parser to a new content type + ActionController::Base.param_parsers['application/atom+xml'] = Proc.new do |data| + node = REXML::Document.new(post) + { node.root.name => node.root } + end + + # Assign the default XmlSimple to a new content type + ActionController::Base.param_parsers['application/backpack+xml'] = :xml_simple + + Default YAML web services were retired, ActionController::Base.param_parsers carries an example which shows how to get this functionality back. As part of this new plugin support, request.[formatted_post?, xml_post?, yaml_post? and post_format] were all deprecated in favor of request.content_type [Tobias Lütke] +* Fixed Effect.Appear in effects.js to work with floats in Safari #3524, #3813, #3044 *Thomas Fuchs* + +* Fixed that default image extension was not appended when using a full URL with AssetTagHelper#image_tag #4032, #3728 *rubyonrails@beautifulpixel.com* + +* Added that page caching will only happen if the response code is less than 400 #4033 *g.bucher@teti.ch* + +* Add ActionController::IntegrationTest to allow high-level testing of the way the controllers and routes all work together *Jamis Buck* + +* Added support to AssetTagHelper#javascript_include_tag for having :defaults appear anywhere in the list, so you can now make one call ala javascript_include_tag(:defaults, "my_scripts") or javascript_include_tag("my_scripts", :defaults) depending on how you want the load order #3506 *Bob Silva* + +* Added support for visual effects scoped queues to the visual_effect helper #3530 *Abdur-Rahman Advany* + +* Added .rxml (and any non-rhtml template, really) supportfor CaptureHelper#content_for and CaptureHelper#capture #3287 *Brian Takita* + +* Added script.aculo.us drag and drop helpers to RJS [Thomas Fuchs]. Examples: + + page.draggable 'product-1' + page.drop_receiving 'wastebasket', :url => { :action => 'delete' } + page.sortable 'todolist', :url => { action => 'change_order' } + +* Fixed that form elements would strip the trailing [] from the first parameter #3545 *ruby@bobsilva.com* + +* During controller resolution, update the NameError suppression to check for the expected constant. *Nicholas Seckar* + +* Update script.aculo.us to V1.5.3 *Thomas Fuchs* + +* Added various InPlaceEditor options, #3746, #3891, #3896, #3906 *Bill Burcham, ruairi, sl33p3r* + +* Added :count option to pagination that'll make it possible for the ActiveRecord::Base.count call to using something else than * for the count. Especially important for count queries using DISTINCT #3839 *Stefan Kaes* + +* Update script.aculo.us to V1.5.2 *Thomas Fuchs* + +* Added element and collection proxies to RJS [David Heinemeier Hansson]. Examples: + + page['blank_slate'] # => $('blank_slate'); + page['blank_slate'].show # => $('blank_slate').show(); + page['blank_slate'].show('first').up # => $('blank_slate').show('first').up(); + + page.select('p') # => $$('p'); + page.select('p.welcome b').first # => $$('p.welcome b').first(); + page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide(); + +* Add JavaScriptGenerator#replace for replacing an element's "outer HTML". #3246 *tom@craz8.com, Sam Stephenson* + +* Remove over-engineered form_for code for a leaner implementation. *Nicholas Seckar* + +* Document form_for's :html option. *Nicholas Seckar* + +* Major components cleanup and speedup. #3527 *Stefan Kaes* + +* Fix problems with pagination and :include. *Kevin Clark* + +* Add ActiveRecordTestCase for testing AR integration. *Kevin Clark* + +* Add Unit Tests for pagination *Kevin Clark* + +* Add :html option for specifying form tag options in form_for. *Sam Stephenson* + +* Replace dubious controller parent class in filter docs. #3655, #3722 *info@rhalff.com, eigentone@gmail.com* + +* Don't interpret the :value option on text_area as an html attribute. Set the text_area's value. #3752 *gabriel@gironda.org* + +* Fix remote_form_for creates a non-ajax form. *Rick Olson* + +* Don't let arbitrary classes match as controllers -- a potentially dangerous bug. *Nicholas Seckar* + +* Fix Routing tests. Fix routing where failing to match a controller would prevent the rest of routes from being attempted. *Nicholas Seckar* + +* Add :builder => option to form_for and friends. *Nicholas Seckar, Rick Olson* + +* Fix controller resolution to avoid accidentally inheriting a controller from a parent module. *Nicholas Seckar* + +* Set sweeper's @controller to nil after a request so that the controller may be collected between requests. *Nicholas Seckar* + +* Subclasses of ActionController::Caching::Sweeper should be Reloadable. *Rick Olson* + +* Document the :xhr option for verifications. #3666 *leeo* + +* Added :only and :except controls to skip_before/after_filter just like for when you add filters *David Heinemeier Hansson* + +* Ensure that the instance variables are copied to the template when performing render :update. *Nicholas Seckar* + +* Add the ability to call JavaScriptGenerator methods from helpers called in update blocks. [Sam Stephenson] Example: + module ApplicationHelper + def update_time + page.replace_html 'time', Time.now.to_s(:db) + page.visual_effect :highlight, 'time' + end + end + + class UserController < ApplicationController + def poll + render :update { |page| page.update_time } + end + end + +* Add render(:update) to ActionView::Base. *Sam Stephenson* + +* Fix render(:update) to not render layouts. *Sam Stephenson* + +* Fixed that SSL would not correctly be detected when running lighttpd/fcgi behind lighttpd w/mod_proxy #3548 *Steve Purcell* + +* Added the possibility to specify atomatic expiration for the memcachd session container #3571 *Stefan Kaes* + +* Change layout discovery to take into account the change in semantics with File.join and nil arguments. *Marcel Molina Jr.* + +* Raise a RedirectBackError if redirect_to :back is called when there's no HTTP_REFERER defined #3049 *Kevin Clark* + +* Treat timestamps like datetimes for scaffolding purposes #3388 *Maik Schmidt* + +* Fix IE bug with link_to "something", :post => true #3443 *Justin Palmer* + +* Extract Test::Unit::TestCase test process behavior into an ActionController::TestProcess module. *Sam Stephenson* + +* Pass along blocks from render_to_string to render. *Sam Stephenson* + +* Add render :update for inline RJS. [Sam Stephenson] Example: + class UserController < ApplicationController + def refresh + render :update do |page| + page.replace_html 'user_list', :partial => 'user', :collection => @users + page.visual_effect :highlight, 'user_list' + end + end + end + +* allow nil objects for error_messages_for *Michael Koziarski* + +* Refactor human_size to exclude decimal place if it is zero. *Marcel Molina Jr.* + +* Update to Prototype 1.5.0_pre0 *Sam Stephenson* + +* Automatically discover layouts when a controller is namespaced. #2199, #3424 *me@jonnii.com rails@jeffcole.net Marcel Molina Jr.* + +* Add support for multiple proxy servers to CgiRequest#host *gaetanot@comcast.net* + +* Documentation typo fix. #2367 *Blair Zajac* + +* Remove Upload Progress. #2871 *Sean Treadway* + +* Fix typo in function name mapping in auto_complete_field. #2929 #3446 *doppler@gmail.com phil.ross@gmail.com* + +* Allow auto-discovery of third party template library layouts. *Marcel Molina Jr.* + +* Have the form builder output radio button, not check box, when calling the radio button helper. #3331 *LouisStAmour@gmail.com* + +* Added assignment of the Autocompleter object created by JavaScriptMacroHelper#auto_complete_field to a local javascript variables *David Heinemeier Hansson* + +* Added :on option for PrototypeHelper#observe_field that allows you to specify a different callback hook to have the observer trigger on *David Heinemeier Hansson* + +* Added JavaScriptHelper#button_to_function that works just like JavaScriptHelper#link_to_function but uses a button instead of a href *David Heinemeier Hansson* + +* Added that JavaScriptHelper#link_to_function will honor existing :onclick definitions when adding the function call *David Heinemeier Hansson* + +* Added :disable_with option to FormTagHelper#submit_tag to allow for easily disabled submit buttons with different text *David Heinemeier Hansson* + +* Make auto_link handle nil by returning quickly if blank? *Scott Barron* + +* Make auto_link match urls with a port number specified. *Marcel Molina Jr.* + +* Added support for toggling visual effects to ScriptaculousHelper::visual_effect, #3323. *Thomas Fuchs* + +* Update to script.aculo.us to 1.5.0 rev. 3343 *Thomas Fuchs* + +* Added :select option for JavaScriptMacroHelper#auto_complete_field that makes it easier to only use part of the auto-complete suggestion as the value for insertion *Thomas Fuchs* + +* Added delayed execution of Javascript from within RJS #3264 [devslashnull@gmail.com]. Example: + + page.delay(20) do + page.visual_effect :fade, 'notice' + end + +* Add session ID to default logging, but remove the verbose description of every step *David Heinemeier Hansson* + +* Add the following RJS methods: *Sam Stephenson* + + * alert - Displays an alert() dialog + * redirect_to - Changes window.location.href to simulate a browser redirect + * call - Calls a JavaScript function + * assign - Assigns to a JavaScript variable + * << - Inserts an arbitrary JavaScript string + +* Fix incorrect documentation for form_for *Nicholas Seckar* + +* Don't include a layout when rendering an rjs template using render's :template option. *Marcel Molina Jr.* + +## 1.1.2 (December 13th, 2005) ## + +* Become part of Rails 1.0 + +* Update to script.aculo.us 1.5.0 final (equals 1.5.0_rc6) *Thomas Fuchs* + +* Update to Prototype 1.4.0 final *Sam Stephenson* + +* Added form_remote_for (form_for meets form_remote_tag) *David Heinemeier Hansson* + +* Update to script.aculo.us 1.5.0_rc6 + +* More robust relative url root discovery for SCGI compatibility. This solves the 'SCGI routes problem' -- you no longer need to prefix all your routes with the name of the SCGI mountpoint. #3070 *Dave Ringoen* + +* Fix docs for text_area_tag. #3083. *Christopher Cotton* + +* Change form_for and fields_for method signatures to take object name and object as separate arguments rather than as a Hash. *David Heinemeier Hansson* + +* Introduce :selected option to the select helper. Allows you to specify a selection other than the current value of object.method. Specify :selected => nil to leave all options unselected. #2991 *Jonathan Viney * + +* Initialize @optional in routing code to avoid warnings about uninitialized access to an instance variable. *Nicholas Seckar* + +* Make ActionController's render honor the :locals option when rendering a :file. #1665. *Emanuel Borsboom, Marcel Molina Jr.* + +* Allow assert_tag(:conditions) to match the empty string when a tag has no children. Closes #2959. *Jamis Buck* + +* Update html-scanner to handle CDATA sections better. Closes #2970. *Jamis Buck* + +* Don't put flash in session if sessions are disabled. *Jeremy Kemper* + +* Strip out trailing &_= for raw post bodies. Closes #2868. *Sam Stephenson* + +* Pass multiple arguments to Element.show and Element.hide in JavaScriptGenerator instead of using iterators. *Sam Stephenson* + +* Improve expire_fragment documentation. #2966 *court3nay* + +* Correct docs for automatic layout assignment. #2610. *Charles M. Gerungan* + +* Always create new AR sessions rather than trying too hard to avoid database traffic. #2731 *Jeremy Kemper* + +* Update to Prototype 1.4.0_rc4. Closes #2943 (old Array.prototype.reverse behavior can be obtained by passing false as an argument). *Sam Stephenson* + +* Use Element.update('id', 'html') instead of $('id').innerHTML = 'html' in JavaScriptGenerator#replace_html so that script tags are evaluated. *Sam Stephenson* + +* Make rjs templates always implicitly skip out on layouts. *Marcel Molina Jr.* + +* Correct length for the truncate text helper. #2913 *Stefan Kaes* + +* Update to Prototype 1.4.0_rc3. Closes #1893, #2505, #2550, #2748, #2783. *Sam Stephenson* + +* Add support for new rjs templates which wrap an update_page block. *Marcel Molina Jr.* + +* Rename Version constant to VERSION. #2802 *Marcel Molina Jr.* + +* Correct time_zone_options_for_select docs. #2892 *pudeyo@rpi.com* + +* Remove the unused, slow response_dump and session_dump variables from error pages. #1222 *lmarlow* + +* Performance tweaks: use Set instead of Array to speed up prototype helper include? calls. Avoid logging code if logger is nil. Inline commonly-called template presence checks. #2880, #2881, #2882, #2883 *Stefan Kaes* + +* MemCache store may be given multiple addresses. #2869 *Ryan Carver * + +* Handle cookie parsing irregularity for certain Nokia phones. #2530 *zaitzow@gmail.com* + +* Added PrototypeHelper::JavaScriptGenerator and PrototypeHelper#update_page for easily modifying multiple elements in an Ajax response. [Sam Stephenson] Example: + + update_page do |page| + page.insert_html :bottom, 'list', '
  • Last item
  • ' + page.visual_effect :highlight, 'list' + page.hide 'status-indicator', 'cancel-link' + end + + generates the following JavaScript: + + new Insertion.Bottom("list", "
  • Last item
  • "); + new Effect.Highlight("list"); + ["status-indicator", "cancel-link"].each(Element.hide); + +* Refactored JavaScriptHelper into PrototypeHelper and ScriptaculousHelper *Sam Stephenson* + +* Update to latest script.aculo.us version (as of [3031]) + +* Updated docs for in_place_editor, fixes a couple bugs and offers extended support for external controls *Justin Palmer* + +* Update documentation for render :file. #2858 *Tom Werner* + +* Only include builtin filters whose filenames match /^[a-z][a-z_]*_helper.rb$/ to avoid including operating system metadata such as ._foo_helper.rb. #2855 *court3nay* + +* Added FormHelper#form_for and FormHelper#fields_for that makes it easier to work with forms for single objects also if they don't reside in instance variables [David Heinemeier Hansson]. Examples: + + <% form_for :person, @person, :url => { :action => "update" } do |f| %> + First name: <%= f.text_field :first_name %> + Last name : <%= f.text_field :last_name %> + Biography : <%= f.text_area :biography %> + Admin? : <%= f.check_box :admin %> + <% end %> + + <% form_for :person, person, :url => { :action => "update" } do |person_form| %> + First name: <%= person_form.text_field :first_name %> + Last name : <%= person_form.text_field :last_name %> + + <% fields_for :permission => person.permission do |permission_fields| %> + Admin? : <%= permission_fields.check_box :admin %> + <% end %> + <% end %> + +* options_for_select allows any objects which respond_to? :first and :last rather than restricting to Array and Range. #2824 *Jacob Robbins , Jeremy Kemper* + +* The auto_link text helper accepts an optional block to format the link text for each url and email address. Example: auto_link(post.body) { |text| truncate(text, 10) } *Jeremy Kemper* + +* assert_tag uses exact matches for string conditions, instead of partial matches. Use regex to do partial matches. #2799 *Jamis Buck* + +* CGI::Session::ActiveRecordStore.data_column_name = 'foobar' to use a different session data column than the 'data' default. *nbpwie102@sneakemail.com* + +* Do not raise an exception when default helper is missing; log a debug message instead. It's nice to delete empty helpers. *Jeremy Kemper* + +* Controllers with acronyms in their names (e.g. PDFController) require the correct default helper (PDFHelper in file pdf_helper.rb). #2262 *jeff@opendbms.com* + + +## 1.11.0 (November 7th, 2005) ## + +* Added request as instance method to views, so you can do <%= request.env["HTTP_REFERER"] %>, just like you can already access response, session, and the likes *David Heinemeier Hansson* + +* Fix conflict with assert_tag and Glue gem #2255 *david.felstead@gmail.com* + +* Add documentation to assert_tag indicating that it only works with well-formed XHTML #1937, #2570 *Jamis Buck* + +* Added action_pack.rb stub so that ActionPack::Version loads properly *Sam Stephenson* + +* Added short-hand to assert_tag so assert_tag :tag => "span" can be written as assert_tag "span" *David Heinemeier Hansson* + +* Added skip_before_filter/skip_after_filter for easier control of the filter chain in inheritance hierachies [David Heinemeier Hansson]. Example: + + class ApplicationController < ActionController::Base + before_filter :authenticate + end + + class WeblogController < ApplicationController + # will run the :authenticate filter + end + + class SignupController < ActionController::Base + # will not run the :authenticate filter + skip_before_filter :authenticate + end + +* Added redirect_to :back as a short-hand for redirect_to(request.env["HTTP_REFERER"]) *David Heinemeier Hansson* + +* Change javascript_include_tag :defaults to not use script.aculo.us loader, which facilitates the use of plugins for future script.aculo.us and third party javascript extensions, and provide register_javascript_include_default for plugins to specify additional JavaScript files to load. Removed slider.js and builder.js from actionpack. *Thomas Fuchs* + +* Fix problem where redirecting components can cause an infinite loop *Rick Olson* + +* Added support for the queue option on visual_effect *Thomas Fuchs* + +* Update script.aculo.us to V1.5_rc4 *Thomas Fuchs* + +* Fix that render :text didn't interpolate instance variables #2629, #2626 *Stefan Kaes* + +* Fix line number detection and escape RAILS_ROOT in backtrace Regexp *Nicholas Seckar* + +* Fixed document.getElementsByClassName from Prototype to be speedy again *Sam Stephenson* + +* Recognize ./#{RAILS_ROOT} as RAILS_ROOT in error traces *Nicholas Seckar* + +* Remove ARStore session fingerprinting *Nicholas Seckar* + +* Fix obscure bug in ARStore *Nicholas Seckar* + +* Added TextHelper#strip_tags for removing HTML tags from a string (using HTMLTokenizer) #2229 *marcin@junkheap.net* + +* Added a reader for flash.now, so it's possible to do stuff like flash.now[:alert] ||= 'New if not set' #2422 *Caio Chassot* + + +## 1.10.2 (October 26th, 2005) ## + +* Reset template variables after using render_to_string *Stefan Kaes* + +* Expose the session model backing CGI::Session + +* Abbreviate RAILS_ROOT in traces + + +## 1.10.1 (October 19th, 2005) ## + +* Update error trace templates *Nicholas Seckar* + +* Stop showing generated routing code in application traces *Nicholas Seckar* + + +## 1.10.0 (October 16th, 2005) ## + +* Make string-keys locals assigns optional. Add documentation describing depreciated state *Stefan Kaes* + +* Improve line number detection for template errors *Nicholas Seckar* + +* Update/clean up documentation (rdoc) + +* Upgrade to Prototype 1.4.0_rc0 *Sam Stephenson* + +* Added assert_vaild. Reports the proper AR error messages as fail message when the passed record is invalid *Tobias Lütke* + +* Add temporary support for passing locals to render using string keys *Nicholas Seckar* + +* Clean up error pages by providing better backtraces *Nicholas Seckar* + +* Raise an exception if an attempt is made to insert more session data into the ActiveRecordStore data column than the column can hold. #2234. *justin@textdrive.com* + +* Removed references to assertions.rb from actionpack assert's backtraces. Makes error reports in functional unit tests much less noisy. *Tobias Lütke* + +* Updated and clarified documentation for JavaScriptHelper to be more concise about the various options for including the JavaScript libs. *Thomas Fuchs* + +* Hide "Retry with Breakpoint" button on error pages until feature is functional. *David Heinemeier Hansson* + +* Fix Request#host_with_port to use the standard port when Rails is behind a proxy. *Nicholas Seckar* + +* Escape query strings in the href attribute of URLs created by url_helper. #2333 *Michael Schuerig * + +* Improved line number reporting for template errors *Nicholas Seckar* + +* Added :locals support for render :inline #2463 *mdabney@cavoksolutions.com* + +* Unset the X-Requested-With header when using the xhr wrapper in functional tests so that future requests aren't accidentally xhr'ed #2352 *me@julik.nl, Sam Stephenson* + +* Unescape paths before writing cache to file system. #1877. *Damien Pollet* + +* Wrap javascript_tag contents in a CDATA section and add a cdata_section method to TagHelper #1691 *Michael Schuerig, Sam Stephenson* + +* Misc doc fixes (typos/grammar/etc). #2445. *coffee2code* + +* Speed improvement for session_options. #2287. *Stefan Kaes* + +* Make cacheing binary files friendly with Windows. #1975. *Rich Olson* + +* Convert boolean form options form the tag_helper. #809. *Michael Schuerig * + +* Fixed that an instance variable with the same name as a partial should be implicitly passed as the partial :object #2269 *court3nay* + +* Update Prototype to V1.4.0_pre11, script.aculo.us to [2502] *Thomas Fuchs* + +* Make assert_tag :children count appropriately. Closes #2181. *jamie@bravenet.com* + +* Forced newer versions of RedCloth to use hard breaks *David Heinemeier Hansson* + +* Added new scriptaculous options for auto_complete_field #2343 *Manfred Stienstra* + +* Don't prepend the asset host if the string is already a fully-qualified URL + +* Updated to script.aculo.us V1.5.0_rc2 and Prototype to V1.4.0_pre7 *Thomas Fuchs* + +* Undo condition change made in [2345] to prevent normal parameters arriving as StringIO. + +* Tolerate consecutive delimiters in query parameters. #2295 *darashi@gmail.com* + +* Streamline render process, code cleaning. Closes #2294. *skae* + +* Keep flash after components are rendered. #2291 *Rick Olson, Scott* + +* Shorten IE file upload path to filename only to match other browsers. #1507 *court3nay* + +* Fix open/save dialog in IE not opening files send with send_file/send_data, #2279 *Thomas Fuchs* + +* Fixed that auto_discovery_link_tag couldn't take a string as the URL *David Heinemeier Hansson* + +* Fixed problem with send_file and WEBrick using stdout #1812 *David Heinemeier Hansson* + +* Optimized tag_options to not sort keys, which is no longer necessary when assert_dom_equal and friend is available #1995 *skae* + +* Added assert_dom_equal and assert_dom_not_equal to compare tags generated by the helpers in an order-indifferent manner #1995 *skae* + +* Fixed that Request#domain caused an exception if the domain header wasn't set in the original http request #1795 *Michael Koziarski* + +* Make the truncate() helper multi-byte safe (assuming $KCODE has been set to something other than "NONE") #2103 + +* Add routing tests from #1945 *ben@groovie.org* + +* Add a routing test case covering #2101 *Nicholas Seckar* + +* Cache relative_url_root for all webservers, not just Apache #2193 *skae* + +* Speed up cookie use by decreasing string copying #2194 *skae* + +* Fixed access to "Host" header with requests made by crappy old HTTP/1.0 clients #2124 *Marcel Molina Jr.* + +* Added easy assignment of fragment cache store through use of symbols for included stores (old way still works too) + + Before: + ActionController::Base.fragment_cache_store = + ActionController::Base::Caching::Fragments::FileStore.new("/path/to/cache/directory") + + After: + ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory" + +* Added ActionController::Base.session_store=, session_store, and session_options to make it easier to tweak the session options (instead of going straight to ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS) + +* Added TextHelper#cycle to cycle over an array of values on each hit (useful for alternating row colors etc) #2154 *dave-ml@dribin.org* + +* Ensure that request.path never returns nil. Closes #1675 *Nicholas Seckar* + +* Add ability to specify Route Regexps for controllers. Closes #1917. *Sebastian Kanthak* + +* Provide Named Route's hash methods as helper methods. Closes #1744. *Nicholas Seckar, Steve Purcell* + +* Added :multipart option to ActiveRecordHelper#form to make it possible to add file input fields #2034 *jstirk@oobleyboo.com* + +* Moved auto-completion and in-place editing into the Macros module and their helper counterparts into JavaScriptMacrosHelper + +* Added in-place editing support in the spirit of auto complete with ActionController::Base.in_place_edit_for, JavascriptHelper#in_place_editor_field, and Javascript support from script.aculo.us #2038 *Jon Tirsen* + +* Added :disabled option to all data selects that'll make the elements inaccessible for change #2167, #253 *eigentone* + +* Fixed that TextHelper#auto_link_urls would include punctuation in the links #2166, #1671 *eigentone* + +* Fixed that number_to_currency(1000, {:precision => 0})) should return "$1,000", instead of "$1,000." #2122 *sd@notso.net* + +* Allow link_to_remote to use any DOM-element as the parent of the form elements to be submitted #2137 [erik@ruby-lang.nl]. Example: + + + + + <%= link_to_remote 'Save', :update => "row023", + :submit => "row023", :url => {:action => 'save_row'} %> + + +* Fixed that render :partial would fail when :object was a Hash (due to backwards compatibility issues) #2148 *Sam Stephenson* + +* Fixed JavascriptHelper#auto_complete_for to only include unique items #2153 *Thomas Fuchs* + +* Fixed all AssetHelper methods to work with relative paths, such that javascript_include_tag('stdlib/standard') will look in /javascripts/stdlib/standard instead of '/stdlib/standard/' #1963 + +* Avoid extending view instance with helper modules each request. Closes #1979 + +* Performance improvements to CGI methods. Closes #1980 *Stefan Kaes* + +* Added :post option to UrlHelper#link_to that makes it possible to do POST requests through normal ahref links using Javascript + +* Fixed overwrite_params + +* Added ActionController::Base.benchmark and ActionController::Base.silence to allow for easy benchmarking and turning off the log + +* Updated vendor copy of html-scanner to support better xml parsing + +* Added :popup option to UrlHelper#link_to #1996 [gabriel.gironda@gmail.com]. Examples: + + link_to "Help", { :action => "help" }, :popup => true + link_to "Busy loop", { :action => "busy" }, :popup => ['new_window', 'height=300,width=600'] + +* Drop trailing \000 if present on RAW_POST_DATA (works around bug in Safari Ajax implementation) #918 + +* Fix observe_field to fall back to event-based observation if frequency <= 0 #1916 *Michael Schubert* + +* Allow use of the :with option for submit_to_remote #1936 *jon@instance-design.co.uk* + +* AbstractRequest#domain returns nil when host is an ip address #2012 *Kevin Clark* + +* ActionController documentation update #2051 *François Beausoleil* + +* Yield @content_for_ variables to templates #2058 *Sam Stephenson* + +* Make rendering an empty partial collection behave like :nothing => true #2080 *Sam Stephenson* + +* Add option to specify the singular name used by pagination. + +* Use string key to obtain action value. Allows indifferent hashes to be disabled. + +* Added ActionView::Base.cache_template_loading back. + +* Rewrote compiled templates to decrease code complexity. Removed template load caching in favour of compiled caching. Fixed template error messages. *Nicholas Seckar* + +* Fix Routing to handle :some_param => nil better. *Nicholas Seckar, Luminas* + +* Add support for :include with pagination (subject to existing constraints for :include with :limit and :offset) #1478 *Michael Schubert* + +* Prevent the benchmark module from blowing up if a non-HTTP/1.1 request is processed + +* Added :use_short_month option to select_month helper to show month names as abbreviations + +* Make link_to escape the javascript in the confirm option #1964 *nicolas.pouillard@gmail.com* + +* Make assert_redirected_to properly check URL's passed as strings #1910 *Scott Barron* + +* Make sure :layout => false is always used when rendering inside a layout + +* Use raise instead of assert_not_nil in Test::Unit::TestCase#process to ensure that the test variables (controller, request, response) have been set + +* Make sure assigns are built for every request when testing #1866 + +* Allow remote_addr to be queried on TestRequest #1668 + +* Fixed bug when a partial render was passing a local with the same name as the partial + +* Improved performance of test app req/sec with ~10% refactoring the render method #1823 *Stefan Kaes* + +* Improved performance of test app req/sec with 5-30% through a series of Action Pack optimizations #1811 *Stefan Kaes* + +* Changed caching/expiration/hit to report using the DEBUG log level and errors to use the ERROR log level instead of both using INFO + +* Added support for per-action session management #1763 + +* Improved rendering speed on complicated templates by up to 100% (the more complex the templates, the higher the speedup) #1234 [Stefan Kaes]. This did necessasitate a change to the internals of ActionView#render_template that now has four parameters. Developers of custom view handlers (like Amrita) need to update for that. + +* Added options hash as third argument to FormHelper#input, so you can do input('person', 'zip', :size=>10) #1719 *jeremye@bsa.ca.gov* + +* Added Base#expires_in(seconds)/Base#expires_now to control HTTP content cache headers #1755 *Thomas Fuchs* + +* Fixed line number reporting for Builder template errors #1753 *piotr* + +* Fixed assert_routing so that testing controllers in modules works as expected *Nicholas Seckar, Rick Olson* + +* Fixed bug with :success/:failure callbacks for the JavaScriptHelper methods #1730 *court3nay/Thomas Fuchs* + +* Added named_route method to RouteSet instances so that RouteSet instance methods do not prevent certain names from being used. *Nicholas Seckar* + +* Fixed routes so that routes which do not specify :action in the path or in the requirements have a default of :action => 'index', In addition, fixed url generation so that :action => 'index' does not need to be provided for such urls. *Nicholas Seckar, Markjuh* + +* Worked around a Safari bug where it wouldn't pass headers through if the response was zero length by having render :nothing return ' ' instead of '' + +* Fixed Request#subdomains to handle "foo.foo.com" correctly + + +## 1.9.1 (11 July, 2005) ## + +* Fixed that auto_complete_for didn't force the input string to lower case even as the db comparison was + +* Fixed that Action View should always use the included Builder, never attempt to require the gem, to ensure compatibility + +* Added that nil options are not included in tags, so tag("p", :ignore => nil) now returns

    not

    but that tag("p", :ignore => "") still includes it #1465 *Michael Schuerig* + +* Fixed that UrlHelper#link_to_unless/link_to_if used html_escape on the name if no link was to be applied. This is unnecessary and breaks its use with images #1649 *joergd@pobox.com* + +* Improved error message for DoubleRenderError + +* Fixed routing to allow for testing of *path components #1650 *Nicholas Seckar* + +* Added :handle as an option to sortable_element to restrict the drag handle to a given class #1642 *thejohnny* + +* Added a bunch of script.aculo.us features #1644, #1677, #1695 *Thomas Fuchs* + * Effect.ScrollTo, to smoothly scroll the page to an element + * Better Firefox flickering handling on SlideUp/SlideDown + * Removed a possible memory leak in IE with draggables + * Added support for cancelling dragging my hitting ESC + * Added capability to remove draggables/droppables and redeclare sortables in dragdrop.js (this makes it possible to call sortable_element on the same element more than once, e.g. in AJAX returns that modify the sortable element. all current sortable 'stuff' on the element will be discarded and the sortable will be rebuilt) + * Always reset background color on Effect.Highlight; this make change backwards-compatibility, to be sure include style="background-color:(target-color)" on your elements or else elements will fall back to their CSS rules (which is a good thing in most circumstances) + * Removed circular references from element to prevent memory leaks (still not completely gone in IE) + * Changes to class extension in effects.js + * Make Effect.Highlight restore any previously set background color when finishing (makes effect work with CSS classes that set a background color) + * Fixed myriads of memory leaks in IE and Gecko-based browsers *David Zülke* + * Added incremental and local autocompleting and loads of documentation to controls.js *Ivan Krstic* + * Extended the auto_complete_field helper to accept tokens option + * Changed object extension mechanism to favor Object.extend to make script.aculo.us easily adaptable to support 3rd party libs like IE7.js *David Zülke* + +* Fixed that named routes didn't use the default values for action and possible other parameters #1534 *Nicholas Seckar* + +* Fixed JavascriptHelper#visual_effect to use camelize such that :blind_up will work #1639 *pelletierm@eastmedia.net* + +* Fixed that a SessionRestoreError was thrown if a model object was placed in the session that wasn't available to all controllers. This means that it's no longer necessary to use the 'model :post' work-around in ApplicationController to have a Post model in your session. + + +## 1.9.0 (6 July, 2005) ## + +* Added logging of the request URI in the benchmark statement (makes it easy to grep for slow actions) + +* Added javascript_include_tag :defaults shortcut that'll include all the default javascripts included with Action Pack (prototype, effects, controls, dragdrop) + +* Cache several controller variables that are expensive to calculate #1229 *Stefan Kaes* + +* The session class backing CGI::Session::ActiveRecordStore may be replaced with any class that duck-types with a subset of Active Record. See docs for details #1238 *Stefan Kaes* + +* Fixed that hashes was not working properly when passed by GET to lighttpd #849 *Nicholas Seckar* + +* Fixed assert_template nil will be true when no template was rendered #1565 *maceywj@telus.net* + +* Added :prompt option to FormOptions#select (and the users of it, like FormOptions#select_country etc) to create "Please select" style descriptors #1181 *Michael Schuerig* + +* Added JavascriptHelper#update_element_function, which returns a Javascript function (or expression) that'll update a DOM element according to the options passed #933 [mortonda@dgrmm.net]. Examples: + + <%= update_element_function("products", :action => :insert, :position => :bottom, :content => "

    New product!

    ") %> + + <% update_element_function("products", :action => :replace, :binding => binding) do %> +

    Product 1

    +

    Product 2

    + <% end %> + +* Added :field_name option to DateHelper#select_(year|month|day) to deviate from the year/month/day defaults #1266 *Marcel Molina Jr.* + +* Added JavascriptHelper#draggable_element and JavascriptHelper#drop_receiving_element to facilitate easy dragging and dropping through the script.aculo.us libraries #1578 *Thomas Fuchs* + +* Added that UrlHelper#mail_to will now also encode the default link title #749 *f.svehla@gmail.com* + +* Removed the default option of wrap=virtual on FormHelper#text_area to ensure XHTML compatibility #1300 *thomas@columbus.rr.com* + +* Adds the ability to include XML CDATA tags using Builder #1563 [Josh Knowles]. Example: + + xml.cdata! "some text" # => + +* Added evaluation of SCRIPT blocks in content returned to Ajax calls #1577 *Thomas Fuchs/court3nay/Sean Treadway* + +* Directly generate paths with a leading slash instead of tacking it on later. #1543 *Nicholas Seckar* + +* Fixed errant parameter modification in functional tests. #1542 *Nicholas Seckar* + +* Routes fail with leading slash #1540 *Nicholas Seckar* + +* Added support for graceful error handling of Ajax calls #1217 [Jamis Buck/Thomas Fuchs]. Example: + + link_to_remote( + "test", + :url => { :action => "faulty" }, + :update => { :success => "good", :failure => "bad" }, + 403 => "alert('Forbidden- got ya!')", + 404 => "alert('Nothing there...?')", + :failure => "alert('Unkown error ' + request.status)") + +* Attempt to explicitly flush the output at the end of CgiProcess#out + +* Fixed assert_redirected_to to handle absolute controller paths properly #1472 *Rick Olson/Nicholas Seckar* + +* Added event-based observations when frequency is not set on observe_field/form #1474 *flash@vanklinkenbergsoftware.nl* + +* Added script.aculo.us Javascripts (controls.js, dragdrop.js, effects.js) (NEEDS MORE DESCRIPTION) #1509 *Thomas Fuchs* + +* Fixed prototype to consider all fields it doesn't know as text (such as Safari's search) just like the browser in its serialization #1497 *Sean Treadway* + +* Improved performance of Routes generation by a factor of 5 #1434 *Nicholas Seckar* + +* Added named routes (NEEDS BETTER DESCRIPTION) #1434 *Nicholas Seckar* + +* Improved AbstractRequest documentation #1483 *court3nay* + +* Added ActionController::Base.allow_concurrency to control whether the application is thread-safe, so multi-threaded servers like WEBrick knows whether to apply a mutex around the performance of each action. Turned off by default. EXPERIMENTAL FEATURE. + +* Added TextHelper#word_wrap(text, line_length = 80) #1449 *tuxie@dekadance.se* + +* Added a fall-through action for form_remote_tag that'll be used in case Javascript is unavailable #1459 [Scott Barron]. Example: + + form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") } + +* Added :xhr => true/false option to verify so you can ensure that a request is coming from an Ajax call or not #1464 *Thomas Fuchs* + +* Added tag_options as a third parameter to AssetHelper#auto_discovery_link_tag to control options like the title of the link #1430 *Kevin Clark* + +* Added option to pass in parameters to CaptureHelper#capture, so you can create more advanced view helper methods #1466 [duane.johnson@gmail.com]. Example: + + <% show_calendar(:year => 2005, :month => 6) do |day, options| %> + <% options[:bgcolor] = '#dfd' if 10..15.include? day %> + [<%= day %>] + <% end %> + +* Changed the default name of the input tag generated by FormTagHelper#submit_tag from "submit" to "commit" so it doesn't clash with form.submit() calls in Javascript #1271 + +* Fixed relative urls support for lighttpd #1048 *Nicholas Seckar/maznawak@nerim.net* + +* Correct distance_of_time_in_words for integer arguments and make the second arg optional, treating the first arg as a duration in seconds. #1458 *madrobby * + +* Fixed query parser to deal gracefully with equal signs inside keys and values #1345 [gorou]. + Example: /?sig=abcdef=:foobar=&x=y will pass now. + +* Added Cuba to country list #1351 *todd* + +* Fixed radio_button to work with numeric values #1352 *demetrius* + +* Added :extension option to NumberHelper#number_to_phone #1361 *delynnb* + +* Added button_to as a form-based solution to deal with harmful actions that should be hidden behind POSTs. This makes it just as easy as link_to to create a safe trigger for actions like destroy, although it's limited by being a block element, the fixed look, and a no-no inside other forms. #1371 *tom@moertel.com* + +* Fixed image_tag so an exception is not thrown just because the image is missing and alt value can't be generated #1395 *Marcel Molina Jr.* + +* Added a third parameter to TextHelper#auto_link called href_options for specifying additional tag options on the links generated #1401 [tyler.kovacs@gmail.com]. Example: auto_link(text, :all, { :target => "_blank" }) to have all the generated links open in a new window. + +* Fixed TextHelper#highlight to return the text, not nil, if the phrase is blank #1409 *Patrick Lenz* + +* Fixed TagHelper such that :name and 'name' keys in the options doesn't result in two attributes #1455 *take_tk* + +* Ensure that helpers are only available to the controllers where they are defined and their subclasses. #1394 *kdole@tamu.edu* + +* render("foo/bar") works with a layout again + +* Fixed double-singularization on scaffolded pagination call (Address would be turned into Addres) #1216, #1404 *nilsga* + +* Removed the require hack used by functional testing to work around an earlier bug in rake. + +* Allow distance_of_time_in_words to work with any value that responds to #to_time (like dates) #969 + +* Support :render option for :verify #1440 *Tobias Lütke* + +* Updated vendor copy of html-scanner lib to 0.5.2, for bug fixes and optimizations. The :content option may be used as expected--to find a tag whose textual content is a particular value--in assert_tag, now. + +* Changed test requests to come from 0.0.0.0 instead of 127.0.0.1 such that they don't trigger debugging screens on exceptions, but instead call rescue_action_in_public + +* Modernize scaffolding to match the generator: use the new render method and change style from the warty @params["id"] to the sleek params[:id]. #1367 + +* Include :id in the action generated by the form helper method. Then, for example, the controller can do Model.find(params[:id]) for both edit and update actions. Updated scaffolding to take advantage. #1367 + +* Add assertions with friendly messages to TestCase#process to ensure that @controller, @request, and @response are set. #1367 + +* Arrays, hashes sent via multipart posts are converted to strings #1032 *dj@omelia.org, me@julik.nl* + +* render(:layout => true) is a synonym for render(:layout => nil) + +* Make sure the benchmarking render method always returns the output of the render. + +* render(:action), render(:template) and render() are the only three calls that default to using a layout. All other render calls assume :layout => false. This also fixes send_file, which was applying a layout if one existed for the current action. + +* verify with :redirect_to won't redirect if a redirect or render has already been performed #1350 + +* render(:partial => true) is identical to the behavior of the deprecated render_partial() + +* Fixed render(:partial => "...") to use an empty Hash for the local assigns #1365 + +* Fixed Caching::Fragments::FileStore.delete to not raise an exception if the delete fails. + +* Deprecated all render_* methods in favor of consolidating all rendering behavior in Base#render(options). This enables more natural use of combining options, such as layouts. Examples: + + +---------------------------------------------------------------+-------------------------------------------------------+ + | BEFORE | AFTER | + +---------------------------------------------------------------+-------------------------------------------------------+ + | render_with_layout "weblog/show", "200 OK", "layouts/dialog" | render :action => "show", :layout => "dialog" | + | render_without_layout "weblog/show" | render :action => "show", :layout => false | + | render_action "error", "404 Not Found" | render :action => "error", :status => "404 Not Found" | + | render_template "xml.div('stuff')", "200 OK", :rxml | render :inline => "xml.div('stuff')", :type => :rxml | + | render_text "hello world!" | render :text => "hello world!" | + | render_partial_collection "person", @people, nil, :a => 1 | render :partial => "person", :collection => @people, | + | | :locals => { :a => 1 } | + +---------------------------------------------------------------+-------------------------------------------------------+ + +* Deprecated redirect_to_path and redirect_to_url in favor of letting redirect_to do the right thing when passed either a path or url. + +* Fixed use of an integer as return code for renders, so render_text "hello world", 404 now works #1327 + +* Fixed assert_redirect_to to work with redirect_to_path #869 *Nicholas Seckar* + +* Fixed escaping of :method option in remote_form_tag #1218 *Rick Olson* + +* Added Serbia and Montenegro to the country_select #1239 *todd@robotcoop.com* + +* Fixed Request#remote_ip in testing #1251 *Jeremy Kemper* + +* Fixed that compute_public_path should recognize external URLs, so image_tag("http://www.example.com/images/icon.gif") is not prefixed with the relative url path #1254 *victor-ronr-trac@carotena.net* + +* Added support for descending year values in DateHelper#select_year, like select_year(Date.today, :start_year => 2005, :end_year => 1900), which would count down from 2005 to 1900 instead of the other way #1274 *nwoods@mail.com* + +* Fixed that FormHelper#checkbox should return a checked checkbox if the value is the same as checked_value #1286 *Florian Weber* + +* Fixed Form.disable in Prototype #1317 *Wintermute* + +* Added accessors to logger, params, response, session, flash, and headers from the view, so you can write <% logger.info "stuff" %> instead of <% @logger.info "others" %> -- more consistent with the preferred way of accessing these attributes and collections from the controller + +* Added support for POST data in form of YAML or XML, which is controller through the Content-Type header. Example request: + + Content-Type: application/xml + HelloWorld + + ...is the same as: + + Content-Type: application/x-yaml + --- + item: + content: HelloWorld + + ...is the same as: + + item[content]=HelloWorld + + Which in the end turns into { "item" => { "content" => "HelloWorld" } }. This makes it a lot easier to publish REST web services on top of your regular actions (as they won't care). + + Example Curl call: + + curl -H 'Content-Type: application/xml' -d 'KillMeMore' http://www.example.com/service + + You can query to find out whether a given request came through as one of these types with: + - request.post_format? (:url_encoded, :xml or :yaml) + - request.formatted_post? (for either xml or yaml) + - request.xml_post? + - request.yaml_post? + +* Added bundling of XmlSimple by Maik Schmidt + +* Fixed that render_partial_collection should always return a string (and not sometimes an array, despite <%= %> not caring) + +* Added TextHelper#sanitize that can will remove any Javascript handlers, blocks, and forms from an input of HTML. This allows for use of HTML on public sites, but still be free of XSS issues. #1277 *Jamis Buck* + +* Fixed the HTML scanner used by assert_tag where a infinite loop could be caused by a stray less-than sign in the input #1270 *Jamis Buck* + +* Added functionality to assert_tag, so you can now do tests on the siblings of a node, to assert that some element comes before or after the element in question, or just to assert that some element exists as a sibling #1226 *Jamis Buck* + +* Added better error handling for regexp caching expiration + +* Fixed handling of requests coming from unknown HTTP methods not to kill the server + +* Added that both AssetHelper#stylesheet_link_tag and AssetHelper#javascript_include_tag now accept an option hash as the last parameter, so you can do stuff like: stylesheet_link_tag "style", :media => "all" + +* Added FormTagHelper#image_submit_tag for making submit buttons that uses images + +* Added ActionController::Base.asset_host that will then be used by all the asset helpers. This enables you to easily offload static content like javascripts and images to a separate server tuned just for that. + +* Fixed action/fragment caching using the filestore when a directory and a file wanted to use the same name. Now there's a .cache prefix that sidesteps the conflict #1188 *imbcmdth@hotmail.com* + +* Fixed missing id uniqueness in FormTag#radio_button #1207 *Jarkko Laine* + +* Fixed assert_redirected_to to work with :only_path => false #1204 *Alisdair McDiarmid* + +* Fixed render_partial_collection to output an empty string instead of nil when handed an empty array #1202 *Ryan Carver* + +* Improved the speed of regular expression expirations for caching by a factor of 10 #1221 *Jamis Buck* + +* Removed dumping of template assigns on the rescue page as it would very easily include a ton of data making page loads take seconds (and the information was rarely helpful) #1222 + +* Added BenchmarkHelper that can measure the execution time of a block in a template and reports the result to the log. Example: + + <% benchmark "Notes section" do %> + <%= expensive_notes_operation %> + <% end %> + + Will add something like "Notes section (0.345234)" to the log. + +* Added ActionController::Caching::Sweeper as an improved an easier to use sweeper. The new sweepers work on a single-step approach instead of two-steps like the old ones. Before + + def after_save(record) + @list = record.is_a?(List) ? record : record.list + end + + def filter(controller) + controller.expire_page(:controller => "lists", :action => %w( show public feed ), :id => @list.id) + controller.expire_action(:controller => "lists", :action => "all") + @list.shares.each { |share| controller.expire_page(:controller => "lists", :action => "show", :id => share.url_key) } + end + + ..after: + + def after_save(record) + list = record.is_a?(List) ? record : record.list + expire_page(:controller => "lists", :action => %w( show public feed ), :id => list.id) + expire_action(:controller => "lists", :action => "all") + list.shares.each { |share| expire_page(:controller => "lists", :action => "show", :id => share.url_key) } + end + + The new sweepers can also observe on the actions themselves by implementing methods according to (before|after)_$controller_$action. Example of a callback that'll be called after PagesController#update_title has been performed: + + def after_pages_update_title + expire_fragment(%r{pages/#{controller.assigns["page"].id}/.*}) + end + + Note that missing_method is delegated to the controller instance, which is assigned in a before filter. This means that you can call expire_fragment instead of @controller.expire_fragment. + +* Added that Fragments#expire_fragment now accepts as a regular expression as the name thereby deprecating expire_matched_fragments + +* Fixed that fragments shouldn't use the current host and the path as part of the key like pages does + +* Added conditions to around_filters just like before_filter and after_filter + + +## 1.8.1 (20th April, 2005) ## + +* Added xml_http_request/xhr method for simulating XMLHttpRequest in functional tests #1151 [Sam Stephenson]. Example: + + xhr :post, :index + +* Fixed that Ajax.Base.options.asynchronous wasn't being respected in Ajax.Request (thanks Jon Casey) + +* Fixed that :get, :post, and the others should take a flash array as the third argument just like process #1144 *rails@cogentdude.com* + +* Fixed a problem with Flash.now + +* Fixed stringification on all assigned hashes. The sacrifice is that assigns[:person] won't work in testing. Instead assigns["person"] or assigns(:person) must be used. In other words, the keys of assigns stay strings but we've added a method-based accessor to appease the need for symbols. + +* Fixed that rendering a template would require a connection to the database #1146 + + +## 1.8.0 (19th April, 2005) ## + +* Added assert_tag and assert_no_tag as a much improved alternative to the deprecated assert_template_xpath_match #1126 *Jamis Buck* + +* Deprecated the majority of all the testing assertions and replaced them with a much smaller core and access to all the collections the old assertions relied on. That way the regular test/unit assertions can be used against these. Added documentation about how to use it all. + +* Added a wide range of new Javascript effects: + * Effect.Puff zooms the element out and makes it smoothly transparent at the same time, giving a "puff" illusion #996 [thomas@fesch.at] + After the animation is completed, the display property will be set to none. + This effect will work on relative and absolute positioned elements. + + * Effect.Appear as the opposite of Effect.Fade #990 [thomas@fesch.at] + You should return elements with style="display:none;" or a like class for this to work best and have no chance of flicker. + + * Effect.Squish for scaling down an element and making it disappear at the end #972 [thomas@fesch.at] + + * Effect.Scale for smoothly scaling images or text up and down #972 [thomas@fesch.at] + + * Effect.Fade which smoothly turns opacity from 100 to 0 and then hides the element #960 [thomas@fesch.at] + +* Added Request#xml_http_request? (and an alias xhr?) to that'll return true when the request came from one of the Javascript helper methods (Ajax). This can be used to give one behavior for modern browsers supporting Ajax, another to old browsers #1127 *Sam Stephenson* + +* Changed render_partial to take local assigns as the second parameter instead of an explicit object and then the assigns. So the API changes from: + + <%= render_partial "account", person, "rules" => regulations.rules %> + + ...to: + + <%= render_partial "account", :account => person, :rules => regulations.rules %> + + The old API will still work, though, and render_partial "account" will still assume :account => @account. + +* Added support for web servers that use PATH_INFO instead of REQUEST_URI like IIS #1014 *BradG/Nicholas Seckar* + +* Added graceful handling of PUT, DELETE, and OPTIONS requests for a complete coverage of REST functionality #1136 *Josh Knowles* + +* Fixed that you can now pass an alternative :href option to link_to_function/remote in order to point to somewhere other than # if the javascript fails or is turned off. You can do the same with form_remote_tag by passing in :action. #1113 *Sam Stephenson* + +* Fixed DateHelper to return values on the option tags such that they'll work properly in IE with form_remote_tag #1024 *Scott Raymond* + +* Fixed FormTagHelper#check_box to respect checked #1049 *DelynnB* + +* Added that render_partial called from a controller will use the action name as default #828 *Dan Peterson* + +* Added Element.toggle, Element.show, and Element.hide to the prototype javascript library. Toggle.display has been deprecated, but will still work #992 *Lucas Carlson* + +* Added that deleting a cookie should not just set it to an empty string but also instantly expire it #1118 *todd@robotcoop.com* + +* Added AssetTagHelper#image_path, AssetTagHelper#javascript_path, and AssetTagHelper#stylesheet_path #1110 *Larry Halff* + +* Fixed url_for(nil) in functional tests #1116 *Alisdair McDiarmid* + +* Fixed error handling of broken layouts #1115 *Michael Schubert* + +* Added submit_to_remote that allows you to trigger an Ajax form submition at the click of the submission button, which allows for multiple targets in a single form through the use of multiple submit buttons #930 *yrashk@gmail.com* + +* Fixed pagination to work with joins #1034 *scott@sigkill.org* + +* Fixed that *rest parameter in map.connect couldn't accept an empty list #1037 *Dee Zsombor* + +* Added :confirm option to link_to_remote just like link_to has #1082 *yrashk@fp.org.ua* + +* Added minute_step as an option to select_minute (and the helpers that use it) to jump in larger increments than just 1 minute. At 15, it would return 0, 15, 30, 45 options #1085 *ordwaye@evergreen.edu* + +* Fixed that an exception would be thrown when an empty form was submitted #1090 *jan@ulbrich-boerwang.de* + +* Moved TextHelper#human_size to NumberHelper#number_to_human_size, but kept an deprecated alias to the old method name + +* Fixed that the content-type for some browsers could include an additional \r which made wonky things happen #1067 *Thomas Fuchs* + +* Fixed that radio buttons shouldn't have a default size attribute #1074 *hendrik@mans.de* + +* Added ActionView::Helpers::InstanceTag::DEFAULT_RADIO_OPTIONS that contains a hash of default options for radio buttons #1074 *hendrik@mans.de* + +* Fixed that in some circumstances controllers outside of modules may have hidden ones inside modules. For example, admin/content might have been hidden by /content. #1075 *Nicholas Seckar* + +* Added JavascriptHelper#periodically_call_remote in order to create areas of a page that update automatically at a set interval #945 *Jon Tirsen* + +* Fixed Cache#expire_matched_fragments that couldn't recognize the difference between string and url_for options #1030 *Stefan Kaes* + +* Added simulation of @request.request_uri in functional tests #1038 *Jamis Buck* + +* Fixed autolinking to work better in more cases #1013 *Jamis Buck* + +* Added the possible of using symbols in form helpers that relate to instance variables like text_field :account, :name in addition to text_field "account", "name"' + +* Fixed javascript_include_tag to output type instead of language and conform to XHTML #1018 *Rick Olson* + +* Added NumberHelper for common string representations like phone number, currency, and percentage #1015 *DeLynn* + +* Added pagination for scaffolding (10 items per page) #964 *mortonda@dgrmm.net* + +* Added assert_no_cookie and fixed assert_cookie_equal to deal with non-existing cookies #979 *Jeremy Kemper* + +* Fixed :overwrite_param so it doesn't delete but reject elements from @request.parameters #982 *raphinou@yahoo.com* + +* Added :method option to verify for ensuring that either GET, POST, etc is allowed #984 *Jamis Buck* + +* Added options to set cc, bcc, subject, and body for UrlHelper#mail_to #966 *DeLynn* + +* Fixed include_blank for select_hour/minute/second #527 *edward@debian.org* + +* Improved the message display on the exception handler pages #963 *Johan Sorensen* + +* Fixed that on very rare occasions, webrick would raise a NoMethodError: private method 'split' called for nil #1001 *Flurin Egger* + +* Fixed problem with page caching #958 *Rick Olson* + + +## 1.7.0 (27th March, 2005) ## + +* Added ActionController::Base.page_cache_extension for setting the page cache file extension (the default is .html) #903 *Andreas* + +* Fixed "bad environment variable value" exception caused by Safari, Apache, and Ajax calls #918 + +* Fixed that pagination_helper would ignore :params #947 *Sebastian Kanthak* + +* Added :owerwrite_params back to url_for and friends -- it was AWL since the introduction of Routes #921 *raphinou* + +* Added :position option to link_to_remote/form_remote_tag that can be either :before, :top, :bottom, or :after and specifies where the return from the method should be inserted #952 *Matthew McCray/Sam Stephenson* + +* Added Effect.Highlight to prototype.js to do Yellow Fade Technique (of 37signals' fame) on any container #952 *Sam Stephenson/court3nay* + +* Added include_seconds option as the third parameter to distance_of_time_in_words which will render "less than a minute" in higher resolution ("less than 10 seconds" etc) #944 *thomas@fesch.at* + +* Added fourth option to process in test cases to specify the content of the flash #949 *Jamis Buck* + +* Added Verifications that allows you to specify preconditions to actions in form of statements like verify :only => :update_post, :params => "admin_privileges", :redirect_to => { :action => "settings" }, which ensure that the update_post action is only called if admin_privileges is available as a parameter -- otherwise the user is redirected to settings. #897 *Jamis Buck* + +* Fixed Form.Serialize for the JavascriptHelper to also seriliaze password fields #934 *dweitzman@gmail.com* + +* Added JavascriptHelper#escape_javascript as a public method (was private) and made it escape both single and double quotes and new lines #940 *mortonda@dgrmm.net* + +* Added trailing_slash option to url_for, so you can generate urls ending in a slash. Note that is currently not recommended unless you need it for special reasons since it breaks caching #937 *stian@grytoyr.net* + +* Added expire_matched_fragments(regular_expression) to clear out a lot of fragment caches at once #927 *Rick Olson* + +* Fixed the problems with : and ? in file names for fragment caches on Windows #927 *Rick Olson* + +* Added TextHelper#human_size for formatting file sizes, like human_size(1234567) => 1.2 MB #943 *thomas@fesch.at* + +* Fixed link_to :confirm #936 *Nicholas Seckar* + +* Improved error reporting especially around never shallowing exceptions. Debugging helpers should be much easier now #980 *Nicholas Seckar* + +* Fixed Toggle.display in prototype.js #902 *Lucas Carlson* + + +## 1.6.0 (22th March, 2005) ## + +* Added a JavascriptHelper and accompanying prototype.js library that opens the world of Ajax to Action Pack with a large array of options for dynamically interacting with an application without reloading the page #884 *Sam Stephenson/David* + +* Added pagination support through both a controller and helper add-on #817 *Sam Stephenson* + +* Fixed routing and helpers to make Rails work on non-vhost setups #826 *Nicholas Seckar/Tobias Lütke* + +* Added a much improved Flash module that allows for finer-grained control on expiration and allows you to flash the current action #839 [Caio Chassot]. Example of flash.now: + + class SomethingController < ApplicationController + def save + ... + if @something.save + # will redirect, use flash + flash[:message] = 'Save successful' + redirect_to :action => 'list' + else + # no redirect, message is for current action, use flash.now + flash.now[:message] = 'Save failed, review' + render_action 'edit' + end + end + end + +* Added to_param call for parameters when composing an url using url_for from something else than strings #812 [Sam Stephenson]. Example: + + class Page +   def initialize(number) +     @number = number +   end +   # ... +   def to_param +     @number.to_s +   end + end + + You can now use instances of Page with url_for: + + class BarController < ApplicationController +   def baz +     page = Page.new(4) +     url = url_for :page => page # => "http://foo/bar/baz?page=4" +   end + end + +* Fixed form helpers to query Model#id_before_type_cast instead of Model#id as a temporary workaround for Ruby 1.8.2 warnings #818 *DeLynn B* + +* Fixed TextHelper#markdown to use blank? instead of empty? so it can deal with nil strings passed #814 *Johan Sörensen* + +* Added TextHelper#simple_format as a non-dependency text presentation helper #814 *Johan Sörensen* + +* Added that the html options disabled, readonly, and multiple can all be treated as booleans. So specifying disabled => :true will give disabled="disabled". #809 *mindel* + +* Added path collection syntax for Routes that will gobble up the rest of the url and pass it on to the controller #830 [rayners]. Example: + + map.connect 'categories/*path_info', :controller => 'categories', :action => 'show' + + A request for /categories/top-level-cat, would give @params[:path_info] with "top-level-cat". + A request for /categories/top-level-cat/level-1-cat, would give @params[:path_info] with "top-level-cat/level-1-cat" and so forth. + + The @params[:path_info] return is really an array, but where to_s has been overwritten to do join("/"). + +* Fixed options_for_select on selected line issue #624 *Florian Weber* + +* Added CaptureHelper with CaptureHelper#capture and CaptureHelper#content_for. See documentation in helper #837 *Tobias Lütke* + +* Fixed :anchor use in url_for #821 *Nicholas Seckar* + +* Removed the reliance on PATH_INFO as it was causing problems for caching and inhibited the new non-vhost support #822 *Nicholas Seckar* + +* Added assigns shortcut for @response.template.assigns to controller test cases [Jeremy Kemper]. Example: + + Before: + + def test_list + assert_equal 5, @response.template.assigns['recipes'].size + assert_equal 8, @response.template.assigns['categories'].size + end + + After: + + def test_list + assert_equal 5, assigns(:recipes).size + assert_equal 8, assigns(:categories).size + end + +* Added TagHelper#image_tag and deprecated UrlHelper#link_image_to (recommended approach is to combine image_tag and link_to instead) + +* Fixed textilize to be resilient to getting nil parsed (by using Object#blank? instead of String#empty?) + +* Fixed that the :multipart option in FormTagHelper#form_tag would be ignored *Yonatan Feldman* + + +## 1.5.1 (7th March, 2005) ## + +* Fixed that the routes.rb file wouldn't be found on symlinked setups due to File.expand_path #793 *piotr@t-p-l.com* + +* Changed ActiveRecordStore to use Marshal instead of YAML as the latter proved troublesome in persisting circular dependencies. Updating existing applications MUST clear their existing session table from data to start using this updated store #739 *Jamis Buck* + +* Added shortcut :id assignment to render_component and friends (before you had to go through :params) #784 *Lucas Carlson* + +* Fixed that map.connect should convert arguments to strings #780 *Nicholas Seckar* + +* Added UrlHelper#link_to_if/link_to_unless to enable other conditions that just link_to_unless_current #757 *mindel* + +* Fixed that single quote was not escaped in a UrlHelper#link_to javascript confirm #549 *Scott Barron* + +* Removed the default border on link_image_to (it broke xhtml strict) -- can be specified with :border => 0 #517 *?/caleb* + +* Fixed that form helpers would treat string and symbol keys differently in html_options (and possibly create duplicate entries) #112 *Jeremy Kemper* + +* Fixed that broken pipe errors (clients disconnecting in mid-request) could bring down a fcgi process + +* Added the original exception message to session recall errors (so you can see which class wasnt required) + +* Fixed that RAILS_ROOT might not be defined when AP was loaded, so do a late initialization of the ROUTE_FILE #761 *Scott Barron* + +* Fix request.path_info and clear up LoadingModule behavior #754 *Nicholas Seckar* + +* Fixed caching to be aware of extensions (so you can cache files like api.wsdl or logo.png) #734 *Nicholas Seckar* + +* Fixed that Routes would raise NameErrors if a controller component contains characters that are not valid constant names #733 *Nicholas Seckar* + +* Added PATH_INFO access from the request that allows urls like the following to be interpreted by rails: http://www.example.com/dispatcher.cgi/controller/action -- that makes it possible to use rails as a CGI under lighttpd and would also allow (for example) Rublog to be ported to rails without breaking existing links to Rublog-powered blogs. #728 *Jamis Buck* + +* Fixed that caching the root would result in .html not index.html #731, #734 *alisdair/Nicholas Seckar* + + +## 1.5.0 (24th February, 2005) ## + +* Added Routing as a replacement for mod_rewrite pretty urls [Nicholas Seckar]. Read more in ActionController::Base.url_for and on http://manuals.rubyonrails.com/read/book/9 + +* Added components that allows you to call other actions for their rendered response while execution another action. You can either delegate the entire response rendering or you can mix a partial response in with your other content. Read more on http://manuals.rubyonrails.com/read/book/14 + +*  Fixed that proxy IPs do not follow all RFC1918 nets #251 *caleb@aei-tech.com* + +* Added Base#render_to_string to parse a template and get the result back as a string #479 + +* Fixed that send_file/data can work even if render* has been called before in action processing to render the content of a file to be send for example #601 + +* Added FormOptionsHelper#time_zone_select and FormOptionsHelper#time_zone_options_for_select to work with the new value object TimeZone in Active Support #688 *Jamis Buck* + +* Added FormHelper#file_field and FormTagHelper#file_field_tag for creating file upload fields + +* Added :order option for date_select that allows control over the order in which the date dropdowns is used and which of them should be used #619 [Tim Bates]. Examples: + + date_select("post", "written_on", :order => [:day, :month, :year]) + date_select("user", "birthday", :order => [:month, :day]) + +* Added ActionView::Base.register_template_handler for easy integration of an alternative template language to ERb and Builder. See test/controller/custom_handler_test.rb for a usage example #656 *Jamis Buck* + +* Added AssetTagHelper that provides methods for linking a HTML page together with other assets, such as javascripts, stylesheets, and feeds. + +* Added FormTagHelper that provides a number of methods for creating form tags that doesn't rely on conventions with an object assigned to the template like FormHelper does. With the FormTagHelper, you provide the names and values yourself. + +* Added Afghanistan, Iran, and Iraq to the countries list used by FormOptions#country_select and FormOptions#country_options_for_select + +* Renamed link_to_image to link_image_to (since thats what it actually does) -- kept alias for the old method name + +* Fixed textilize for RedCloth3 to keep doing hardbreaks + +* Fixed that assert_template_xpath_matches did not indicate when a path was not found #658 *Eric Hodel* + +* Added TextHelper#auto_link to turn email addresses and urls into ahrefs + +* Fixed that on validation errors, scaffold couldn't find template #654 *mindel* + +* Added Base#hide_action(*names) to hide public methods from a controller that would otherwise have been callable through the URL. For the majority of cases, its preferred just to make the methods you don't want to expose protected or private (so they'll automatically be hidden) -- but if you must have a public method, this is a way to make it uncallable. Base#hidden_actions retrieve the list of all hidden actions for the controller #644 *Nicholas Seckar* + +* Fixed that a bunch of methods from ActionController::Base was accessible as actions (callable through a URL) when they shouldn't have been #644 *Nicholas Seckar* + +* Added UrlHelper#current_page?(options) method to check if the url_for options passed corresponds to the current page + +* Fixed https handling on other ports than 443 *Alan Gano* + +* Added follow_redirect method for functional tests that'll get-request the redirect that was made. Example: + + def test_create_post + post :create, "post" => { "title" => "Exciting!" } + assert_redirected_to :action => "show" + + follow_redirect + assert_rendered_file "post/show" + end + + Limitation: Only works for redirects to other actions within the same controller. + +* Fixed double requiring of models with the same name as the controller + +* Fixed that query params could be forced to nil on a POST due to the raw post fix #562 *moriq@moriq.com* + +* Fixed that cookies shouldn't be frozen in TestRequest #571 *Eric Hodel* + + +## 1.4.0 (January 25th, 2005) ## + +* Fixed problems with ActiveRecordStore under the development environment in Rails + +* Fixed the ordering of attributes in the xml-decleration of Builder #540 *woeye* + +* Added @request.raw_post as a convenience access to @request.env['RAW_POST_DATA'] #534 *Tobias Lütke* + +* Added support for automatic id-based indexing for lists of items #532 [dblack]. Example: + + <% @students.each do |@student| %> + <%= text_field "student[]", "first_name", :size => "20" %> + <%= text_field "student[]", "last_name" %> + <%= text_field "student[]", "grade", :size => "5" %> + <% end %> + + ...would produce, for say David Black with id 123 and a grace of C+: + + + + + +* Added :application_prefix to url_for and friends that makes it easier to setup Rails in non-vhost environments #516 *Jamis Buck* + +* Added :encode option to mail_to that'll allow you to masquarede the email address behind javascript or hex encoding #494 *Lucas Carlson* + +* Fixed that the content-header was being set to application/octet_stream instead of application/octet-stream on send_date/file *Alexey* + +* Removed the need for passing the binding when using CacheHelper#cache + +* Added TestResponse#binary_content that'll return as a string the data sent through send_data/send_file for testing #500 *Alexey* + +* Added @request.env['RAW_POST_DATA'] for people who need access to the data before Ruby's CGI has parsed it #505 *Jeremy Kemper* + +* Fixed that a default fragment store wan't being set to MemoryStore as intended. + +* Fixed that all redirect and render calls now return true, so you can use the pattern of "do and return". Example: + + def show + redirect_to(:action => "login") and return unless @person.authenticated? + render_text "I won't happen unless the person is authenticated" + end + +* Added that renders and redirects called in before_filters will have the same effect as returning false: stopping the chain. Example: + + class WeblogController + before_filter { |c| c.send(:redirect_to_url("http://www.farfaraway.com")}) } + + def hello + render_text "I will never be called" + end + end + + +* Added that only one render or redirect can happen per action. The first call wins and subsequent calls are ignored. Example: + + def do_something + redirect_to :action => "elsewhere" + render_action "overthere" + end + + Only the redirect happens. The rendering call is simply ignored. + + +## 1.3.1 (January 18th, 2005) ## + +* Fixed a bug where cookies wouldn't be set if a symbol was used instead of a string as the key + +* Added assert_cookie_equal to assert the contents of a named cookie + +* Fixed bug in page caching that prevented it from working at all + + +## 1.3.0 (January 17th, 2005) ## + +* Added an extensive caching module that offers three levels of granularity (page, action, fragment) and a variety of stores. + Read more in ActionController::Caching. + +* Added the option of passing a block to ActiveRecordHelper#form in order to add more to the auto-generated form #469 *dom@sisna.com* + + form("entry", :action => "sign") do |form| + form << content_tag("b", "Department") + form << collection_select("department", "id", @departments, "id", "name") + end + +* Added arrays as a value option for params in url_for and friends #467 [Eric Anderson]. Example: + + url_for(:controller => 'user', :action => 'delete', :params => { 'username' => %( paul john steve ) } ) + # => /user/delete?username[]=paul&username[]=john&username[]=steve + +* Fixed that controller tests can now assert on the use of cookies #466 *Alexey* + +* Fixed that send_file would "remember" all the files sent by adding to the headers again and again #458 *Jeremy Kemper* + +* Fixed url rewriter confusion when the controller or action name was a substring of the controller_prefix or action_prefix + +* Added conditional layouts like layout "weblog_standard", :except => :rss #452 *Marcel Molina Jr.* + +* Fixed that MemCacheStore wasn't included by default and added default MemCache object pointing to localhost #447 *Lucas Carlson* + +* Added fourth argument to render_collection_of_partials that allows you to specify local_assigns -- just like render_partial #432 *Ryan Davis* + +* Fixed that host would choke when cgi.host returned nil #432 *Tobias Lütke* + +* Added that form helpers now take an index option #448 *Tim Bates* + + Example: + text_field "person", "name", "index" => 3 + + Becomes: + + +* Fixed three issues with retrying breakpoints #417 *Florian Gross* + + 1. Don't screw up pages that use multiple values for the same parameter (?foo=bar&foo=qux was converted to ?foo=barqux) + 2. Don't screw up all forms when you click the "Retry with Breakpoint" link multiple times instead of reloading + (This caused the parameters to be added multiple times for GET forms leading to trouble.) + 3. Don't add ?BP-RETRY=1 multiple times + +* Added that all renders and redirects now return false, so they can be used as the last line in before_filters to stop execution. + + Before: + def authenticate + unless @session[:authenticated] + redirect_to :controller => "account", :action => "login" + return false + end + end + + After: + def authenticate + redirect_to(:controller => "account", :action => "login") unless @session[:authenticated] + end + +* Added conditional filters #431 [Marcel Molina Jr.]. Example: + + class JournalController < ActionController::Base + # only require authentication if the current action is edit or delete + before_filter :authorize, :only_on => [ :edit, :delete ] + + private + def authorize + # redirect to login unless authenticated + end + end + +* Added Base#render_nothing as a cleaner way of doing render_text "" when you're not interested in returning anything but an empty response. + +* Added the possibility of passing nil to UrlHelper#link_to to use the link itself as the name + + +## 1.2.0 (January 4th, 2005) ## + +* Added MemCacheStore for storing session data in Danga's MemCache system *Bob Cottrell* + Depends on: MemCached server (http://www.danga.com/memcached/), MemCache client (http://raa.ruby-lang.org/project/memcache/) + +* Added thread-safety to the DRbStore #66, #389 *Ben Stiglitz* + +* Added DateHelper#select_time and DateHelper#select_second #373 *Scott Baron* + +* Added :host and :protocol options to url_for and friends to redirect to another host and protocol than the current. + +* Added class declaration for the MissingFile exception #388 *Kent Sibilev* + +* Added "short hypertext note with a hyperlink to the new URI(s)" to redirects to fulfill compliance with RFC 2616 (HTTP/1.1) section 10.3.3 #397 *Tim Bates* + +* Added second boolean parameter to Base.redirect_to_url and Response#redirect to control whether the redirect is permanent or not (301 vs 302) #375 *Hodel* + +* Fixed redirects when the controller and action is named the same. Still haven't fixed same controller, module, and action, though #201 *Josh Peek* + +* Fixed problems with running multiple functional tests in Rails under 1.8.2 by including hack for test/unit weirdness + +* Fixed that @request.remote_ip didn't work in the test environment #369 *Bruno Mattarollo* + + +## 1.1.0 ## + +* Added search through session to clear out association caches at the end of each request. This makes it possible to place Active Record objects + in the session without worrying about stale data in the associations (the main object is still subject to caching, naturally) #347 *Tobias Lütke* + +* Added more informative exception when using helper :some_helper and the helper requires another file that fails, you'll get an + error message tells you what file actually failed to load, rather than falling back on assuming it was the helper file itself #346 *dblack* + +* Added use of *_before_type_cast for all input and text fields. This is helpful for getting "100,000" back on a integer-based + validation where the value would normally be "100". + +* Added Request#port_string to get something like ":8080" back on 8080 and "" on 80 (or 443 with https). + +* Added Request#domain (returns string) and Request#subdomains (returns array). + +* Added POST support for the breakpoint retries, so form processing that raises an exception can be retried with the original request *Florian Gross* + +* Fixed regression with Base#reset_session that wouldn't use the DEFAULT_SESSION_OPTIONS *adam@the-kramers.net* + +* Fixed error rendering of rxml documents to not just swallow the exception and return 0 (still not guessing the right line, but hey) + +* Fixed that textilize and markdown would instantiate their engines even on empty strings. This also fixes #333 *Ulysses* + +* Fixed UrlHelper#link_to_unless so it doesn't care if the id is a string or fixnum *Ryan Davis* + + +## 1.0.1 ## + +* Fixed a bug that would cause an ApplicationController to require itself three times and hence cause filters to be run three times *evl* + + +## 1.0 ## + +* Added that controllers will now attempt to require a model dependency with their name and in a singular attempt for their name. + So both PostController and PostsController will automatically have the post.rb model required. If no model is found, no error is raised, + as it is then expected that no match is available and the programmer will have included his own models. + +* Fixed DateHelper#date_select so that you can pass include_blank as an option even if you don't use start_year and end_year #59 *what-a-day* + +* Added that controllers will now search for a layout in $template_root/layouts/$controller_name.r(html|xml), so PostsController will look + for layouts/posts.rhtml or layouts/posts.rxml and automatically configure this layout if found #307 *Marcel Molina Jr.* + +* Added FormHelper#radio_button to work with radio buttons like its already possible with check boxes *Michael Koziarski* + +* Added TemplateError#backtrace that makes it much easier to debug template errors from unit and functional tests + +* Added display of error messages with scaffolded form pages + +* Added option to ERB templates to swallow newlines by using <% if something -%> instead of just <% if something %>. Example: + + class SomeController < ApplicationController + <% if options[:scaffold] %> + scaffold :<%= singular_name %> + <% end %> + helper :post + + ...produces this on post as singular_name: + + class SomeController < ApplicationController + + scaffold :post + + helper :post + + ...where as: + + class SomeController < ApplicationController + <% if options[:scaffold] -%> + scaffold :<%= singular_name %> + <% end -%> + helper :post + + ...produces: + + class SomeController < ApplicationController + scaffold :post + helper :post + + *This undocumented gem for ERb was uncovered by bitsweat* + +* Fixed CgiRequest so that it'll now accept session options with Symbols as keys (as the documentation points out) *Suggested by Andreas* + +* Added that render_partial will always by default include a counter with value 1 unless there is a counter passed in via the + local_assigns hash that overrides it. As a result, render_collection_of_partials can still be written in terms of render_partial + and partials that make use of a counter can be called without problems from both render_collection_of_partials as well as + render_partial #295 *Marcel Molina Jr.* + +* Fixed CgiRequest#out to fall back to #write if $stdout doesn't have #syswrite *Jeremy Kemper* + +* Fixed all helpers so that they use XHTML compliant double quotes for values instead of single quotes *htonl/Jeremy Kemper* + +* Added link_to_image(src, options = {}, html_options = {}). Documentation: + + Creates a link tag to the image residing at the +src+ using an URL created by the set of +options+. See the valid options in + link:classes/ActionController/Base.html#M000021. It's also possible to pass a string instead of an options hash to + get a link tag that just points without consideration. The html_options works jointly for the image and ahref tag by + letting the following special values enter the options on the image and the rest goes to the ahref: + + ::alt: If no alt text is given, the file name part of the +src+ is used (capitalized and without the extension) + ::size: Supplied as "XxY", so "30x45" becomes width="30" and height="45" + ::align: Sets the alignment, no special features + + The +src+ can be supplied as a... + * full path, like "/my_images/image.gif" + * file name, like "rss.gif", that gets expanded to "/images/rss.gif" + * file name without extension, like "logo", that gets expanded to "/images/logo.png" + +* Fixed to_input_field_tag so it no longer explicitly uses InstanceTag.value if value was specified in the options hash *evl* + +* Added the possibility of having validate be protected for assert_(in)valid_column #263 *Tobias Lütke* + +* Added that ActiveRecordHelper#form now calls url_for on the :action option. + +* Added all the HTTP methods as alternatives to the generic "process" for functional testing #276 [Tobias Lütke]. Examples: + + # Calls Controller#miletone with a GET request + process :milestone + + # Calls Controller#miletone with a POST request that has parameters + post :milestone, { "name" => "David" } + + # Calls Controller#milestone with a HEAD request that has both parameters and session data + head :milestone, { "id" => 1 }, { "user_id" => 23 } + + This is especially useful for testing idiomatic REST web services. + +* Added proper handling of HEAD requests, so that content isn't returned (Request#head? added as well) #277 *Eric Hodel* + +* Added indifference to whether @headers["Content-Type"], @headers["Content-type"], or @headers["content-type"] is used. + +* Added TestSession#session_id that returns an empty string to make it easier to functional test applications that doesn't use + cookie-based sessions #275 *jcf* + +* Fixed that cached template loading would still check the file system to see if the file existed #258 *Andreas Schwarz* + +* Added options to tailor header tag, div id, and div class on ActiveRecordHelper#error_messages_for *Josh Peek* + +* Added graceful handling of non-alphanumeric names and misplaced brackets in input parameters *Jeremy Kemper* + +* Added a new container for cookies that makes them more intuative to use. The old methods of cookie and @cookies have been deprecated. + + Examples for writing: + + cookies["user_name"] = "david" # => Will set a simple session cookie + cookies["login"] = { "value" => "XJ-122", "expires" => Time.now + 360} # => Will set a cookie that expires in 1 hour + + Examples for reading: + + cookies["user_name"] # => "david" + cookies.size # => 2 + + Read more in ActionController::Cookies + + NOTE: If you were using the old accessor (cookies instead of @cookies), this could potentially break your code -- if you expect a full cookie object! + +* Added the opportunity to defined method_missing on a controller which will handle all requests for actions not otherwise defined #223 *timb* + +* Fixed AbstractRequest#remote_ip for users going through proxies - Patch #228 *Eric Hodel* + +* Added Request#ssl? which is shorthand for @request.protocol == "https://" + +* Added the choice to call form_tag with no arguments (resulting in a form posting to current action) *Jeremy Kemper* + +* Upgraded to Builder 1.2.1 + +* Added :module as an alias for :controller_prefix to url_for and friends, so you can do redirect_to(:module => "shop", :controller => "purchases") + and go to /shop/purchases/ + +* Added support for controllers in modules through @params["module"]. + +* Added reloading for dependencies under cached environments like FastCGI and mod_ruby. This makes it possible to use those environments for development. + This is turned on by default, but can be turned off with ActionController::Base.reload_dependencies = false in production environments. + + NOTE: This will only have an effect if you use the new model, service, and observer class methods to mark dependencies. All libraries loaded through + require will be "forever" cached. You can, however, use ActionController::Base.load_or_require("library") to get this behavior outside of the new + dependency style. + +* Added that controllers will automatically require their own helper if possible. So instead of doing: + + class MsgController < ApplicationController + helper :msg + end + + ...you can just do: + + class MsgController < ApplicationController + end + +* Added dependencies_on(layer) to query the dependencies of a controller. Examples: + + MsgController.dependencies_on(:model) # => [ :post, :comment, :attachment ] + MsgController.dependencies_on(:service) # => [ :notification_service ] + MsgController.dependencies_on(:observer) # => [ :comment_observer ] + +* Added a new dependency model with the class methods model, service, and observer. Example: + + class MsgController < ApplicationController + model :post, :comment, :attachment + service :notification_service + observer :comment_observer + end + + These new "keywords" remove the need for explicitly calling 'require' in most cases. The observer method even instantiates the + observer as well as requiring it. + +* Fixed that link_to would escape & in the url again after url_for already had done so + + +## 0.9.5 (28) ## + +* Added helper_method to designate that a given private or protected method you should available as a helper in the view. *Jeremy Kemper* + +* Fixed assert_rendered_file so it actually verifies if that was the rendered file *htonl* + +* Added the option for sharing partial spacer templates just like partials themselves *radsaq* + +* Fixed that Russia was named twice in country_select *alexey* + +* Fixed request_origin to use remote_ip instead of remote_addr *Jeremy Kemper* + +* Fixed link_to breakage when nil was passed for html_options *alexey* + +* Fixed redirect_to on a virtual server setup with apache with a port other than the default where it would forget the port number *seanohalpin* + +* Fixed that auto-loading webrick on Windows would cause file uploads to fail *Jeremy Kemper* + +* Fixed issues with sending files on WEBrick by setting the proper binmode *Jeremy Kemper* + +* Added send_data as an alternative to send_file when the stream is not read off the filesystem but from a database or generated live *Jeremy Kemper* + +* Added a new way to include helpers that doesn't require the include hack and can go without the explicit require. *Jeremy Kemper* + + Before: + + module WeblogHelper + def self.included(controller) #:nodoc: + controller.ancestors.include?(ActionController::Base) ? controller.add_template_helper(self) : super + end + end + + require 'weblog_helper' + class WeblogController < ActionController::Base + include WeblogHelper + end + + After: + + module WeblogHelper + end + + class WeblogController < ActionController::Base + helper :weblog + end + +* Added a default content-type of "text/xml" to .rxml renders *Ryan Platte* + +* Fixed that when /controller/index was requested by the browser, url_for would generates wrong URLs *Ryan Platte* + +* Fixed a bug that would share cookies between users when using FastCGI and mod_ruby *The Robot Co-op* + +* Added an optional third hash parameter to the process method in functional tests that takes the session data to be used *alexey* + +* Added UrlHelper#mail_to to make it easier to create mailto: style ahrefs + +* Added better error messages for layouts declared with the .rhtml extension (which they shouldn't) *geech* + +* Added another case to DateHelper#distance_in_minutes to return "less than a minute" instead of "0 minutes" and "1 minute" instead of "1 minutes" + +* Added a hidden field to checkboxes generated with FormHelper#check_box that will make sure that the unchecked value (usually 0) + is sent even if the checkbox is not checked. This relieves the controller from doing custom checking if the checkbox wasn't + checked. BEWARE: This might conflict with your run-on-the-mill work-around code. *Tobias Lütke* + +* Fixed error_message_on to just use the first if more than one error had been added *Marcel Molina Jr.* + +* Fixed that URL rewriting with /controller/ was working but /controller was not and that you couldn't use :id on index *geech* + +* Fixed a bug with link_to where the :confirm option wouldn't be picked up if the link was a straight url instead of an option hash + +* Changed scaffolding of forms to use

    Tags

    - <%= render :partial => 'tags/form', - :locals => {:form => post_form} %> + <%= render partial: 'tags/form', + locals: {form: post_form} %> +
    <%= post_form.submit %>
    -- cgit v1.2.3 From e1099eb4fdb64b82485843a569ecd5006aa3dad8 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sun, 13 Nov 2011 21:50:18 +0530 Subject: Revert "Update guide to use Ruby 1.9 hash syntax" This reverts commit 50a9de514f8724b04d3681aa9ca228a8ca490909. Reason: Let's keep the guides at 1.8 syntax --- railties/guides/source/getting_started.textile | 88 +++++++++++++------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 8f34e87e9a..8faacdd03e 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -524,10 +524,10 @@ Blog::Application.routes.draw do #... # You can have the root of your site routed with "root" # just remember to delete public/index.html. - root to: "home#index" + root :to => "home#index" -The +root to: "home#index"+ tells Rails to map the root action to the home +The +root :to => "home#index"+ tells Rails to map the root action to the home controller's index action. Now if you navigate to "http://localhost:3000":http://localhost:3000 in your @@ -696,9 +696,9 @@ Open the +app/models/post.rb+ file and edit it: class Post < ActiveRecord::Base - validates :name, presence: true - validates :title, presence: true, - length: { minimum: 5 } + validates :name, :presence => true + validates :title, :presence => true, + :length => { :minimum => 5 } end @@ -725,7 +725,7 @@ open a console that will roll back any changes you make by using rails conso After the console loads, you can use it to work with your application's models: ->> p = Post.new(content: "A new post") +>> p = Post.new(:content => "A new post") => # @@ -758,15 +758,11 @@ def index respond_to do |format| format.html # index.html.erb - format.json { render json: @posts } + format.json { render :json => @posts } end end -TIP: This Guide was written using Ruby 1.9.2. If you are using Ruby 1.8.7, some of -the syntax may look slightly different. For example, the hash syntax changed from -render :json => @posts (1.8.7) to render json: @posts (1.9.2). - +Post.all+ calls the all method on the +Post+ model, which returns all of the posts currently in the database. The result of this call is an array of Post records that we store in an instance variable called +@posts+. @@ -801,7 +797,8 @@ Here's +app/views/posts/index.html.erb+: <%= post.content %> <%= link_to 'Show', post %> <%= link_to 'Edit', edit_post_path(post) %> - <%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete %> + <%= link_to 'Destroy', post, :confirm => 'Are you sure?', + :method => :delete %> <% end %> @@ -869,7 +866,7 @@ def new respond_to do |format| format.html # new.html.erb - format.json { render json: @post } + format.json { render :json => @post } end end @@ -961,11 +958,14 @@ def create respond_to do |format| if @post.save - format.html { redirect_to @post, notice: 'Post was successfully created.' } - format.json { render json: @post, status: :created, location: @post } + format.html { redirect_to(@post, + :notice => 'Post was successfully created.') } + format.json { render :json => @post, + :status => :created, :location => @post } else - format.html { render action: "new" } - format.json { render json: @post.errors, status: :unprocessable_entity } + format.html { render :action => "new" } + format.json { render :json => @post.errors, + :status => :unprocessable_entity } end end end @@ -1003,8 +1003,8 @@ def show @post = Post.find(params[:id]) respond_to do |format| - format.html # show.html.erb - format.json { render json: @post } + format.html # show.html.erb + format.json { render :json => @post } end end @@ -1073,11 +1073,13 @@ def update respond_to do |format| if @post.update_attributes(params[:post]) - format.html { redirect_to @post, notice: 'Post was successfully updated.' } - format.json { head :ok } + format.html { redirect_to(@post, + :notice => 'Post was successfully updated.') } + format.json { render :json => {}, :status => :ok } else - format.html { render action: "edit" } - format.json { render json: @post.errors, status: :unprocessable_entity } + format.html { render :action => "edit" } + format.json { render :json => @post.errors, + :status => :unprocessable_entity } end end end @@ -1213,9 +1215,9 @@ You'll need to edit the +post.rb+ file to add the other side of the association: class Post < ActiveRecord::Base - validates :name, presence: true - validates :title, presence: true, - length: { :minimum: 5 } + validates :name, :presence => true + validates :title, :presence => true, + :length => { :minimum => 5 } has_many :comments end @@ -1557,8 +1559,8 @@ So first, let's add the delete link in the

    <%= link_to 'Destroy Comment', [comment.post, comment], - confirm: 'Are you sure?', - method: :delete %> + :confirm => 'Are you sure?', + :method => :delete %>

    @@ -1600,10 +1602,10 @@ model, +app/models/post.rb+, as follows: class Post < ActiveRecord::Base - validates :name, presence: true - validates :title, presence: true, - length: {minimum: 5} - has_many :comments, dependent: :destroy + validates :name, :presence => true + validates :title, :presence => true, + :length => { :minimum => 5 } + has_many :comments, :dependent => :destroy end @@ -1627,7 +1629,7 @@ action, except for +index+ and +show+, so we write that: class PostsController < ApplicationController - http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show] + http_basic_authenticate_with :name => "dhh", :password => "secret", :except => [:index, :show] # GET /posts # GET /posts.json @@ -1643,7 +1645,7 @@ We also only want to allow authenticated users to delete comments, so in the class CommentsController < ApplicationController - http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy + http_basic_authenticate_with :name => "dhh", :password => "secret", :only => :destroy def create @post = Post.find(params[:post_id]) @@ -1681,14 +1683,15 @@ edit tags via posts: class Post < ActiveRecord::Base - validates :name, presence: true - validates :title, presence: true, - length: {minimum: 5} - has_many :comments, dependent: :destroy + validates :name, :presence => true + validates :title, :presence => true, + :length => { :minimum => 5 } + + has_many :comments, :dependent => :destroy has_many :tags - accepts_nested_attributes_for :tags, allow_destroy: :true, - reject_if: proc { |attrs| attrs.all? { |k, v| v.blank? } } + accepts_nested_attributes_for :tags, :allow_destroy => :true, + :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } end @@ -1726,9 +1729,8 @@ We will modify +views/posts/_form.html.erb+ to render a partial to make a tag: <%= post_form.text_area :content %>

    Tags

    - <%= render partial: 'tags/form', - locals: {form: post_form} %> - + <%= render :partial => 'tags/form', + :locals => {:form => post_form} %>
    <%= post_form.submit %>
    -- cgit v1.2.3 From c8c08bd000c00817d2f17f560f392965fd82229b Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sun, 13 Nov 2011 21:57:39 +0530 Subject: Revert "Use rails help new instead of rails new -h" This reverts commit 6ac65c92029d3eefd101f9458d86bae0314cd14c. --- railties/guides/source/getting_started.textile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 8faacdd03e..98e7c93dc7 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -263,7 +263,8 @@ $ rails new blog This will create a Rails application called Blog in a directory called blog. TIP: You can see all of the switches that the Rails application builder accepts -by running rails help new. +by running +rails new -h. After you create the blog application, switch to its folder to continue work directly in that application: -- cgit v1.2.3 From af51409de433f14d251f7f229a2f651d3ddf7b1c Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sun, 13 Nov 2011 22:07:54 +0530 Subject: Revert "Move Tip up higher so users who are fine with SQLite can skip to the next section" This reverts commit 4bf057b8661754948681a18cf17ff5676518d774. Reason: Prefer to keep the configuration of all databases at the same level --- railties/guides/source/getting_started.textile | 34 ++++++++++++-------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 98e7c93dc7..9e774ff298 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -335,17 +335,7 @@ and PostgreSQL "out of the box", and has plugins for many database systems. If you are using a database in a production environment Rails most likely has an adapter for it. -h5. Other database configuration options - -TIP: You don't have to update the database configurations manually. If you look at the -options of the application generator, you will see that one of the options -is named --database. This option allows you to choose an adapter from a -list of the most used relational databases. You can even run the generator -repeatedly: cd .. && rails new blog --database=mysql. When you confirm the overwriting - of the +config/database.yml+ file, your application will be configured for MySQL -instead of SQLite. - -h6. Configuring a MySQL Database +h5. Configuring a MySQL Database If you choose to use MySQL instead of the shipped SQLite3 database, your +config/database.yml+ will look a little different. Here's the development @@ -366,7 +356,7 @@ If your development computer's MySQL installation includes a root user with an empty password, this configuration should work for you. Otherwise, change the username and password in the +development+ section as appropriate. -h6. Configuring a PostgreSQL Database +h5. Configuring a PostgreSQL Database If you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases: @@ -381,9 +371,9 @@ development: password: -h6. Configuring an SQLite3 Database for JRuby Platform +h5. Configuring an SQLite3 Database for JRuby Platform -If you choose to use SQLite3 and using JRuby, your +config/database.yml+ will +If you choose to use SQLite3 and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section: @@ -392,9 +382,9 @@ development: database: db/development.sqlite3 -h6. Configuring a MySQL Database for JRuby Platform +h5. Configuring a MySQL Database for JRuby Platform -If you choose to use MySQL and using JRuby, your +config/database.yml+ will look +If you choose to use MySQL and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section: @@ -405,9 +395,9 @@ development: password: -h6. Configuring a PostgreSQL Database for JRuby Platform +h5. Configuring a PostgreSQL Database for JRuby Platform -Finally if you choose to use PostgreSQL and using JRuby, your +Finally if you choose to use PostgreSQL and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section: @@ -422,6 +412,14 @@ development: Change the username and password in the +development+ section as appropriate. +TIP: You don't have to update the database configurations manually. If you look at the +options of the application generator, you will see that one of the options +is named --database. This option allows you to choose an adapter from a +list of the most used relational databases. You can even run the generator +repeatedly: cd .. && rails new blog --database=mysql. When you confirm the overwriting + of the +config/database.yml+ file, your application will be configured for MySQL +instead of SQLite. + h4. Creating the Database Now that you have your database configured, it's time to have Rails create an -- cgit v1.2.3 From 30122307a1fe6645d6a75dedceca40a440f2f969 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Sun, 13 Nov 2011 22:27:44 +0530 Subject: copy edits in getting started guide --- railties/guides/source/getting_started.textile | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 9e774ff298..5f370615ca 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -221,8 +221,7 @@ h3. Creating a New Rails Project The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can -literally follow along step by step. If you need to see the completed code, you -can download it from "Getting Started Code":https://github.com/mikel/getting-started-code. +literally follow along step by step. You can get the complete code "here":https://github.com/lifo/docrails/tree/master/railties/guides/code/getting_started. By following along with this guide, you'll create a Rails project called blog, a (very) simple weblog. Before you can start building the application, you need to @@ -246,7 +245,7 @@ To verify that you have everything installed correctly, you should be able to ru the following: -# rails --version +$ rails --version If it says something like "Rails 3.1.1" you are ready to continue. @@ -273,7 +272,7 @@ directly in that application: $ cd blog
    -The 'rails new blog' command we ran above created a folder in your working directory +The 'rails new blog' command we ran above created a folder in your working directory called blog. The blog folder has a number of auto-generated folders that make up the structure of a Rails application. Most of the work in this tutorial will happen in the app/ folder, but here's a basic @@ -304,7 +303,7 @@ this file in a new Rails application, you'll see a default database configured to use SQLite3. The file contains sections for three different environments in which Rails can run by default: -* The +development+ environment is used on your development/local computer as you interact +* The +development+ environment is used on your development/local computer as you interact manually with the application. * The +test+ environment is used when running automated tests. * The +production+ environment is used when you deploy your application for the world to use. @@ -514,8 +513,7 @@ file_ which holds entries in a special DSL (domain-specific language) that tells Rails how to connect incoming requests to controllers and actions. This file contains many sample routes on commented lines, and one of them actually shows you how to connect the root of your site to a specific controller and action. -Find the line beginning with +root :to+, uncomment it by removing the pound sign -at the beginning of the line. It should look something like the following: +Find the line beginning with +root :to+ and uncomment it. It should look something like the following: Blog::Application.routes.draw do @@ -608,11 +606,11 @@ class CreatePosts < ActiveRecord::Migration end -The above migration has one method named +change+ which will be called when you +The above migration creates a method named +change+ which will be called when you run this migration. The action defined in this method is also reversible, which means Rails knows how to reverse the change made by this migration, in case you -want to reverse it at later date. When you run this migration it will create a -+posts+ table with two string columns and a text column. It also creates two +want to reverse it later. When you run this migration it will create a ++posts+ table with two string columns and a text column. It also creates two timestamp fields to allow Rails to track post creation and update times. More information about Rails migrations can be found in the "Rails Database Migrations":migrations.html guide. @@ -704,7 +702,7 @@ end These changes will ensure that all posts have a name and a title, and that the title is at least five characters long. Rails can validate a variety of conditions in a model, including the presence or uniqueness of columns, their -format, and the existence of associated objects. Validations are covered in detail +format, and the existence of associated objects. Validations are covered in detail in "Active Record Validations and Callbacks":active_record_validations_callbacks.html#validations-overview h4. Using the Console @@ -747,7 +745,7 @@ while the console is open, type +reload!+ at the console prompt to load them. h4. Listing All Posts Let's dive into the Rails code a little deeper to see how the application is -showing us the list of Posts. Open the file +showing us the list of Posts. Open the file +app/controllers/posts_controller.rb+ and look at the +index+ action: @@ -762,9 +760,8 @@ def index end -+Post.all+ calls the all method on the +Post+ model, which returns all of -the posts currently in the database. The result of this call is an array -of Post records that we store in an instance variable called +@posts+. ++Post.all+ returns all of the posts currently in the database as an array +of +Post+ records that we store in an instance variable called +@posts+. TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html. -- cgit v1.2.3 From 8971cca7d0cef3ce452bf44fb09ae628419d8ea1 Mon Sep 17 00:00:00 2001 From: Jason Noble Date: Sun, 13 Nov 2011 10:20:03 -0700 Subject: Move tooltip on re-running rails new with a different --database option --- railties/guides/source/getting_started.textile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 8a0a70efad..fde83ae730 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -308,6 +308,14 @@ manually with the application. * The +test+ environment is used when running automated tests. * The +production+ environment is used when you deploy your application for the world to use. +TIP: You don't have to update the database configurations manually. If you look at the +options of the application generator, you will see that one of the options +is named --database. This option allows you to choose an adapter from a +list of the most used relational databases. You can even run the generator +repeatedly: cd .. && rails new blog --database=mysql. When you confirm the overwriting + of the +config/database.yml+ file, your application will be configured for MySQL +instead of SQLite. Detailed examples of the common database connections are below. + h5. Configuring an SQLite3 Database Rails comes with built-in support for "SQLite3":http://www.sqlite.org, which is @@ -411,14 +419,6 @@ development: Change the username and password in the +development+ section as appropriate. -TIP: You don't have to update the database configurations manually. If you look at the -options of the application generator, you will see that one of the options -is named --database. This option allows you to choose an adapter from a -list of the most used relational databases. You can even run the generator -repeatedly: cd .. && rails new blog --database=mysql. When you confirm the overwriting - of the +config/database.yml+ file, your application will be configured for MySQL -instead of SQLite. - h4. Creating the Database Now that you have your database configured, it's time to have Rails create an -- cgit v1.2.3 From 8f0085a483ebc6d416e902c3caff68f82934e091 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Sun, 13 Nov 2011 10:19:54 -1000 Subject: change tests to expect X-F-F over REMOTE_ADDR --- actionpack/test/dispatch/request_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index a611252b31..4658eeea17 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -36,7 +36,7 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'REMOTE_ADDR' => '1.2.3.4', 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' - assert_equal '1.2.3.4', request.remote_ip + assert_equal '3.4.5.6', request.remote_ip request = stub_request 'REMOTE_ADDR' => '127.0.0.1', 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' @@ -106,7 +106,7 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'REMOTE_ADDR' => '67.205.106.74,172.16.0.1', 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' - assert_equal '67.205.106.74', request.remote_ip + assert_equal '3.4.5.6', request.remote_ip request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,67.205.106.73' assert_equal 'unknown', request.remote_ip -- cgit v1.2.3 From 2189bff732490aa842c88f1691993520fa1eb9ab Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Sun, 13 Nov 2011 10:20:29 -1000 Subject: correctly raise IpSpoofAttackError message --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 3b813b03bb..3208256d56 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -51,8 +51,8 @@ module ActionDispatch if check_ip && !forwarded_ips.include?(client_ip) # We don't know which came from the proxy, and which from the user raise IpSpoofAttackError, "IP spoofing attack?!" \ - "HTTP_CLIENT_IP=#{env['HTTP_CLIENT_IP'].inspect}" \ - "HTTP_X_FORWARDED_FOR=#{env['HTTP_X_FORWARDED_FOR'].inspect}" + "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \ + "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" end client_ip || forwarded_ips.last || remote_addrs.last -- cgit v1.2.3 From 2d063c6269a546c8bab4b36c027246f582bfaa13 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Sun, 13 Nov 2011 10:20:55 -1000 Subject: turns out the tests expect remote_addrs.first --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 3208256d56..5f81b639ae 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -55,7 +55,7 @@ module ActionDispatch "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" end - client_ip || forwarded_ips.last || remote_addrs.last + client_ip || forwarded_ips.last || remote_addrs.first end protected -- cgit v1.2.3 From 9c4532bf74604ae1c52a44d1aa8c1022a312ff88 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Sun, 13 Nov 2011 10:22:12 -1000 Subject: remove ignored flag, fixes warnings --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 5f81b639ae..58e25aed5a 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -19,7 +19,7 @@ module ActionDispatch @app = app @check_ip_spoofing = check_ip_spoofing if custom_proxies - custom_regexp = Regexp.new(custom_proxies, "i") + custom_regexp = Regexp.new(custom_proxies) @trusted_proxies = Regexp.union(TRUSTED_PROXIES, custom_regexp) else @trusted_proxies = TRUSTED_PROXIES -- cgit v1.2.3 From e0eb2292bb8dfce150cd7c1d9948beff14f0cd7c Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Mon, 14 Nov 2011 06:25:03 -0500 Subject: Upgrade Sprockets to 2.1.0 This version brings bug fixes for performance and caching. --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index a446531a6b..9da9143de3 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency('rack', '~> 1.3.5') s.add_dependency('rack-test', '~> 0.6.1') s.add_dependency('journey', '~> 1.0.0') - s.add_dependency('sprockets', '~> 2.1.0.beta') + s.add_dependency('sprockets', '~> 2.1.0') s.add_dependency('erubis', '~> 2.7.0') s.add_development_dependency('tzinfo', '~> 0.3.29') -- cgit v1.2.3 From da02f792fe78535628f86bf983308800207b4225 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 14 Nov 2011 11:28:12 +0000 Subject: Sync CHANGELOGs from 3-1-stable --- actionpack/CHANGELOG.md | 11 +++++++++++ activerecord/CHANGELOG.md | 21 +++++++++++++++++++++ railties/CHANGELOG.md | 10 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 74711c0320..3e2dbe4e13 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -64,6 +64,15 @@ ## Rails 3.1.2 (unreleased) ## +* Ensure that the format isn't applied twice to the cache key, else it becomes impossible + to target with expire_action. + + *Christopher Meiklejohn* + +* Swallow error when can't unmarshall object from session. + + *Bruno Zanchet* + * Implement a workaround for a bug in ruby-1.9.3p0 where an error would be raised while attempting to convert a template from one encoding to another. @@ -76,6 +85,8 @@ *Jon Leighton* +* Ensure users upgrading from 3.0.x to 3.1.x will properly upgrade their flash object in session (issues #3298 and #2509) + ## Rails 3.1.1 (unreleased) ## * javascript_path and stylesheet_path now refer to /assets if asset pipelining diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index a79f4df570..65578c1dc9 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -67,6 +67,27 @@ ## Rails 3.1.2 (unreleased) ## +* Fix bug with PostgreSQLAdapter#indexes. When the search path has multiple schemas, spaces + were not being stripped from the schema names after the first. + + *Sean Kirby* + +* Preserve SELECT columns on the COUNT for finder_sql when possible. *GH 3503* + + *Justin Mazzi* + +* Reset prepared statement cache when schema changes impact statement results. *GH 3335* + + *Aaron Patterson* + +* Postgres: Do not attempt to deallocate a statement if the connection is no longer active. + + *Ian Leitch* + +* Prevent QueryCache leaking database connections. *GH 3243* + + *Mark J. Titorenko* + * Fix bug where building the conditions of a nested through association could potentially modify the conditions of the through and/or source association. If you have experienced bugs with conditions appearing in the wrong queries when using nested through associations, diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 0c59f59917..b05ac21b49 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -30,6 +30,16 @@ Plugins developers need to special case their initializers that are meant to be run in the assets group by adding :group => :assets. +## Rails 3.1.2 (unreleased) ## + +* Engines: don't blow up if db/seeds.rb is missing. + + *Jeremy Kemper* + +* `rails new foo --skip-test-unit` should not add the `:test` task to the rake default task. + *GH 2564* + + *José Valim* ## Rails 3.1.0 (August 30, 2011) ## -- cgit v1.2.3 From c7b84689a4d59b9f2c5773b6a8527adb68e04560 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 14 Nov 2011 11:29:57 +0000 Subject: Add note about syncing CHANGELOGs --- RELEASING_RAILS.rdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RELEASING_RAILS.rdoc b/RELEASING_RAILS.rdoc index cbc9d0e1de..b7ebc4600c 100644 --- a/RELEASING_RAILS.rdoc +++ b/RELEASING_RAILS.rdoc @@ -81,6 +81,10 @@ You can review the commits for the 3.0.10 release like this: [aaron@higgins rails (3-0-10)]$ git log v3.0.9.. +If you're doing a stable branch release, you should also ensure that all of +the CHANGELOG entries in the stable branch are also synced to the master +branch. + === Update the RAILS_VERSION file to include the RC. === Release the gem. -- cgit v1.2.3 From 49cd6a0ff7a3f5b0e85707961c952bdc3b0a178f Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Mon, 14 Nov 2011 07:07:38 -0500 Subject: Added therubyrhino to default Gemfile under JRuby --- railties/lib/rails/generators/app_base.rb | 1 + railties/test/generators/app_generator_test.rb | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 0a79d6e86e..3fbde0d989 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -199,6 +199,7 @@ module Rails group :assets do gem 'sass-rails', :git => 'git://github.com/rails/sass-rails.git' gem 'coffee-rails', :git => 'git://github.com/rails/coffee-rails.git' + #{"gem 'therubyrhino'\n" if defined?(JRUBY_VERSION)} gem 'uglifier', '>= 1.0.3' end GEMFILE diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 955ed09361..a1bd2fbaa5 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -208,6 +208,13 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "test/performance/browsing_test.rb" end + def test_inclusion_of_therubyrhino_under_jruby + if defined?(JRUBY_VERSION) + run_generator([destination_root]) + assert_file "Gemfile", /gem\s+["']therubyrhino["']$/ + end + end + def test_creation_of_a_test_directory run_generator assert_file 'test' -- cgit v1.2.3 From 4d8081b6e7ffa88b4fc74187fb1599ef9b27e6ed Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 14 Nov 2011 12:08:03 +0000 Subject: Add note about checking postgres tests before release --- RELEASING_RAILS.rdoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RELEASING_RAILS.rdoc b/RELEASING_RAILS.rdoc index b7ebc4600c..bd75b36b2a 100644 --- a/RELEASING_RAILS.rdoc +++ b/RELEASING_RAILS.rdoc @@ -25,6 +25,12 @@ for Rails. You can check the status of his tests here: Do not release with Red AWDwR tests. +=== Are the postgres tests green? If not, make them green + +Currently Travis CI doesn't run the Active Record postgres tests. They are +working to resolve this, but in the mean time, it is crucial to ensure that +the tests are still green before release. + === Do we have any git dependencies? If so, contact those authors. Having git dependencies indicates that we depend on unreleased code. @@ -60,6 +66,8 @@ for today: === Is Sam Ruby happy? If not, make him happy. +=== Are the postgres tests green? If not, make them green + === Contact the security team. CVE emails must be sent on this day. === Create a release branch. -- cgit v1.2.3 From ca3b4689375f0f65275407f28981c58a15d50193 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 14 Nov 2011 12:23:43 +0000 Subject: Sync changelog entry --- actionpack/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 3e2dbe4e13..4c265c41d8 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -64,6 +64,8 @@ ## Rails 3.1.2 (unreleased) ## +* Upgrade sprockets dependency to ~> 2.1.0 + * Ensure that the format isn't applied twice to the cache key, else it becomes impossible to target with expire_action. -- cgit v1.2.3 From af64ac4e5ce8406137d5520fa88e8f652ab703e9 Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Mon, 14 Nov 2011 16:56:05 +0100 Subject: use any? instead of !empty? --- activemodel/lib/active_model/dirty.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 166cccf161..026f077ee7 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -98,7 +98,7 @@ module ActiveModel # person.name = 'bob' # person.changed? # => true def changed? - !changed_attributes.empty? + changed_attributes.any? end # List of attributes with unsaved changes. -- cgit v1.2.3 From 156784fef1f66dddcdfb753839f2d37bbee41655 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 14 Nov 2011 16:51:02 +0000 Subject: rake release should push the tag --- tasks/release.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/release.rb b/tasks/release.rb index 33aaee5a4b..191c014f9f 100644 --- a/tasks/release.rb +++ b/tasks/release.rb @@ -116,6 +116,7 @@ namespace :all do task :tag do sh "git tag #{tag}" + sh "git push --tags" end task :release => %w(ensure_clean_state build commit tag push) -- cgit v1.2.3 From be777b30d581aa3488f1c7be14783b58a1567b82 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 14 Nov 2011 17:08:24 +0000 Subject: Add a note to REALEASING_RAILS about testing the gem locally before releasing --- RELEASING_RAILS.rdoc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RELEASING_RAILS.rdoc b/RELEASING_RAILS.rdoc index bd75b36b2a..1dfcfe2488 100644 --- a/RELEASING_RAILS.rdoc +++ b/RELEASING_RAILS.rdoc @@ -95,6 +95,14 @@ branch. === Update the RAILS_VERSION file to include the RC. +=== Build and test the gem. + +Run `rake install` to generate the gems and install them locally. Then try +generating a new app and ensure that nothing explodes. + +This will stop you looking silly when you push an RC to rubygems.org and then +realise it is broken. + === Release the gem. IMPORTANT: Due to YAML parse problems on the rubygems.org server, it is safest @@ -162,6 +170,7 @@ Today, do this stuff in this order: * Apply security patches to the release branch * Update CHANGELOG with security fixes. * Update RAILS_VERSION to remove the rc +* Build and test the gem * Release the gems * Email security lists * Email general announcement lists -- cgit v1.2.3 From 9fa329b7544b15cdf5751d518e380abc82468df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 14 Nov 2011 20:12:17 +0100 Subject: Speed up attribute invocation by checking if both name and calls are compilable. --- activemodel/lib/active_model/attribute_methods.rb | 59 ++++++++++++---------- .../lib/active_record/attribute_methods/read.rb | 2 +- .../lib/active_record/attribute_methods/write.rb | 2 +- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index ef0b95424e..e69cb5c459 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -57,7 +57,8 @@ module ActiveModel module AttributeMethods extend ActiveSupport::Concern - COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?=]?\z/ + NAME_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?=]?\z/ + CALL_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?]?\z/ included do class_attribute :attribute_method_matchers, :instance_writer => false @@ -112,7 +113,7 @@ module ActiveModel # If we can compile the method name, do it. Otherwise use define_method. # This is an important *optimization*, please don't change it. define_method # has slower dispatch and consumes more memory. - if name =~ COMPILABLE_REGEXP + if name =~ NAME_COMPILABLE_REGEXP sing.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{name}; #{value.nil? ? 'nil' : value.to_s.inspect}; end RUBY @@ -240,18 +241,7 @@ module ActiveModel attribute_method_matchers.each do |matcher| matcher_new = matcher.method_name(new_name).to_s matcher_old = matcher.method_name(old_name).to_s - - if matcher_new =~ COMPILABLE_REGEXP && matcher_old =~ COMPILABLE_REGEXP - module_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{matcher_new}(*args) - send(:#{matcher_old}, *args) - end - RUBY - else - define_method(matcher_new) do |*args| - send(matcher_old, *args) - end - end + define_optimized_call self, matcher_new, matcher_old end end @@ -293,17 +283,7 @@ module ActiveModel if respond_to?(generate_method) send(generate_method, attr_name) else - if method_name =~ COMPILABLE_REGEXP - defn = "def #{method_name}(*args)" - else - defn = "define_method(:'#{method_name}') do |*args|" - end - - generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 - #{defn} - send(:#{matcher.method_missing_target}, '#{attr_name}', *args) - end - RUBY + define_optimized_call generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s end end end @@ -342,11 +322,11 @@ module ActiveModel # used to alleviate the GC, which ultimately also speeds up the app # significantly (in our case our test suite finishes 10% faster with # this cache). - def attribute_method_matchers_cache + def attribute_method_matchers_cache #:nodoc: @attribute_method_matchers_cache ||= {} end - def attribute_method_matcher(method_name) + def attribute_method_matcher(method_name) #:nodoc: if attribute_method_matchers_cache.key?(method_name) attribute_method_matchers_cache[method_name] else @@ -359,6 +339,31 @@ module ActiveModel end end + # Define a method `name` in `mod` that dispatches to `send` + # using the given `extra` args. This fallbacks `define_method` + # and `send` if the given names cannot be compiled. + def define_optimized_call(mod, name, send, *extra) #:nodoc: + if name =~ NAME_COMPILABLE_REGEXP + defn = "def #{name}(*args)" + else + defn = "define_method(:'#{name}') do |*args|" + end + + extra = (extra.map(&:inspect) << "*args").join(", ") + + if send =~ CALL_COMPILABLE_REGEXP + target = "#{send}(#{extra})" + else + target = "send(:'#{send}', #{extra})" + end + + mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1 + #{defn} + #{target} + end + RUBY + end + class AttributeMethodMatcher attr_reader :prefix, :suffix, :method_missing_target diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 4174e4da09..4a5afcd585 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -77,7 +77,7 @@ module ActiveRecord # # The second, slower, branch is necessary to support instances where the database # returns columns with extra stuff in (like 'my_column(omg)'). - if method_name =~ ActiveModel::AttributeMethods::COMPILABLE_REGEXP + if method_name =~ ActiveModel::AttributeMethods::NAME_COMPILABLE_REGEXP generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ def _#{method_name} #{access_code} diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index e9cdb130db..eb585ee906 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -10,7 +10,7 @@ module ActiveRecord module ClassMethods protected def define_method_attribute=(attr_name) - if attr_name =~ ActiveModel::AttributeMethods::COMPILABLE_REGEXP + if attr_name =~ ActiveModel::AttributeMethods::NAME_COMPILABLE_REGEXP generated_attribute_methods.module_eval("def #{attr_name}=(new_value); write_attribute('#{attr_name}', new_value); end", __FILE__, __LINE__) else generated_attribute_methods.send(:define_method, "#{attr_name}=") do |new_value| -- cgit v1.2.3 From 00a0a4ddebe0160f851d28e29d5fb7e8e7a2a5dc Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Mon, 14 Nov 2011 11:20:20 -1000 Subject: cleaner names --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 58e25aed5a..446fcce823 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -13,16 +13,16 @@ module ActionDispatch )\. }x - attr_reader :check_ip_spoofing, :trusted_proxies + attr_reader :check_ip, :proxies def initialize(app, check_ip_spoofing = true, custom_proxies = nil) @app = app - @check_ip_spoofing = check_ip_spoofing + @check_ip = check_ip_spoofing if custom_proxies custom_regexp = Regexp.new(custom_proxies) - @trusted_proxies = Regexp.union(TRUSTED_PROXIES, custom_regexp) + @proxies = Regexp.union(TRUSTED_PROXIES, custom_regexp) else - @trusted_proxies = TRUSTED_PROXIES + @proxies = TRUSTED_PROXIES end end @@ -47,7 +47,7 @@ module ActionDispatch forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR') remote_addrs = ips_from('REMOTE_ADDR') - check_ip = client_ip && @middleware.check_ip_spoofing + check_ip = client_ip && @middleware.check_ip if check_ip && !forwarded_ips.include?(client_ip) # We don't know which came from the proxy, and which from the user raise IpSpoofAttackError, "IP spoofing attack?!" \ @@ -62,7 +62,7 @@ module ActionDispatch def ips_from(header) ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : [] - ips.reject{|ip| ip =~ @middleware.trusted_proxies } + ips.reject{|ip| ip =~ @middleware.proxies } end end -- cgit v1.2.3 From cda1a5d5fe002ca92aca01586e8a60439605f960 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Mon, 14 Nov 2011 11:20:57 -1000 Subject: memoize the relatively expensive remote IP code --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 446fcce823..ee0d19a50d 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -42,7 +42,7 @@ module ActionDispatch # HTTP_X_FORWARDED_FOR may be a comma-delimited list in the case of # multiple chained proxies. The last address which is not a known proxy # will be the originating IP. - def to_s + def calculate_ip client_ip = @env['HTTP_CLIENT_IP'] forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR') remote_addrs = ips_from('REMOTE_ADDR') @@ -58,6 +58,12 @@ module ActionDispatch client_ip || forwarded_ips.last || remote_addrs.first end + def to_s + return @ip if @calculated_ip + @calculated_ip = true + @ip = calculate_ip + end + protected def ips_from(header) -- cgit v1.2.3 From 4f2bf6491cbc482d25a9357c2eb7fc8047d4f12e Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Mon, 14 Nov 2011 11:22:44 -1000 Subject: Return the calculated remote_ip or ip This was an especially nasty bug introduced in 317f4e2, by the way that an instance of GetIp is not nil, but GetIp#to_s could sometimes return nil. Gross, huh? --- actionpack/lib/action_dispatch/http/request.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 69ca050d0c..b10f6b48c7 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -157,7 +157,8 @@ module ActionDispatch # Originating IP address, usually set by the RemoteIp middleware. def remote_ip - @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s + # Coerce the remote_ip object into a string, because to_s could return nil + @remote_ip ||= @env["action_dispatch.remote_ip"].to_s || ip end # Returns the unique request id, which is based off either the X-Request-Id header that can -- cgit v1.2.3 From b8c85de62004868a34a27e58731f2a9e37aeebd0 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Mon, 14 Nov 2011 12:29:51 -1000 Subject: add test for bug fixed in 4f2bf64 --- actionpack/test/dispatch/request_test.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 4658eeea17..4d805464c2 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -89,6 +89,11 @@ class RequestTest < ActiveSupport::TestCase assert_equal '9.9.9.9', request.remote_ip end + test "remote ip when the remote ip middleware returns nil" do + request = stub_request 'REMOTE_ADDR' => '127.0.0.1' + assert_equal '127.0.0.1', request.remote_ip + end + test "remote ip with user specified trusted proxies" do @trusted_proxies = /^67\.205\.106\.73$/i -- cgit v1.2.3 From d743954792ccf5975a11ee88cdd690e8f1915728 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Mon, 14 Nov 2011 16:43:21 -1000 Subject: GetIp#to_s should never return nil. That's icky. --- actionpack/lib/action_dispatch/http/request.rb | 5 ++--- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 9 ++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index b10f6b48c7..0e8bd0bd6d 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -155,10 +155,9 @@ module ActionDispatch @ip ||= super end - # Originating IP address, usually set by the RemoteIp middleware. + # Originating IP address from the RemoteIp middleware. def remote_ip - # Coerce the remote_ip object into a string, because to_s could return nil - @remote_ip ||= @env["action_dispatch.remote_ip"].to_s || ip + @remote_ip ||= @env["action_dispatch.remote_ip"] end # Returns the unique request id, which is based off either the X-Request-Id header that can diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index ee0d19a50d..77aa4e743e 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -55,7 +55,10 @@ module ActionDispatch "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" end - client_ip || forwarded_ips.last || remote_addrs.first + not_proxy = client_ip || forwarded_ips.last || remote_addrs.first + + # Return first REMOTE_ADDR if there are no other options + not_proxy || ips_from('REMOTE_ADDR', :all).first end def to_s @@ -66,9 +69,9 @@ module ActionDispatch protected - def ips_from(header) + def ips_from(header, allow_proxies = false) ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : [] - ips.reject{|ip| ip =~ @middleware.proxies } + allow_proxies ? ips : ips.reject{|ip| ip =~ @middleware.proxies } end end -- cgit v1.2.3 From e1b79c56bef43d858fc59dbe7506039414c9e4ed Mon Sep 17 00:00:00 2001 From: Gabriel Sobrinho Date: Tue, 1 Nov 2011 08:40:30 -0200 Subject: Failing test case for issue #3483 --- activerecord/test/cases/finder_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 69754d23b9..688679f081 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -374,6 +374,10 @@ class FinderTest < ActiveRecord::TestCase assert_equal [1], Comment.find(:all, :conditions => { :id => 1..1, :post_id => 1..10 }).map(&:id).sort end + def test_find_on_hash_conditions_with_array_of_integers_and_ranges + assert_equal [1,2,3], Comment.find(:all, :conditions => { :post_id => [1..2, 3, 4, 5..10]}).map(&:id).sort + end + def test_find_on_multiple_hash_conditions assert Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => false }) assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) } -- cgit v1.2.3 From 63a22ca6169f06d10cd843ea3a75df6498fdcf7d Mon Sep 17 00:00:00 2001 From: Ryan Naughton Date: Mon, 14 Nov 2011 21:43:27 -0600 Subject: Fixes issue #3483, regarding using a mixture of ranges and discrete values in find conditions. Paired with Joey Schoblaska. --- .../lib/active_record/relation/predicate_builder.rb | 14 ++++++++------ activerecord/test/cases/finder_test.rb | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 7e8ddd1b5d..af167dc59b 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -22,21 +22,23 @@ module ActiveRecord value = value.select(value.klass.arel_table[value.klass.primary_key]) if value.select_values.empty? attribute.in(value.arel.ast) when Array, ActiveRecord::Associations::CollectionProxy - values = value.to_a.map { |x| - x.is_a?(ActiveRecord::Base) ? x.id : x - } + values = value.to_a.map {|x| x.is_a?(ActiveRecord::Base) ? x.id : x} + ranges, values = values.partition {|value| value.is_a?(Range) || value.is_a?(Arel::Relation)} + + array_predicates = ranges.map {|range| attribute.in(range)} if values.include?(nil) values = values.compact if values.empty? - attribute.eq nil + array_predicates << attribute.eq(nil) else - attribute.in(values.compact).or attribute.eq(nil) + array_predicates << attribute.in(values.compact).or(attribute.eq(nil)) end else - attribute.in(values) + array_predicates << attribute.in(values) end + array_predicates.inject {|composite, predicate| composite.or(predicate)} when Range, Arel::Relation attribute.in(value) when ActiveRecord::Base diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 688679f081..05c4b15407 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -375,7 +375,7 @@ class FinderTest < ActiveRecord::TestCase end def test_find_on_hash_conditions_with_array_of_integers_and_ranges - assert_equal [1,2,3], Comment.find(:all, :conditions => { :post_id => [1..2, 3, 4, 5..10]}).map(&:id).sort + assert_equal [1,2,3,5,6,7,8,9], Comment.find(:all, :conditions => {:id => [1..2, 3, 5, 6..8, 9]}).map(&:id).sort end def test_find_on_multiple_hash_conditions -- cgit v1.2.3 From 76b6027cd80685617b5bf5ceb986fd5dc8e213b2 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Fri, 11 Nov 2011 15:34:47 +0530 Subject: Unused variable removed --- railties/test/application/console_test.rb | 1 - railties/test/application/rackup_test.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb index b3745f194e..2073c780bf 100644 --- a/railties/test/application/console_test.rb +++ b/railties/test/application/console_test.rb @@ -71,7 +71,6 @@ class ConsoleTest < Test::Unit::TestCase assert !User.new.respond_to?(:age) silence_stream(STDOUT) { irb_context.reload! } - session = irb_context.new_session assert User.new.respond_to?(:age) end diff --git a/railties/test/application/rackup_test.rb b/railties/test/application/rackup_test.rb index ff9cdcadc7..86e1995def 100644 --- a/railties/test/application/rackup_test.rb +++ b/railties/test/application/rackup_test.rb @@ -6,7 +6,7 @@ module ApplicationTests def rackup require "rack" - app, options = Rack::Builder.parse_file("#{app_path}/config.ru") + app, _ = Rack::Builder.parse_file("#{app_path}/config.ru") app end -- cgit v1.2.3 From df08273d1420ee4879931f508fe2953235c707ef Mon Sep 17 00:00:00 2001 From: Sergey Parizhskiy Date: Tue, 15 Nov 2011 13:09:41 +0200 Subject: made url to a github issues a bit shorter - no need in a page param when it's a first page --- railties/guides/source/contributing_to_ruby_on_rails.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile index 80c3cf6e1a..1cd70404a3 100644 --- a/railties/guides/source/contributing_to_ruby_on_rails.textile +++ b/railties/guides/source/contributing_to_ruby_on_rails.textile @@ -215,7 +215,7 @@ TIP: You may want to "put your git branch name in your shell prompt":http://qugs h3. Helping to Resolve Existing Issues -As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "Everyone's Issues":https://github.com/rails/rails/issues?sort=created&direction=desc&state=open&page=1 list in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually: +As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "Everyone's Issues":https://github.com/rails/rails/issues?sort=created&direction=desc&state=open list in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually: h4. Verifying Bug Reports -- cgit v1.2.3 From 83bf0b626cf2134260903e57d74f67de57384073 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 16 Nov 2011 02:36:36 +0530 Subject: refactor test_multiple_of --- activesupport/test/core_ext/integer_ext_test.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/activesupport/test/core_ext/integer_ext_test.rb b/activesupport/test/core_ext/integer_ext_test.rb index fe8c7eb224..b1f5f70a70 100644 --- a/activesupport/test/core_ext/integer_ext_test.rb +++ b/activesupport/test/core_ext/integer_ext_test.rb @@ -2,6 +2,8 @@ require 'abstract_unit' require 'active_support/core_ext/integer' class IntegerExtTest < Test::Unit::TestCase + PRIME = 22953686867719691230002707821868552601124472329079 + def test_multiple_of [ -7, 0, 7, 14 ].each { |i| assert i.multiple_of?(7) } [ -7, 7, 14 ].each { |i| assert ! i.multiple_of?(6) } @@ -11,10 +13,7 @@ class IntegerExtTest < Test::Unit::TestCase assert !5.multiple_of?(0) # test with a prime - assert !22953686867719691230002707821868552601124472329079.multiple_of?(2) - assert !22953686867719691230002707821868552601124472329079.multiple_of?(3) - assert !22953686867719691230002707821868552601124472329079.multiple_of?(5) - assert !22953686867719691230002707821868552601124472329079.multiple_of?(7) + [2, 3, 5, 7].each { |i| assert !PRIME.multiple_of?(i) } end def test_ordinalize -- cgit v1.2.3 From 8d1a2b3ecde5a8745b3eaab4763a71d80ca3441f Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Tue, 15 Nov 2011 22:47:18 +0000 Subject: Revert "Merge pull request #3640 from indirect/remote_ip" This reverts commit 6491aadc525b8703708e0fd0fbf05bd436a47801, reversing changes made to 83bf0b626cf2134260903e57d74f67de57384073. See https://github.com/rails/rails/pull/3640#issuecomment-2752761 for explanation. --- actionpack/lib/action_dispatch/http/request.rb | 5 +++-- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 0e8bd0bd6d..b10f6b48c7 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -155,9 +155,10 @@ module ActionDispatch @ip ||= super end - # Originating IP address from the RemoteIp middleware. + # Originating IP address, usually set by the RemoteIp middleware. def remote_ip - @remote_ip ||= @env["action_dispatch.remote_ip"] + # Coerce the remote_ip object into a string, because to_s could return nil + @remote_ip ||= @env["action_dispatch.remote_ip"].to_s || ip end # Returns the unique request id, which is based off either the X-Request-Id header that can diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 77aa4e743e..ee0d19a50d 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -55,10 +55,7 @@ module ActionDispatch "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" end - not_proxy = client_ip || forwarded_ips.last || remote_addrs.first - - # Return first REMOTE_ADDR if there are no other options - not_proxy || ips_from('REMOTE_ADDR', :all).first + client_ip || forwarded_ips.last || remote_addrs.first end def to_s @@ -69,9 +66,9 @@ module ActionDispatch protected - def ips_from(header, allow_proxies = false) + def ips_from(header) ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : [] - allow_proxies ? ips : ips.reject{|ip| ip =~ @middleware.proxies } + ips.reject{|ip| ip =~ @middleware.proxies } end end -- cgit v1.2.3 From bc00514b6236d701d3e660c4ec365a767a070a91 Mon Sep 17 00:00:00 2001 From: rpq Date: Tue, 15 Nov 2011 23:20:21 -0500 Subject: added comma --- railties/guides/source/asset_pipeline.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index 6ff5e87b6d..3681501293 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -438,7 +438,7 @@ location ~ ^/assets/ { } -When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves. +When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves. Nginx is able to do this automatically enabling +gzip_static+: -- cgit v1.2.3 From 21c5a0a104bf04e3e7b63aa5f0104f1c666655c3 Mon Sep 17 00:00:00 2001 From: Daniel Dyba Date: Sat, 16 Jul 2011 16:54:03 -0700 Subject: Changed Commands module to RailsCommands. This is to avoid a conflict that occurs when you add Rake to your Gemfile. There is a Commands Object in Rake that conflicts with the Commands module in plugin.rb. See rails issue #1866. --- railties/lib/rails/commands/plugin.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb index 4df849447d..aa4551c806 100644 --- a/railties/lib/rails/commands/plugin.rb +++ b/railties/lib/rails/commands/plugin.rb @@ -274,7 +274,7 @@ end # load default environment and parse arguments require 'optparse' -module Commands +module RailsCommands class Plugin attr_reader :environment, :script_name def initialize @@ -327,7 +327,7 @@ module Commands command = general.shift if command =~ /^(install|remove)$/ - command = Commands.const_get(command.capitalize).new(self) + command = RailsCommands.const_get(command.capitalize).new(self) command.parse!(sub) else puts "Unknown command: #{command}" unless command.blank? @@ -539,4 +539,4 @@ class RecursiveHTTPFetcher end end -Commands::Plugin.parse! +RailsCommands::Plugin.parse! -- cgit v1.2.3 From 325abe9fbad58b6a0e119a678039b195247a57bc Mon Sep 17 00:00:00 2001 From: Daniel Dyba Date: Sun, 17 Jul 2011 23:09:51 -0700 Subject: Substituted RailsCommands for Rails::Commands --- railties/lib/rails/commands/plugin.rb | 320 +++++++++++++++++----------------- 1 file changed, 161 insertions(+), 159 deletions(-) diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb index aa4551c806..c99a2e6685 100644 --- a/railties/lib/rails/commands/plugin.rb +++ b/railties/lib/rails/commands/plugin.rb @@ -274,198 +274,200 @@ end # load default environment and parse arguments require 'optparse' -module RailsCommands - class Plugin - attr_reader :environment, :script_name - def initialize - @environment = RailsEnvironment.default - @rails_root = RailsEnvironment.default.root - @script_name = File.basename($0) - end +module Rails + module Commands + class Plugin + attr_reader :environment, :script_name + def initialize + @environment = RailsEnvironment.default + @rails_root = RailsEnvironment.default.root + @script_name = File.basename($0) + end - def environment=(value) - @environment = value - RailsEnvironment.default = value - end + def environment=(value) + @environment = value + RailsEnvironment.default = value + end - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: plugin [OPTIONS] command" - o.define_head "Rails plugin manager." + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: plugin [OPTIONS] command" + o.define_head "Rails plugin manager." - o.separator "" - o.separator "GENERAL OPTIONS" + o.separator "" + o.separator "GENERAL OPTIONS" - o.on("-r", "--root=DIR", String, - "Set an explicit rails app directory.", - "Default: #{@rails_root}") { |rails_root| @rails_root = rails_root; self.environment = RailsEnvironment.new(@rails_root) } + o.on("-r", "--root=DIR", String, + "Set an explicit rails app directory.", + "Default: #{@rails_root}") { |rails_root| @rails_root = rails_root; self.environment = RailsEnvironment.new(@rails_root) } - o.on("-v", "--verbose", "Turn on verbose output.") { |verbose| $verbose = verbose } - o.on("-h", "--help", "Show this help message.") { puts o; exit } + o.on("-v", "--verbose", "Turn on verbose output.") { |verbose| $verbose = verbose } + o.on("-h", "--help", "Show this help message.") { puts o; exit } - o.separator "" - o.separator "COMMANDS" + o.separator "" + o.separator "COMMANDS" - o.separator " install Install plugin(s) from known repositories or URLs." - o.separator " remove Uninstall plugins." + o.separator " install Install plugin(s) from known repositories or URLs." + o.separator " remove Uninstall plugins." - o.separator "" - o.separator "EXAMPLES" - o.separator " Install a plugin from a subversion URL:" - o.separator " #{@script_name} plugin install http://example.com/my_svn_plugin\n" - o.separator " Install a plugin from a git URL:" - o.separator " #{@script_name} plugin install git://github.com/SomeGuy/my_awesome_plugin.git\n" - o.separator " Install a plugin and add a svn:externals entry to vendor/plugins" - o.separator " #{@script_name} plugin install -x my_svn_plugin\n" + o.separator "" + o.separator "EXAMPLES" + o.separator " Install a plugin from a subversion URL:" + o.separator " #{@script_name} plugin install http://example.com/my_svn_plugin\n" + o.separator " Install a plugin from a git URL:" + o.separator " #{@script_name} plugin install git://github.com/SomeGuy/my_awesome_plugin.git\n" + o.separator " Install a plugin and add a svn:externals entry to vendor/plugins" + o.separator " #{@script_name} plugin install -x my_svn_plugin\n" + end end - end - def parse!(args=ARGV) - general, sub = split_args(args) - options.parse!(general) + def parse!(args=ARGV) + general, sub = split_args(args) + options.parse!(general) - command = general.shift - if command =~ /^(install|remove)$/ - command = RailsCommands.const_get(command.capitalize).new(self) - command.parse!(sub) - else - puts "Unknown command: #{command}" unless command.blank? - puts options - exit 1 + command = general.shift + if command =~ /^(install|remove)$/ + command = Commands.const_get(command.capitalize).new(self) + command.parse!(sub) + else + puts "Unknown command: #{command}" unless command.blank? + puts options + exit 1 + end end - end - def split_args(args) - left = [] - left << args.shift while args[0] and args[0] =~ /^-/ - left << args.shift if args[0] - [left, args] - end - - def self.parse!(args=ARGV) - Plugin.new.parse!(args) - end - end + def split_args(args) + left = [] + left << args.shift while args[0] and args[0] =~ /^-/ + left << args.shift if args[0] + [left, args] + end - class Install - def initialize(base_command) - @base_command = base_command - @method = :http - @options = { :quiet => false, :revision => nil, :force => false } + def self.parse!(args=ARGV) + Plugin.new.parse!(args) + end end - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]" - o.define_head "Install one or more plugins." - o.separator "" - o.separator "Options:" - o.on( "-x", "--externals", - "Use svn:externals to grab the plugin.", - "Enables plugin updates and plugin versioning.") { |v| @method = :externals } - o.on( "-o", "--checkout", - "Use svn checkout to grab the plugin.", - "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout } - o.on( "-e", "--export", - "Use svn export to grab the plugin.", - "Exports the plugin, allowing you to check it into your local repository. Does not enable updates or add an svn:externals entry.") { |v| @method = :export } - o.on( "-q", "--quiet", - "Suppresses the output from installation.", - "Ignored if -v is passed (rails plugin -v install ...)") { |v| @options[:quiet] = true } - o.on( "-r REVISION", "--revision REVISION", - "Checks out the given revision from subversion or git.", - "Ignored if subversion/git is not used.") { |v| @options[:revision] = v } - o.on( "-f", "--force", - "Reinstalls a plugin if it's already installed.") { |v| @options[:force] = true } - o.separator "" - o.separator "You can specify plugin names as given in 'plugin list' output or absolute URLs to " - o.separator "a plugin repository." + class Install + def initialize(base_command) + @base_command = base_command + @method = :http + @options = { :quiet => false, :revision => nil, :force => false } end - end - def determine_install_method - best = @base_command.environment.best_install_method - @method = :http if best == :http and @method == :export - case - when (best == :http and @method != :http) - msg = "Cannot install using subversion because `svn' cannot be found in your PATH" - when (best == :export and (@method != :export and @method != :http)) - msg = "Cannot install using #{@method} because this project is not under subversion." - when (best != :externals and @method == :externals) - msg = "Cannot install using externals because vendor/plugins is not under subversion." + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]" + o.define_head "Install one or more plugins." + o.separator "" + o.separator "Options:" + o.on( "-x", "--externals", + "Use svn:externals to grab the plugin.", + "Enables plugin updates and plugin versioning.") { |v| @method = :externals } + o.on( "-o", "--checkout", + "Use svn checkout to grab the plugin.", + "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout } + o.on( "-e", "--export", + "Use svn export to grab the plugin.", + "Exports the plugin, allowing you to check it into your local repository. Does not enable updates or add an svn:externals entry.") { |v| @method = :export } + o.on( "-q", "--quiet", + "Suppresses the output from installation.", + "Ignored if -v is passed (rails plugin -v install ...)") { |v| @options[:quiet] = true } + o.on( "-r REVISION", "--revision REVISION", + "Checks out the given revision from subversion or git.", + "Ignored if subversion/git is not used.") { |v| @options[:revision] = v } + o.on( "-f", "--force", + "Reinstalls a plugin if it's already installed.") { |v| @options[:force] = true } + o.separator "" + o.separator "You can specify plugin names as given in 'plugin list' output or absolute URLs to " + o.separator "a plugin repository." + end end - if msg - puts msg - exit 1 + + def determine_install_method + best = @base_command.environment.best_install_method + @method = :http if best == :http and @method == :export + case + when (best == :http and @method != :http) + msg = "Cannot install using subversion because `svn' cannot be found in your PATH" + when (best == :export and (@method != :export and @method != :http)) + msg = "Cannot install using #{@method} because this project is not under subversion." + when (best != :externals and @method == :externals) + msg = "Cannot install using externals because vendor/plugins is not under subversion." + end + if msg + puts msg + exit 1 + end + @method end - @method - end - def parse!(args) - options.parse!(args) - if args.blank? - puts options + def parse!(args) + options.parse!(args) + if args.blank? + puts options + exit 1 + end + environment = @base_command.environment + install_method = determine_install_method + puts "Plugins will be installed using #{install_method}" if $verbose + args.each do |name| + ::Plugin.find(name).install(install_method, @options) + end + rescue StandardError => e + puts "Plugin not found: #{args.inspect}" + puts e.inspect if $verbose exit 1 end - environment = @base_command.environment - install_method = determine_install_method - puts "Plugins will be installed using #{install_method}" if $verbose - args.each do |name| - ::Plugin.find(name).install(install_method, @options) - end - rescue StandardError => e - puts "Plugin not found: #{args.inspect}" - puts e.inspect if $verbose - exit 1 - end - end - - class Remove - def initialize(base_command) - @base_command = base_command end - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} remove name [name]..." - o.define_head "Remove plugins." + class Remove + def initialize(base_command) + @base_command = base_command end - end - def parse!(args) - options.parse!(args) - if args.blank? - puts options - exit 1 + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} remove name [name]..." + o.define_head "Remove plugins." + end end - root = @base_command.environment.root - args.each do |name| - ::Plugin.new(name).uninstall + + def parse!(args) + options.parse!(args) + if args.blank? + puts options + exit 1 + end + root = @base_command.environment.root + args.each do |name| + ::Plugin.new(name).uninstall + end end end - end - class Info - def initialize(base_command) - @base_command = base_command - end + class Info + def initialize(base_command) + @base_command = base_command + end - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} info name [name]..." - o.define_head "Shows plugin info at {url}/about.yml." + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} info name [name]..." + o.define_head "Shows plugin info at {url}/about.yml." + end end - end - def parse!(args) - options.parse!(args) - args.each do |name| - puts ::Plugin.find(name).info - puts + def parse!(args) + options.parse!(args) + args.each do |name| + puts ::Plugin.find(name).info + puts + end end end end @@ -539,4 +541,4 @@ class RecursiveHTTPFetcher end end -RailsCommands::Plugin.parse! +Rails::Commands::Plugin.parse! -- cgit v1.2.3 From df5ec41b891bbd0392e9bb9695c17e3821903eed Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 10:42:56 -0800 Subject: bundler treats trunk ruby as ruby 1.9, hack around that for now --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 1b7d478f18..97605e32b5 100644 --- a/Gemfile +++ b/Gemfile @@ -41,7 +41,7 @@ platforms :mri_18 do end platforms :mri_19 do - gem "ruby-debug19", :require => "ruby-debug" unless ENV['TRAVIS'] + gem "ruby-debug19", :require => "ruby-debug" unless ENV['TRAVIS'] || RUBY_VERSION >= "2.0" end platforms :mri do -- cgit v1.2.3 From 61228e9a0cafb5f0a8e4f2c24da36ef9261840fb Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 13:25:55 -0800 Subject: fixing tests on PG --- activerecord/test/cases/adapters/postgresql/schema_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 19669bdeb0..467e5d7b86 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -197,7 +197,7 @@ class SchemaTest < ActiveRecord::TestCase end def test_dump_indexes_for_schema_multiple_schemas_in_search_path - do_dump_index_tests_for_schema("public, #{SCHEMA_NAME}", INDEX_A_COLUMN, INDEX_B_COLUMN_S1) + do_dump_index_tests_for_schema("public, #{SCHEMA_NAME}", INDEX_A_COLUMN, INDEX_B_COLUMN_S1, INDEX_D_COLUMN) end def test_with_uppercase_index_name -- cgit v1.2.3 From 3a6a10a36d9fdcc6de0f2a8e81c73001c1331072 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Wed, 16 Nov 2011 21:37:10 +0000 Subject: Switch from marshal format to plain text for the encoding conversions dump. This is for windows compatibility. Fixes #3644. --- .../lib/action_view/data/encoding_conversions.dump | Bin 122854 -> 0 bytes .../lib/action_view/data/encoding_conversions.txt | 88 +++++++++++++++++++++ actionpack/lib/action_view/template.rb | 13 +-- 3 files changed, 95 insertions(+), 6 deletions(-) delete mode 100644 actionpack/lib/action_view/data/encoding_conversions.dump create mode 100644 actionpack/lib/action_view/data/encoding_conversions.txt diff --git a/actionpack/lib/action_view/data/encoding_conversions.dump b/actionpack/lib/action_view/data/encoding_conversions.dump deleted file mode 100644 index 18d7cd448b..0000000000 Binary files a/actionpack/lib/action_view/data/encoding_conversions.dump and /dev/null differ diff --git a/actionpack/lib/action_view/data/encoding_conversions.txt b/actionpack/lib/action_view/data/encoding_conversions.txt new file mode 100644 index 0000000000..fdfbe28803 --- /dev/null +++ b/actionpack/lib/action_view/data/encoding_conversions.txt @@ -0,0 +1,88 @@ +ASCII-8BIT:UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-8:ASCII-8BIT,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +US-ASCII:ASCII-8BIT,UTF-8,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Big5:ASCII-8BIT,UTF-8,US-ASCII,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Big5-HKSCS:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Big5-UAO:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP949:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +EUC-JP:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +EUC-KR:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +GB18030:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +GBK:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-1:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-2:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-3:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-4:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-5:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-6:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-7:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-8:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-9:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-10:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-11:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-13:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-14:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-8859-15:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +KOI8-R:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +KOI8-U:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Shift_JIS:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-16BE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-16LE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-32BE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-32LE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1251:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM437:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM737:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM775:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP850:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM852:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP852:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM855:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP855:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM857:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM860:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM861:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM862:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM863:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM865:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM866:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +IBM869:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macCroatian:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macCyrillic:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macGreek:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macIceland:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macRoman:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macRomania:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macTurkish:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +macUkraine:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP950:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP951:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +stateless-ISO-2022-JP:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +eucJP-ms:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP51932:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +GB2312:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +GB12345:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-2022-JP:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP50220:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +CP50221:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1252:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1250:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1256:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1253:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1255:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1254:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +TIS-620:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-874:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-1257:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +Windows-31J:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF8-MAC:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-16:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF-32:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF8-DoCoMo:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +SJIS-DoCoMo:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF8-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +SJIS-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +ISO-2022-JP-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +stateless-ISO-2022-JP-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank +UTF8-SoftBank:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,SJIS-SoftBank +SJIS-SoftBank:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank \ No newline at end of file diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index fbc135c4a7..8d69880308 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -12,18 +12,19 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' && RUBY_VERSION == '1.9.3' && # able to find it (due to a bug). # # However, we don't know what conversions we may need to do a runtime. So we load up a - # marshal-dumped structure which contains a pre-generated list of all the possible conversions, + # text file which contains a pre-generated list of all the possible conversions, # and we load all of them. # # In my testing this increased the process size by about 3.9 MB (after the conversions array # is GC'd) and took around 170ms to run, which seems acceptable for a workaround. # - # The script to dump the conversions is: https://gist.github.com/1342729 + # The script to dump the conversions is: https://gist.github.com/1371499 - filename = File.join(File.dirname(__FILE__), 'data', 'encoding_conversions.dump') - conversions = Marshal.load(File.read(filename)) - conversions.each do |from, to_array| - to_array.each do |to| + filename = File.join(File.dirname(__FILE__), 'data', 'encoding_conversions.txt') + conversions = File.read(filename) + conversions.split("\n").map do |line| + from, to_array = line.split(':') + to_array.split(',').each do |to| Encoding::Converter.new(from, to) end end -- cgit v1.2.3 From cef1e14e09e5654895f264a2cff1c0898672b1f0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 14:45:18 -0800 Subject: removing some useless conditionals --- activerecord/lib/active_record/railties/databases.rake | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index aea928b443..f3cb2a971e 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -1,8 +1,8 @@ require 'active_support/core_ext/object/inclusion' +require 'active_record' db_namespace = namespace :db do task :load_config => :rails_env do - require 'active_record' ActiveRecord::Base.configurations = Rails.application.config.database_configuration ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a @@ -279,16 +279,14 @@ db_namespace = namespace :db do # desc "Raises an error if there are pending migrations" task :abort_if_pending_migrations => :environment do - if defined? ActiveRecord - pending_migrations = ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations_paths).pending_migrations + pending_migrations = ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations_paths).pending_migrations - if pending_migrations.any? - puts "You have #{pending_migrations.size} pending migrations:" - pending_migrations.each do |pending_migration| - puts ' %4d %s' % [pending_migration.version, pending_migration.name] - end - abort %{Run `rake db:migrate` to update your database then try again.} + if pending_migrations.any? + puts "You have #{pending_migrations.size} pending migrations:" + pending_migrations.each do |pending_migration| + puts ' %4d %s' % [pending_migration.version, pending_migration.name] end + abort %{Run `rake db:migrate` to update your database then try again.} end end @@ -498,7 +496,7 @@ db_namespace = namespace :db do # desc 'Check for pending migrations and load the test schema' task :prepare => 'db:abort_if_pending_migrations' do - if defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank? + unless ActiveRecord::Base.configurations.blank? db_namespace[{ :sql => 'test:clone_structure', :ruby => 'test:load' }[ActiveRecord::Base.schema_format]].invoke end end -- cgit v1.2.3 From f05ccf805a6d2a3ed73ef9928577e8b0ebbb3c49 Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Wed, 16 Nov 2011 12:53:43 -1000 Subject: Revert "Revert "Merge pull request #3640 from indirect/remote_ip"" This reverts commit 8d1a2b3ecde5a8745b3eaab4763a71d80ca3441f, because I have fixed the issues this commit caused in the next commit. --- actionpack/lib/action_dispatch/http/request.rb | 5 ++--- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 9 ++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index b10f6b48c7..0e8bd0bd6d 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -155,10 +155,9 @@ module ActionDispatch @ip ||= super end - # Originating IP address, usually set by the RemoteIp middleware. + # Originating IP address from the RemoteIp middleware. def remote_ip - # Coerce the remote_ip object into a string, because to_s could return nil - @remote_ip ||= @env["action_dispatch.remote_ip"].to_s || ip + @remote_ip ||= @env["action_dispatch.remote_ip"] end # Returns the unique request id, which is based off either the X-Request-Id header that can diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index ee0d19a50d..77aa4e743e 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -55,7 +55,10 @@ module ActionDispatch "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" end - client_ip || forwarded_ips.last || remote_addrs.first + not_proxy = client_ip || forwarded_ips.last || remote_addrs.first + + # Return first REMOTE_ADDR if there are no other options + not_proxy || ips_from('REMOTE_ADDR', :all).first end def to_s @@ -66,9 +69,9 @@ module ActionDispatch protected - def ips_from(header) + def ips_from(header, allow_proxies = false) ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : [] - ips.reject{|ip| ip =~ @middleware.proxies } + allow_proxies ? ips : ips.reject{|ip| ip =~ @middleware.proxies } end end -- cgit v1.2.3 From 5621abd5698536f1676306930f6aef105d7ae6dc Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Wed, 16 Nov 2011 12:49:15 -1000 Subject: :facepalm: Request#remote_ip has to work without the middleware --- actionpack/lib/action_dispatch/http/request.rb | 4 ++-- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 0e8bd0bd6d..4e6feb708e 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -155,9 +155,9 @@ module ActionDispatch @ip ||= super end - # Originating IP address from the RemoteIp middleware. + # Originating IP address, usually set by the RemoteIp middleware. def remote_ip - @remote_ip ||= @env["action_dispatch.remote_ip"] + @remote_ip ||= @env["action_dispatch.remote_ip"] || ip end # Returns the unique request id, which is based off either the X-Request-Id header that can diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 77aa4e743e..3a88f2ca43 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -58,7 +58,7 @@ module ActionDispatch not_proxy = client_ip || forwarded_ips.last || remote_addrs.first # Return first REMOTE_ADDR if there are no other options - not_proxy || ips_from('REMOTE_ADDR', :all).first + not_proxy || ips_from('REMOTE_ADDR', :allow_proxies).first end def to_s -- cgit v1.2.3 From a9044d011790063e17159209f7bb1cbea255d4dd Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Wed, 16 Nov 2011 12:58:49 -1000 Subject: the object itself isn't the IP, #to_s is the IP --- actionpack/lib/action_dispatch/http/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 4e6feb708e..69ca050d0c 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -157,7 +157,7 @@ module ActionDispatch # Originating IP address, usually set by the RemoteIp middleware. def remote_ip - @remote_ip ||= @env["action_dispatch.remote_ip"] || ip + @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s end # Returns the unique request id, which is based off either the X-Request-Id header that can -- cgit v1.2.3 From 73cb0f98289923c8fa0287bf1cc8857664078d43 Mon Sep 17 00:00:00 2001 From: James Adam Date: Wed, 26 Oct 2011 12:51:38 +0100 Subject: `ActiveRecord::Base#becomes` should retain the errors of the original object. This commit contains a simple failing test that demonstrates the behaviour we expect, and a fix. When using `becomes` to transform the type of an object, it should retain any error information that was present on the original instance. --- activerecord/lib/active_record/persistence.rb | 1 + activerecord/test/cases/base_test.rb | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 5e65e46a7d..f047a1d9fa 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -114,6 +114,7 @@ module ActiveRecord became.instance_variable_set("@attributes_cache", @attributes_cache) became.instance_variable_set("@new_record", new_record?) became.instance_variable_set("@destroyed", destroyed?) + became.instance_variable_set("@errors", errors) became.type = klass.name unless self.class.descends_from_active_record? became end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index fdb656fe13..997c9e7e9d 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1761,6 +1761,14 @@ class BasicsTest < ActiveRecord::TestCase assert_equal "The First Topic", topics(:first).becomes(Reply).title end + def test_becomes_includes_errors + company = Company.new(:name => nil) + assert !company.valid? + original_errors = company.errors + client = company.becomes(Client) + assert_equal original_errors, client.errors + end + def test_silence_sets_log_level_to_error_in_block original_logger = ActiveRecord::Base.logger log = StringIO.new -- cgit v1.2.3 From 38d26b0cb56d82093889efa95992a35ba3bb9f29 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 15:01:02 -0800 Subject: Move conditionals to separate tasks so they can be reused. --- activerecord/lib/active_record/railties/databases.rake | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index f3cb2a971e..ee611f6a2a 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -291,15 +291,11 @@ db_namespace = namespace :db do end desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)' - task :setup => :environment do - db_namespace["create"].invoke - db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby - db_namespace["structure:load"].invoke if ActiveRecord::Base.schema_format == :sql - db_namespace["seed"].invoke - end + task :setup => :seed desc 'Load the seed data from db/seeds.rb' - task :seed => 'db:abort_if_pending_migrations' do + task :seed => ['db:schema:load_if_ruby', 'db:structure:load_if_sql'] do + db_namespace['abort_if_pending_migrations'].invoke Rails.application.load_seed end @@ -362,6 +358,10 @@ db_namespace = namespace :db do abort %{#{file} doesn't exist yet. Run `rake db:migrate` to create it then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded} end end + + task :load_if_ruby => 'db:create' do + db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby + end end namespace :structure do @@ -437,6 +437,10 @@ db_namespace = namespace :db do raise "Task not supported by '#{abcs[env]['adapter']}'" end end + + task :load_if_sql => 'db:create' do + db_namespace["structure:load"].invoke if ActiveRecord::Base.schema_format == :sql + end end namespace :test do -- cgit v1.2.3 From ca69408b49156f98a76adfc03088b6b067fabc61 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 15:27:47 -0800 Subject: Reduce schema format tests --- .../lib/active_record/railties/databases.rake | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index ee611f6a2a..d19208dd76 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -150,8 +150,16 @@ db_namespace = namespace :db do task :migrate => [:environment, :load_config] do ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) - db_namespace["schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby - db_namespace["structure:dump"].invoke if ActiveRecord::Base.schema_format == :sql + db_namespace['_dump'].invoke + end + + task :_dump do + case ActiveRecord::Base.schema_format + when :ruby then db_namespace["schema:dump"].invoke + when :sql then db_namespace["structure:dump"].invoke + else + raise "unknown schema format #{ActiveRecord::Base.schema_format}" + end end namespace :migrate do @@ -174,8 +182,7 @@ db_namespace = namespace :db do version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil raise 'VERSION is required' unless version ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version) - db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby - db_namespace['structure:dump'].invoke if ActiveRecord::Base.schema_format == :sql + db_namespace['_dump'].invoke end # desc 'Runs the "down" for a given migration VERSION.' @@ -183,8 +190,7 @@ db_namespace = namespace :db do version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil raise 'VERSION is required' unless version ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version) - db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby - db_namespace['structure:dump'].invoke if ActiveRecord::Base.schema_format == :sql + db_namespace['_dump'].invoke end desc 'Display status of migrations' @@ -224,16 +230,14 @@ db_namespace = namespace :db do task :rollback => [:environment, :load_config] do step = ENV['STEP'] ? ENV['STEP'].to_i : 1 ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step) - db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby - db_namespace['structure:dump'].invoke if ActiveRecord::Base.schema_format == :sql + db_namespace['_dump'].invoke end # desc 'Pushes the schema to the next version (specify steps w/ STEP=n).' task :forward => [:environment, :load_config] do step = ENV['STEP'] ? ENV['STEP'].to_i : 1 ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step) - db_namespace['schema:dump'].invoke if ActiveRecord::Base.schema_format == :ruby - db_namespace['structure:dump'].invoke if ActiveRecord::Base.schema_format == :sql + db_namespace['_dump'].invoke end # desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.' -- cgit v1.2.3 From b96aaf8ccbd06986dc489a9f29ea4092dd5cf911 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 15:30:00 -0800 Subject: dbfile isn't supported anymore, so remove --- activerecord/lib/active_record/railties/databases.rake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index d19208dd76..ef8f815207 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -388,7 +388,7 @@ db_namespace = namespace :db do `pg_dump -i -s -x -O -f db/structure.sql #{search_path} #{abcs[Rails.env]['database']}` raise 'Error dumping database' if $?.exitstatus == 1 when /sqlite/ - dbfile = abcs[Rails.env]['database'] || abcs[Rails.env]['dbfile'] + dbfile = abcs[Rails.env]['database'] `sqlite3 #{dbfile} .schema > db/structure.sql` when 'sqlserver' `smoscript -s #{abcs[Rails.env]['host']} -d #{abcs[Rails.env]['database']} -u #{abcs[Rails.env]['username']} -p #{abcs[Rails.env]['password']} -f db\\structure.sql -A -U` @@ -424,7 +424,7 @@ db_namespace = namespace :db do ENV['PGUSER'] = abcs[env]['username'].to_s if abcs[env]['username'] `psql -f "#{Rails.root}/db/structure.sql" #{abcs[env]['database']} #{abcs[env]['template']}` when /sqlite/ - dbfile = abcs[env]['database'] || abcs[env]['dbfile'] + dbfile = abcs[env]['database'] `sqlite3 #{dbfile} < "#{Rails.root}/db/structure.sql"` when 'sqlserver' `sqlcmd -S #{abcs[env]['host']} -d #{abcs[env]['database']} -U #{abcs[env]['username']} -P #{abcs[env]['password']} -i db\\structure.sql` @@ -481,7 +481,7 @@ db_namespace = namespace :db do drop_database(abcs['test']) create_database(abcs['test']) when /sqlite/ - dbfile = abcs['test']['database'] || abcs['test']['dbfile'] + dbfile = abcs['test']['database'] File.delete(dbfile) if File.exist?(dbfile) when 'sqlserver' test = abcs.deep_dup['test'] -- cgit v1.2.3 From 97ca6358c5fbd5458b684d6d46489b7b68c48225 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 15:40:20 -0800 Subject: Join method uses empty string by default, so remove it --- .../lib/active_record/connection_adapters/abstract_mysql_adapter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index baf4c043c4..e26b10fa97 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -389,11 +389,11 @@ module ActiveRecord sql = "SHOW TABLES" end - select_all(sql).map do |table| + select_all(sql).map { |table| table.delete('Table_type') sql = "SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}" exec_without_stmt(sql).first['Create Table'] + ";\n\n" - end.join("") + }.join end # Drops the database specified on the +name+ attribute -- cgit v1.2.3 From bb95e815380c85d14afade807ebb2dd227d90b9e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 15:51:25 -0800 Subject: Adding a deprecation warning for use of the schema_info table. --- .../lib/active_record/connection_adapters/abstract/schema_statements.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 11da84e245..7742f32213 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/array/wrap' +require 'active_support/deprecation/reporting' module ActiveRecord module ConnectionAdapters # :nodoc: @@ -445,6 +446,7 @@ module ActiveRecord si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix if table_exists?(si_table) + ActiveRecord::Deprecation.warn "Usage of the schema table `#{si_table}` is deprecated. Please switch to using `schema_migrations` table" old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i assume_migrated_upto_version(old_version) -- cgit v1.2.3 From 64a3175eea3c121f30a5a24034aa1ed400c80b12 Mon Sep 17 00:00:00 2001 From: capps Date: Wed, 16 Nov 2011 15:57:54 -0800 Subject: "denoted" instead of "donated" "parentheses" instead of "use brackets" --- railties/guides/source/i18n.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 2d4cc13571..e9477e84cf 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -231,7 +231,7 @@ end Now, when you call the +books_path+ method you should get +"/en/books"+ (for the default locale). An URL like +http://localhost:3001/nl/books+ should load the Netherlands locale, then, and following calls to +books_path+ should return +"/nl/books"+ (because the locale changed). -If you don't want to force the use of a locale in your routes you can use an optional path scope (donated by the use brackets) like so: +If you don't want to force the use of a locale in your routes you can use an optional path scope (denoted by the parentheses) like so: # config/routes.rb -- cgit v1.2.3 From 4c1a1933cbc5ab96efe340a3b31ac5fee12c99c8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 16:18:00 -0800 Subject: No need to `readlines` then `join`, just use `read` :heart: --- activerecord/lib/active_record/railties/databases.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index ef8f815207..5964fa9cb0 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -414,7 +414,7 @@ db_namespace = namespace :db do when /mysql/ ActiveRecord::Base.establish_connection(abcs[env]) ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0') - IO.readlines("#{Rails.root}/db/structure.sql").join.split("\n\n").each do |table| + IO.read("#{Rails.root}/db/structure.sql").split("\n\n").each do |table| ActiveRecord::Base.connection.execute(table) end when /postgresql/ -- cgit v1.2.3 From e3671422556ac61f39539264713ba9c04814b80f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Nov 2011 16:55:11 -0800 Subject: Initialize our instance variables. --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 3a88f2ca43..8dbe3af6f1 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -33,7 +33,9 @@ module ActionDispatch class GetIp def initialize(env, middleware) - @env, @middleware = env, middleware + @env = env + @middleware = middleware + @calculate_ip = false end # Determines originating IP address. REMOTE_ADDR is the standard -- cgit v1.2.3 From c2b6f63bbe2740fd63a36eeefe17d51813a17324 Mon Sep 17 00:00:00 2001 From: Alexander Uvarov Date: Thu, 17 Nov 2011 12:04:46 +0600 Subject: Fix impractical I18n lookup in nested fields_for --- actionpack/lib/action_view/helpers/form_helper.rb | 10 ++++- actionpack/test/template/form_helper_test.rb | 46 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index f148ffbd73..d687866d0d 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -995,8 +995,16 @@ module ActionView label_tag(name_and_id["id"], options, &block) else content = if text.blank? + object_name.gsub!(/\[(.*)_attributes\]\[\d\]/, '.\1') method_and_value = tag_value.present? ? "#{method_name}.#{tag_value}" : method_name - I18n.t("helpers.label.#{object_name}.#{method_and_value}", :default => "").presence + + if object.respond_to?(:to_model) + key = object.class.model_name.i18n_key + i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] + end + + i18n_default ||= "" + I18n.t("#{object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence else text.to_s end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 6434d9645e..34486bb151 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -27,7 +27,13 @@ class FormHelperTest < ActionView::TestCase :body => "Write entire text here", :color => { :red => "Rojo" + }, + :comments => { + :body => "Write body here" } + }, + :tag => { + :value => "Tag" } } } @@ -68,6 +74,12 @@ class FormHelperTest < ActionView::TestCase @post.secret = 1 @post.written_on = Date.new(2004, 6, 15) + @post.comments = [] + @post.comments << @comment + + @post.tags = [] + @post.tags << Tag.new + @blog_post = Blog::Post.new("And his name will be forty and four.", 44) end @@ -151,6 +163,40 @@ class FormHelperTest < ActionView::TestCase I18n.locale = old_locale end + def test_label_with_locales_and_nested_attributes + old_locale, I18n.locale = I18n.locale, :label + form_for(@post, :html => { :id => 'create-post' }) do |f| + f.fields_for(:comments) do |cf| + concat cf.label(:body) + end + end + + expected = whole_form("/posts/123", "create-post" , "edit_post", :method => "put") do + "" + end + + assert_dom_equal expected, output_buffer + ensure + I18n.locale = old_locale + end + + def test_label_with_locales_fallback_and_nested_attributes + old_locale, I18n.locale = I18n.locale, :label + form_for(@post, :html => { :id => 'create-post' }) do |f| + f.fields_for(:tags) do |cf| + concat cf.label(:value) + end + end + + expected = whole_form("/posts/123", "create-post" , "edit_post", :method => "put") do + "" + end + + assert_dom_equal expected, output_buffer + ensure + I18n.locale = old_locale + end + def test_label_with_for_attribute_as_symbol assert_dom_equal('', label(:post, :title, nil, :for => "my_for")) end -- cgit v1.2.3 From 5ccd9bcc1a3012573e6ab19ac52abf8917374bea Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 17 Nov 2011 12:24:40 +0530 Subject: No need to `readlines` then `join`, just use `read` :heart: same as 4c1a1933cbc5ab96efe340a3b31ac5fee12c99c8 --- activerecord/lib/active_record/railties/databases.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 5964fa9cb0..4ffcf6dbc1 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -430,7 +430,7 @@ db_namespace = namespace :db do `sqlcmd -S #{abcs[env]['host']} -d #{abcs[env]['database']} -U #{abcs[env]['username']} -P #{abcs[env]['password']} -i db\\structure.sql` when 'oci', 'oracle' ActiveRecord::Base.establish_connection(abcs[env]) - IO.readlines("#{Rails.root}/db/structure.sql").join.split(";\n\n").each do |ddl| + IO.read("#{Rails.root}/db/structure.sql").split(";\n\n").each do |ddl| ActiveRecord::Base.connection.execute(ddl) end when 'firebird' -- cgit v1.2.3 From c3ae1d2aec400d6aaea78bd94eb7845b71f1ec15 Mon Sep 17 00:00:00 2001 From: Arun Agrawal Date: Thu, 17 Nov 2011 12:50:19 +0530 Subject: It should be @calculated_ip not @calculate_ip We are using @calculated_ip. @calculate_ip is no where used --- actionpack/lib/action_dispatch/middleware/remote_ip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 8dbe3af6f1..66ece60860 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -35,7 +35,7 @@ module ActionDispatch def initialize(env, middleware) @env = env @middleware = middleware - @calculate_ip = false + @calculated_ip = false end # Determines originating IP address. REMOTE_ADDR is the standard -- cgit v1.2.3 From 0af93089deaf6dc9428c0f2f7a376cdb6f81daee Mon Sep 17 00:00:00 2001 From: Alex Tambellini Date: Thu, 17 Nov 2011 09:44:17 -0500 Subject: Move schema_format :sql config setting from test.rb to application.rb I've moved the schema_format :sql config setting to application.rb because you would never enable this only for the test environment. If you use database constraints or database specific data types you would want all of your environments to use them. --- railties/guides/code/getting_started/config/application.rb | 5 +++++ railties/guides/code/getting_started/config/environments/test.rb | 5 ----- .../lib/rails/generators/rails/app/templates/config/application.rb | 5 +++++ .../generators/rails/app/templates/config/environments/test.rb.tt | 5 ----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/railties/guides/code/getting_started/config/application.rb b/railties/guides/code/getting_started/config/application.rb index e914b5a80e..e16da30f72 100644 --- a/railties/guides/code/getting_started/config/application.rb +++ b/railties/guides/code/getting_started/config/application.rb @@ -39,6 +39,11 @@ module Blog # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] + # Use SQL instead of Active Record's schema dumper when creating the database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + # Enable the asset pipeline config.assets.enabled = true diff --git a/railties/guides/code/getting_started/config/environments/test.rb b/railties/guides/code/getting_started/config/environments/test.rb index 833241ace3..08697cbbc9 100644 --- a/railties/guides/code/getting_started/config/environments/test.rb +++ b/railties/guides/code/getting_started/config/environments/test.rb @@ -29,11 +29,6 @@ Blog::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Use SQL instead of Active Record's schema dumper when creating the test database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types - # config.active_record.schema_format = :sql - # Print deprecation notices to the stderr config.active_support.deprecation = :stderr diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index 13fbe9e526..40fd843b1b 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -49,6 +49,11 @@ module <%= app_const_base %> # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] + # Use SQL instead of Active Record's schema dumper when creating the database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + <% unless options.skip_sprockets? -%> # Enable the asset pipeline config.assets.enabled = true diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt index 80198cc21e..37a8b81dad 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt @@ -29,11 +29,6 @@ # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Use SQL instead of Active Record's schema dumper when creating the test database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types - # config.active_record.schema_format = :sql - <%- unless options.skip_active_record? -%> # Raise exception on mass assignment protection for ActiveRecord models config.active_record.mass_assignment_sanitizer = :strict -- cgit v1.2.3 From 8d17af23ef5202e7c28bbf701e247bce6011df07 Mon Sep 17 00:00:00 2001 From: Sunny Ripert Date: Thu, 17 Nov 2011 17:05:53 +0100 Subject: Guides: better example to find the last sent email --- railties/guides/source/testing.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index 2341a3522c..5dbbe2c0f0 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -927,7 +927,7 @@ class UserControllerTest < ActionController::TestCase assert_difference 'ActionMailer::Base.deliveries.size', +1 do post :invite_friend, :email => 'friend@example.com' end - invite_email = ActionMailer::Base.deliveries.first + invite_email = ActionMailer::Base.deliveries.last assert_equal "You have been invited by me@example.com", invite_email.subject assert_equal 'friend@example.com', invite_email.to[0] -- cgit v1.2.3 From a89fabbb0266e9a5a391a88fd39b97d08879412f Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Thu, 17 Nov 2011 18:49:47 +0100 Subject: Cleanup of databases.rake psql env variables --- activerecord/lib/active_record/railties/databases.rake | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 4ffcf6dbc1..589ed3bd11 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -377,10 +377,7 @@ db_namespace = namespace :db do ActiveRecord::Base.establish_connection(abcs[Rails.env]) File.open("#{Rails.root}/db/structure.sql", "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump } when /postgresql/ - ENV['PGHOST'] = abcs[Rails.env]['host'] if abcs[Rails.env]['host'] - ENV['PGPORT'] = abcs[Rails.env]['port'].to_s if abcs[Rails.env]['port'] - ENV['PGPASSWORD'] = abcs[Rails.env]['password'].to_s if abcs[Rails.env]['password'] - ENV['PGUSER'] = abcs[Rails.env]['username'].to_s if abcs[Rails.env]['username'] + set_psql_env(abcs[Rails.env]) search_path = abcs[Rails.env]['schema_search_path'] unless search_path.blank? search_path = search_path.split(",").map{|search_path_part| "--schema=#{search_path_part.strip}" }.join(" ") @@ -418,10 +415,7 @@ db_namespace = namespace :db do ActiveRecord::Base.connection.execute(table) end when /postgresql/ - ENV['PGHOST'] = abcs[env]['host'] if abcs[env]['host'] - ENV['PGPORT'] = abcs[env]['port'].to_s if abcs[env]['port'] - ENV['PGPASSWORD'] = abcs[env]['password'].to_s if abcs[env]['password'] - ENV['PGUSER'] = abcs[env]['username'].to_s if abcs[env]['username'] + set_psql_env(abcs[env]) `psql -f "#{Rails.root}/db/structure.sql" #{abcs[env]['database']} #{abcs[env]['template']}` when /sqlite/ dbfile = abcs[env]['database'] @@ -599,3 +593,10 @@ end def firebird_db_string(config) FireRuby::Database.db_string_for(config.symbolize_keys) end + +def set_psql_env(config) + ENV['PGHOST'] = config['host'] if config['host'] + ENV['PGPORT'] = config['port'].to_s if config['port'] + ENV['PGPASSWORD'] = config['password'].to_s if config['password'] + ENV['PGUSER'] = config['username'].to_s if config['username'] +end -- cgit v1.2.3 From 649f2513a453cae319be8b63a9de25ae11fb9e8f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Nov 2011 10:00:33 -0800 Subject: Revert "Merge pull request #3603 from vijaydev/change_table_without_block_arg" This reverts commit 81fad6a270ec3cbbb88553c9f2e8200c34fd4d13, reversing changes made to 23101de283de13517e30c4c3d1ecc65525264886. Conflicts: activerecord/test/cases/migration_test.rb --- .../abstract/schema_statements.rb | 19 +++----- activerecord/test/cases/migration_test.rb | 54 ---------------------- 2 files changed, 7 insertions(+), 66 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 7742f32213..1d837f29be 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -242,19 +242,14 @@ module ActiveRecord # # See also Table for details on # all of the various column transformation - def change_table(table_name, options = {}, &blk) - bulk_change = supports_bulk_alter? && options[:bulk] - recorder = bulk_change ? ActiveRecord::Migration::CommandRecorder.new(self) : self - table = Table.new(table_name, recorder) - - if block_given? - if blk.arity == 1 - yield table - else - table.instance_eval(&blk) - end + def change_table(table_name, options = {}) + if supports_bulk_alter? && options[:bulk] + recorder = ActiveRecord::Migration::CommandRecorder.new(self) + yield Table.new(table_name, recorder) + bulk_change_table(table_name, recorder.commands) + else + yield Table.new(table_name, self) end - bulk_change_table(table_name, recorder.commands) if bulk_change end # Renames a table. diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 75eb9c2bce..ae5b2a62b5 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1757,60 +1757,6 @@ if ActiveRecord::Base.connection.supports_migrations? end end end - - def test_change_table_without_block_parameter_no_bulk - Person.connection.create_table :testings, :force => true do - string :foo - end - assert Person.connection.column_exists?(:testings, :foo, :string) - - Person.connection.change_table :testings do - remove :foo - integer :bar - end - - assert_equal %w(bar id), Person.connection.columns(:testings).map { |c| c.name }.sort - ensure - Person.connection.drop_table :testings rescue nil - end - - if ActiveRecord::Base.connection.supports_bulk_alter? - def test_change_table_without_block_parameter_with_bulk - Person.connection.create_table :testings, :force => true do - string :foo - end - assert Person.connection.column_exists?(:testings, :foo, :string) - - assert_queries(1) do - Person.connection.change_table(:testings, :bulk => true) do - integer :bar - string :foo_bar - end - end - - assert_equal %w(bar foo foo_bar id), Person.connection.columns(:testings).map { |c| c.name }.sort - ensure - Person.connection.drop_table :testings rescue nil - end - end - - def test_change_table_should_not_have_mixed_syntax - Person.connection.create_table :testings, :force => true do - string :foo - end - assert_raise(NoMethodError) do - Person.connection.change_table :testings do |t| - t.remove :foo - integer :bar - end - end - assert_raise(NameError) do - Person.connection.change_table :testings do - t.remove :foo - integer :bar - end - end - end end # SexierMigrationsTest class MigrationLoggerTest < ActiveRecord::TestCase -- cgit v1.2.3 From a2f14e23441ec016f9643b9054f409006b0e16b3 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Nov 2011 10:28:23 -0800 Subject: Revert "Merge pull request #1163 from amatsuda/sexier_migration_31" This reverts commit 0e407a90413d8a19002b85508d811ccdf2190783, reversing changes made to 533a9f84b035756eedf9fdccf0c494dc9701ba72. Conflicts: activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb activerecord/test/cases/migration_test.rb --- .../abstract/schema_statements.rb | 10 +- .../connection_adapters/sqlite_adapter.rb | 18 ++-- activerecord/lib/active_record/session_store.rb | 7 +- activerecord/test/cases/migration_test.rb | 120 --------------------- 4 files changed, 13 insertions(+), 142 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 1d837f29be..faa42e2d19 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -155,17 +155,11 @@ module ActiveRecord # ) # # See also TableDefinition#column for details on how to create columns. - def create_table(table_name, options = {}, &blk) + def create_table(table_name, options = {}) td = table_definition td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false - if block_given? - if blk.arity == 1 - yield td - else - td.instance_eval(&blk) - end - end + yield td if block_given? if options[:force] && table_exists?(table_name) drop_table(table_name) diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 35df0a1542..bc3804b3d9 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -480,30 +480,28 @@ module ActiveRecord drop_table(from) end - def copy_table(from, to, options = {}, &block) #:nodoc: - from_columns, from_primary_key = columns(from), primary_key(from) - options = options.merge(:id => (!from_columns.detect {|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s)) - table_definition = nil + def copy_table(from, to, options = {}) #:nodoc: + options = options.merge(:id => (!columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s)) create_table(to, options) do |definition| - table_definition = definition - from_columns.each do |column| + @definition = definition + columns(from).each do |column| column_name = options[:rename] ? (options[:rename][column.name] || options[:rename][column.name.to_sym] || column.name) : column.name - table_definition.column(column_name, column.type, + @definition.column(column_name, column.type, :limit => column.limit, :default => column.default, :precision => column.precision, :scale => column.scale, :null => column.null) end - table_definition.primary_key from_primary_key if from_primary_key - table_definition.instance_eval(&block) if block + @definition.primary_key(primary_key(from)) if primary_key(from) + yield @definition if block_given? end copy_table_indexes(from, to, options[:rename] || {}) copy_table_contents(from, to, - table_definition.columns.map {|column| column.name}, + @definition.columns.map {|column| column.name}, options[:rename] || {}) end diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index 92550c7efc..76c37cc367 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -64,13 +64,12 @@ module ActiveRecord end def create_table! - id_col_name, data_col_name = session_id_column, data_column_name connection_pool.clear_table_cache!(table_name) connection.create_table(table_name) do |t| - t.string id_col_name, :limit => 255 - t.text data_col_name + t.string session_id_column, :limit => 255 + t.text data_column_name end - connection.add_index table_name, id_col_name, :unique => true + connection.add_index table_name, session_id_column, :unique => true end end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index ae5b2a62b5..3e219f2a49 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1639,126 +1639,6 @@ if ActiveRecord::Base.connection.supports_migrations? end - class SexyMigrationsTest < ActiveRecord::TestCase - def test_references_column_type_adds_id - with_new_table do |t| - t.expects(:column).with('customer_id', :integer, {}) - t.references :customer - end - end - - def test_references_column_type_with_polymorphic_adds_type - with_new_table do |t| - t.expects(:column).with('taggable_type', :string, {}) - t.expects(:column).with('taggable_id', :integer, {}) - t.references :taggable, :polymorphic => true - end - end - - def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag - with_new_table do |t| - t.expects(:column).with('taggable_type', :string, {:null => false}) - t.expects(:column).with('taggable_id', :integer, {:null => false}) - t.references :taggable, :polymorphic => true, :null => false - end - end - - def test_belongs_to_works_like_references - with_new_table do |t| - t.expects(:column).with('customer_id', :integer, {}) - t.belongs_to :customer - end - end - - def test_timestamps_creates_updated_at_and_created_at - with_new_table do |t| - t.expects(:column).with(:created_at, :datetime, kind_of(Hash)) - t.expects(:column).with(:updated_at, :datetime, kind_of(Hash)) - t.timestamps - end - end - - def test_integer_creates_integer_column - with_new_table do |t| - t.expects(:column).with(:foo, 'integer', {}) - t.expects(:column).with(:bar, 'integer', {}) - t.integer :foo, :bar - end - end - - def test_string_creates_string_column - with_new_table do |t| - t.expects(:column).with(:foo, 'string', {}) - t.expects(:column).with(:bar, 'string', {}) - t.string :foo, :bar - end - end - - if current_adapter?(:PostgreSQLAdapter) || current_adapter?(:SQLite3Adapter) || current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter) - def test_xml_creates_xml_column - type = current_adapter?(:PostgreSQLAdapter) ? 'xml' : :text - - with_new_table do |t| - t.expects(:column).with(:data, type, {}) - t.xml :data - end - end - else - def test_xml_creates_xml_column - with_new_table do |t| - assert_raises(NotImplementedError) do - t.xml :data - end - end - end - end - - protected - def with_new_table - Person.connection.create_table :delete_me, :force => true do |t| - yield t - end - ensure - Person.connection.drop_table :delete_me rescue nil - end - - end # SexyMigrationsTest - - class SexierMigrationsTest < ActiveRecord::TestCase - def test_create_table_with_column_without_block_parameter - Person.connection.create_table :testings, :force => true do - column :foo, :string - end - assert Person.connection.column_exists?(:testings, :foo, :string) - ensure - Person.connection.drop_table :testings rescue nil - end - - def test_create_table_with_sexy_column_without_block_parameter - Person.connection.create_table :testings, :force => true do - integer :bar - end - assert Person.connection.column_exists?(:testings, :bar, :integer) - ensure - Person.connection.drop_table :testings rescue nil - end - - def test_create_table_should_not_have_mixed_syntax - assert_raise(NoMethodError) do - Person.connection.create_table :testings, :force => true do |t| - t.string :foo - integer :bar - end - end - assert_raise(NameError) do - Person.connection.create_table :testings, :force => true do - t.string :foo - integer :bar - end - end - end - end # SexierMigrationsTest - class MigrationLoggerTest < ActiveRecord::TestCase def test_migration_should_be_run_without_logger previous_logger = ActiveRecord::Base.logger -- cgit v1.2.3 From 9b534060bfafbf1db36e73bb3e538b8c412dcc54 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Fri, 18 Nov 2011 01:17:21 +0530 Subject: update guide: db:structure:dump produces structure.sql now --- railties/guides/source/migrations.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile index 23e36b39f9..5b52a93853 100644 --- a/railties/guides/source/migrations.textile +++ b/railties/guides/source/migrations.textile @@ -658,7 +658,7 @@ In many ways this is exactly what it is. This file is created by inspecting the There is however a trade-off: +db/schema.rb+ cannot express database specific items such as foreign key constraints, triggers, or stored procedures. While in a migration you can execute custom SQL statements, the schema dumper cannot reconstitute those statements from the database. If you are using features like this, then you should set the schema format to +:sql+. -Instead of using Active Record's schema dumper, the database's structure will be dumped using a tool specific to the database (via the +db:structure:dump+ Rake task) into +db/#{Rails.env}_structure.sql+. For example, for the PostgreSQL RDBMS, the +pg_dump+ utility is used. For MySQL, this file will contain the output of +SHOW CREATE TABLE+ for the various tables. Loading these schemas is simply a question of executing the SQL statements they contain. By definition, this will create a perfect copy of the database's structure. Using the +:sql+ schema format will, however, prevent loading the schema into a RDBMS other than the one used to create it. +Instead of using Active Record's schema dumper, the database's structure will be dumped using a tool specific to the database (via the +db:structure:dump+ Rake task) into +db/structure.sql+. For example, for the PostgreSQL RDBMS, the +pg_dump+ utility is used. For MySQL, this file will contain the output of +SHOW CREATE TABLE+ for the various tables. Loading these schemas is simply a question of executing the SQL statements they contain. By definition, this will create a perfect copy of the database's structure. Using the +:sql+ schema format will, however, prevent loading the schema into a RDBMS other than the one used to create it. h4. Schema Dumps and Source Control -- cgit v1.2.3 From 8d83e339fc91bfba51bb30384efc1bca6a099a53 Mon Sep 17 00:00:00 2001 From: gregolsen Date: Thu, 17 Nov 2011 22:17:33 +0200 Subject: updating API docstring so that user can infer default value --- activesupport/lib/active_support/core_ext/date/calculations.rb | 4 ++-- activesupport/lib/active_support/core_ext/time/calculations.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 26a99658cc..c6d5f29690 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -192,13 +192,13 @@ class Date alias :sunday :end_of_week alias :at_end_of_week :end_of_week - # Returns a new Date/DateTime representing the start of the given day in the previous week (default is Monday). + # Returns a new Date/DateTime representing the start of the given day in the previous week (default is :monday). def prev_week(day = :monday) result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day] self.acts_like?(:time) ? result.change(:hour => 0) : result end - # Returns a new Date/DateTime representing the start of the given day in next week (default is Monday). + # Returns a new Date/DateTime representing the start of the given day in next week (default is :monday). def next_week(day = :monday) result = (self + 7).beginning_of_week + DAYS_INTO_WEEK[day] self.acts_like?(:time) ? result.change(:hour => 0) : result diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 372dd69212..43cd103481 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -176,12 +176,12 @@ class Time end alias :at_end_of_week :end_of_week - # Returns a new Time representing the start of the given day in the previous week (default is Monday). + # Returns a new Time representing the start of the given day in the previous week (default is :monday). def prev_week(day = :monday) ago(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0) end - # Returns a new Time representing the start of the given day in next week (default is Monday). + # Returns a new Time representing the start of the given day in next week (default is :monday). def next_week(day = :monday) since(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0) end -- cgit v1.2.3 From e37597072587e24a1daf62191fa22e7dbbeaffea Mon Sep 17 00:00:00 2001 From: Philip Arndt Date: Fri, 18 Nov 2011 10:17:16 +1300 Subject: Fixed typo: expect -> expected --- activesupport/lib/active_support/dependencies.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index b3ac271778..db90de4682 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -428,7 +428,7 @@ module ActiveSupport #:nodoc: end # Attempt to autoload the provided module name by searching for a directory - # matching the expect path suffix. If found, the module is created and assigned + # matching the expected path suffix. If found, the module is created and assigned # to +into+'s constants with the name +const_name+. Provided that the directory # was loaded from a reloadable base path, it is added to the set of constants # that are to be unloaded. -- cgit v1.2.3 From d57d8098fc269a26ea0051a9027a33af1a9a4b2b Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 17 Nov 2011 23:07:06 +0100 Subject: warn the user values are directly interpolated into _html translation strings --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 ++ railties/guides/source/i18n.textile | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index be64dc823e..0e6c3c5724 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -43,6 +43,8 @@ module ActionView # a safe HTML string that won't be escaped by other HTML helper methods. This # naming convention helps to identify translations that include HTML tags so that # you know what kind of output to expect when you call translate in a template. + # Note however that rule extends to interpolated values, so you are responsible + # for passing them already escaped in the call, if they need to be. def translate(key, options = {}) options.merge!(:rescue_format => :html) unless options.key?(:rescue_format) translation = I18n.translate(scope_key_by_partial(key), options) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 2d4cc13571..43afa6c9e2 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -634,6 +634,18 @@ en: !images/i18n/demo_html_safe.png(i18n demo html safe)! +Please note that values are interpolated directly into the translation. +If they need to be escaped you need to pass them already escaped in the +t+ call. + + +# config/locales/en.yml +en: + welcome_html: Welcome %{name}! + +<%# Note the call to h() to avoid injection %> +<%= t('welcome_html', :name => h(user.name)) %> + + h3. How to Store your Custom Translations The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format. [2] -- cgit v1.2.3 From a437986f433a775c7c370ad3f0273938015699df Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Nov 2011 14:41:53 -0800 Subject: allow people to set a local .Gemfile so that things like ruby-debug are not required for regular development --- .gitignore | 1 + Gemfile | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index aa14cee911..52a431867c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # Check out http://help.github.com/ignore-files/ for how to set that up. debug.log +.Gemfile /.bundle /.rbenv-version /.rvmrc diff --git a/Gemfile b/Gemfile index 97605e32b5..b0fbb3b310 100644 --- a/Gemfile +++ b/Gemfile @@ -36,13 +36,11 @@ gem "memcache-client", ">= 1.8.5" platforms :mri_18 do gem "system_timer" - gem "ruby-debug", ">= 0.10.3" unless ENV['TRAVIS'] gem "json" end -platforms :mri_19 do - gem "ruby-debug19", :require => "ruby-debug" unless ENV['TRAVIS'] || RUBY_VERSION >= "2.0" -end +# Add your own local bundler stuff +instance_eval File.read ".Gemfile" if File.exists? ".Gemfile" platforms :mri do group :test do @@ -69,7 +67,6 @@ platforms :ruby do end platforms :jruby do - gem "ruby-debug", ">= 0.10.3" gem "json" gem "activerecord-jdbcsqlite3-adapter", ">= 1.2.0" -- cgit v1.2.3 From 1079724fe643fe63e6d58a37274c2cf0ff172a8b Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 17 Nov 2011 23:59:19 +0100 Subject: Revert "warn the user values are directly interpolated into _html translation strings" Reason: After another round of discussion, it has been decided to let interpolation deal with unsafe strings as it should do. This reverts commit d57d8098fc269a26ea0051a9027a33af1a9a4b2b. --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 -- railties/guides/source/i18n.textile | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 0e6c3c5724..be64dc823e 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -43,8 +43,6 @@ module ActionView # a safe HTML string that won't be escaped by other HTML helper methods. This # naming convention helps to identify translations that include HTML tags so that # you know what kind of output to expect when you call translate in a template. - # Note however that rule extends to interpolated values, so you are responsible - # for passing them already escaped in the call, if they need to be. def translate(key, options = {}) options.merge!(:rescue_format => :html) unless options.key?(:rescue_format) translation = I18n.translate(scope_key_by_partial(key), options) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 43afa6c9e2..2d4cc13571 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -634,18 +634,6 @@ en: !images/i18n/demo_html_safe.png(i18n demo html safe)! -Please note that values are interpolated directly into the translation. -If they need to be escaped you need to pass them already escaped in the +t+ call. - - -# config/locales/en.yml -en: - welcome_html: Welcome %{name}! - -<%# Note the call to h() to avoid injection %> -<%= t('welcome_html', :name => h(user.name)) %> - - h3. How to Store your Custom Translations The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format. [2] -- cgit v1.2.3 From e8d57f361a9982382f75449ec0d65d6c798b9ce2 Mon Sep 17 00:00:00 2001 From: lest Date: Thu, 17 Nov 2011 18:29:55 +0300 Subject: _html translation should escape interpolated arguments --- actionpack/CHANGELOG.md | 14 ++++++++++++++ actionpack/lib/action_view/helpers/translation_helper.rb | 13 +++++++++---- actionpack/test/template/translation_helper_test.rb | 6 ++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 4c265c41d8..9d847c763b 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -64,6 +64,20 @@ ## Rails 3.1.2 (unreleased) ## +* Fix XSS security vulnerability in the `translate` helper method. When using interpolation + in combination with HTML-safe translations, the interpolated input would not get HTML + escaped. *GH 3664* + + Before: + + translate('foo_html', :something => '\n}, javascript_include_tag(:application, :debug => true) + assert_match %r{}, + javascript_include_tag('jquery.plugin', :digest => false) + @config.assets.compile = true @config.assets.debug = true assert_match %r{}, -- cgit v1.2.3 From 3a1d51959bf569a7419fe8ab9416b338334b4800 Mon Sep 17 00:00:00 2001 From: lest Date: Tue, 22 Nov 2011 17:36:58 +0300 Subject: deprecation warning, changelog entry --- actionpack/CHANGELOG.md | 4 ++++ actionpack/lib/action_dispatch/middleware/show_exceptions.rb | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index dc52262503..fe422f71d5 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,9 @@ ## Rails 3.2.0 (unreleased) ## +* Refactor ActionDispatch::ShowExceptions. Controller is responsible for choice to show exceptions. *Sergey Nartimov* + + It's possible to override +show_detailed_exceptions?+ in controllers to specify which requests should provide debugging information on errors. + * Responders now return 204 No Content for API requests without a response body (as in the new scaffold) *José Valim* * Added ActionDispatch::RequestId middleware that'll make a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog *DHH* diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 569063f4db..52dce4cc81 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -2,6 +2,7 @@ require 'active_support/core_ext/exception' require 'action_controller/metal/exceptions' require 'active_support/notifications' require 'action_dispatch/http/request' +require 'active_support/deprecation' module ActionDispatch # This middleware rescues any exception returned by the application and renders @@ -38,7 +39,8 @@ module ActionDispatch "application's log file and/or the web server's log file to find out what " << "went wrong."]] - def initialize(app) + def initialize(app, consider_all_requests_local = nil) + ActiveSupport::Deprecation.warn "Passing consider_all_requests_local option to ActionDispatch::ShowExceptions middleware no longer works" unless consider_all_requests_local.nil? @app = app end -- cgit v1.2.3 From 05e02deb686fc21f99c2d1dcf3abc987796e0e19 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 22 Nov 2011 15:16:23 -0500 Subject: Make explicit the default media when calling stylesheet_tag and change the default generators. --- .../action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb | 3 +++ .../guides/code/getting_started/app/views/layouts/application.html.erb | 2 +- .../rails/app/templates/app/views/layouts/application.html.erb.tt | 2 +- .../templates/app/views/layouts/%name%/application.html.erb.tt | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index 343153c8c5..41958c6559 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -68,6 +68,9 @@ module ActionView # Returns a stylesheet link tag for the sources specified as arguments. If # you don't specify an extension, .css will be appended automatically. # You can modify the link attributes by passing a hash as the last argument. + # For historical reasons, the 'media' attribute will always be present and defaults + # to "screen", so you must explicitely set it to "all" for the stylesheet(s) to + # apply to all media types. # # ==== Examples # stylesheet_link_tag "style" # => diff --git a/railties/guides/code/getting_started/app/views/layouts/application.html.erb b/railties/guides/code/getting_started/app/views/layouts/application.html.erb index 1e1e4b9a99..7fd6b4f516 100644 --- a/railties/guides/code/getting_started/app/views/layouts/application.html.erb +++ b/railties/guides/code/getting_started/app/views/layouts/application.html.erb @@ -2,7 +2,7 @@ Blog - <%= stylesheet_link_tag "application" %> + <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt index c63d1b6ac5..bba96a7431 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt @@ -2,7 +2,7 @@ <%= camelized %> - <%%= stylesheet_link_tag "application" %> + <%%= stylesheet_link_tag "application", :media => "all" %> <%%= javascript_include_tag "application" %> <%%= csrf_meta_tags %> diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt index 01550dec2f..bd983fb90f 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt @@ -2,7 +2,7 @@ <%= camelized %> - <%%= stylesheet_link_tag "<%= name %>/application" %> + <%%= stylesheet_link_tag "<%= name %>/application", :media => "all" %> <%%= javascript_include_tag "<%= name %>/application" %> <%%= csrf_meta_tags %> -- cgit v1.2.3 From a4912078c7d345a347f023ef28c0986458bdebf5 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 22 Nov 2011 15:37:16 -0500 Subject: Fix inconsistencies with Time{WithZone}#{hash,eql?} --- .../lib/active_support/core_ext/time/calculations.rb | 10 ++++++++++ activesupport/lib/active_support/time_with_zone.rb | 7 +++++-- activesupport/test/core_ext/time_ext_test.rb | 6 ++++++ activesupport/test/core_ext/time_with_zone_test.rb | 11 +++++++++-- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 372dd69212..7a55086452 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -312,4 +312,14 @@ class Time end alias_method :compare_without_coercion, :<=> alias_method :<=>, :compare_with_coercion + + # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances + # can be eql? to an equivalent Time + def eql_with_coercion(other) + # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison + other = other.comparable_time if other.respond_to?(:comparable_time) + eql_without_coercion(other) + end + alias_method :eql_without_coercion, :eql? + alias_method :eql?, :eql_with_coercion end diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index 63279d0e6d..d3adf671a0 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -203,7 +203,11 @@ module ActiveSupport end def eql?(other) - utc == other + utc.eql?(other) + end + + def hash + utc.hash end def +(other) @@ -277,7 +281,6 @@ module ActiveSupport def to_i utc.to_i end - alias_method :hash, :to_i alias_method :tv_sec, :to_i # A TimeWithZone acts like a Time, so just return +self+. diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index ab9be4b18b..e7090eed08 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -744,6 +744,12 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] )) end + def test_eql? + assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) ) + assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) + assert_equal false,Time.utc(2000, 1, 1, 0, 0, 1).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) ) + end + def test_minus_with_time_with_zone assert_equal 86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] ) end diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index b2309ae806..9d9e411c28 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -200,8 +200,15 @@ class TimeWithZoneTest < Test::Unit::TestCase end def test_eql? - assert @twz.eql?(Time.utc(2000)) - assert @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) + assert_equal true, @twz.eql?(Time.utc(2000)) + assert_equal true, @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) + assert_equal false, @twz.eql?( Time.utc(2000, 1, 1, 0, 0, 1) ) + assert_equal false, @twz.eql?( DateTime.civil(1999, 12, 31, 23, 59, 59) ) + end + + def test_hash + assert_equal Time.utc(2000).hash, @twz.hash + assert_equal Time.utc(2000).hash, ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]).hash end def test_plus_with_integer -- cgit v1.2.3 From ea70e027b63a1b8bfe4087a4de978ad4eef5575b Mon Sep 17 00:00:00 2001 From: kennyj Date: Wed, 23 Nov 2011 23:49:43 +0900 Subject: Remove unreachable code, and add additional testcases. --- actionpack/lib/action_dispatch/middleware/params_parser.rb | 7 +------ actionpack/test/dispatch/request/json_params_parsing_test.rb | 12 ++++++++++++ actionpack/test/dispatch/request/xml_params_parsing_test.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index d4208ca96e..84e3dd16dd 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -54,12 +54,7 @@ module ActionDispatch rescue Exception => e # YAML, XML or Ruby code block errors logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" - raise - { "body" => request.raw_post, - "content_type" => request.content_mime_type, - "content_length" => request.content_length, - "exception" => "#{e.message} (#{e.class})", - "backtrace" => e.backtrace } + raise e end def content_type_from_legacy_post_data_format_header(env) diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb index d854d55173..d481a2df13 100644 --- a/actionpack/test/dispatch/request/json_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb @@ -45,6 +45,18 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest end end + test "occurring a parse error if parsing unsuccessful" do + with_test_routing do + begin + $stderr = StringIO.new # suppress the log + json = "[\"person]\": {\"name\": \"David\"}}" + assert_raise(MultiJson::DecodeError) { post "/parse", json, {'CONTENT_TYPE' => 'application/json', 'action_dispatch.show_exceptions' => false} } + ensure + $stderr = STDERR + end + end + end + private def assert_parses(expected, actual, headers = {}) with_test_routing do diff --git a/actionpack/test/dispatch/request/xml_params_parsing_test.rb b/actionpack/test/dispatch/request/xml_params_parsing_test.rb index 38453dfe48..65a25557b7 100644 --- a/actionpack/test/dispatch/request/xml_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/xml_params_parsing_test.rb @@ -67,6 +67,18 @@ class XmlParamsParsingTest < ActionDispatch::IntegrationTest end end + test "occurring a parse error if parsing unsuccessful" do + with_test_routing do + begin + $stderr = StringIO.new # suppress the log + xml = "David" + assert_raise(REXML::ParseException) { post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => false) } + ensure + $stderr = STDERR + end + end + end + test "parses multiple files" do xml = <<-end_body -- cgit v1.2.3 From d8e6dc9cf12096908a7a53dec07a397ba23b1088 Mon Sep 17 00:00:00 2001 From: Olek Janiszewski Date: Wed, 23 Nov 2011 18:06:15 +0100 Subject: Fix #3737 AS::expand_cache_key generates wrong key in certain situations `cache_key` method is never called when the argument is a 1-element array with something that responds to `cache_key` --- activesupport/lib/active_support/cache.rb | 14 ++++---------- activesupport/test/caching_test.rb | 12 ++++++++++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 2bf24558a6..cfd1a6dbe3 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -81,16 +81,10 @@ module ActiveSupport end expanded_cache_key << - if key.respond_to?(:cache_key) - key.cache_key - elsif key.is_a?(Array) - if key.size > 1 - key.collect { |element| expand_cache_key(element) }.to_param - else - key.first.to_param - end - elsif key - key.to_param + case + when key.respond_to?(:cache_key) then key.cache_key + when key.is_a?(Array) then key.map { |element| expand_cache_key(element) }.to_param + when key then key.to_param end.to_s expanded_cache_key diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index b1b6de0613..5c844b8122 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -12,10 +12,10 @@ class CacheKeyTest < ActiveSupport::TestCase begin ENV['RAILS_CACHE_ID'] = 'c99' assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo) - assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key([:foo]) + assert_equal 'c99/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo]) assert_equal 'c99/c99/foo/c99/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar]) assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key(:foo, :nm) - assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm) + assert_equal 'nm/c99/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm) assert_equal 'nm/c99/c99/foo/c99/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar], :nm) ensure ENV['RAILS_CACHE_ID'] = nil @@ -50,6 +50,14 @@ class CacheKeyTest < ActiveSupport::TestCase assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key(key) end + def test_array_with_something_that_responds_to_cache_key + key = 'foo' + def key.cache_key + :foo_key + end + assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key([key]) + end + end class CacheStoreSettingTest < ActiveSupport::TestCase -- cgit v1.2.3 From a650dd05f82028e8d1310f1b68b7bc430ea47dcf Mon Sep 17 00:00:00 2001 From: Olek Janiszewski Date: Wed, 23 Nov 2011 18:11:36 +0100 Subject: Fix #3737 AS::expand_cache_key generates wrong key in certain situations (part 2) `nil` and `false` both expand to `""` (empty string), while `true` expands to `"true"`; `false` should expand to `"false"` --- activesupport/lib/active_support/cache.rb | 2 +- activesupport/test/caching_test.rb | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index cfd1a6dbe3..12eeff4f4b 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -84,7 +84,7 @@ module ActiveSupport case when key.respond_to?(:cache_key) then key.cache_key when key.is_a?(Array) then key.map { |element| expand_cache_key(element) }.to_param - when key then key.to_param + else key.to_param end.to_s expanded_cache_key diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 5c844b8122..8871b1b0e9 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -42,7 +42,7 @@ class CacheKeyTest < ActiveSupport::TestCase end end - def test_respond_to_cache_key + def test_expand_cache_key_respond_to_cache_key key = 'foo' def key.cache_key :foo_key @@ -50,7 +50,7 @@ class CacheKeyTest < ActiveSupport::TestCase assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key(key) end - def test_array_with_something_that_responds_to_cache_key + def test_expand_cache_key_array_with_something_that_responds_to_cache_key key = 'foo' def key.cache_key :foo_key @@ -58,6 +58,17 @@ class CacheKeyTest < ActiveSupport::TestCase assert_equal 'foo_key', ActiveSupport::Cache.expand_cache_key([key]) end + def test_expand_cache_key_of_nil + assert_equal '', ActiveSupport::Cache.expand_cache_key(nil) + end + + def test_expand_cache_key_of_false + assert_equal 'false', ActiveSupport::Cache.expand_cache_key(false) + end + + def test_expand_cache_key_of_true + assert_equal 'true', ActiveSupport::Cache.expand_cache_key(true) + end end class CacheStoreSettingTest < ActiveSupport::TestCase -- cgit v1.2.3 From 3ee0116c949dfc5760d60fe9c77168fb3868a4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 23 Nov 2011 18:22:09 +0000 Subject: Optimize cache expansion by skipping rails cache id in nested keys. --- activesupport/lib/active_support/cache.rb | 114 ++++++++++++++++-------------- activesupport/test/caching_test.rb | 8 +-- 2 files changed, 64 insertions(+), 58 deletions(-) diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 12eeff4f4b..07f5fcdeb3 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -25,69 +25,75 @@ module ActiveSupport autoload :LocalCache, 'active_support/cache/strategy/local_cache' end - # Creates a new CacheStore object according to the given options. - # - # If no arguments are passed to this method, then a new - # ActiveSupport::Cache::MemoryStore object will be returned. - # - # If you pass a Symbol as the first argument, then a corresponding cache - # store class under the ActiveSupport::Cache namespace will be created. - # For example: - # - # ActiveSupport::Cache.lookup_store(:memory_store) - # # => returns a new ActiveSupport::Cache::MemoryStore object - # - # ActiveSupport::Cache.lookup_store(:mem_cache_store) - # # => returns a new ActiveSupport::Cache::MemCacheStore object - # - # Any additional arguments will be passed to the corresponding cache store - # class's constructor: - # - # ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache") - # # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache") - # - # If the first argument is not a Symbol, then it will simply be returned: - # - # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new) - # # => returns MyOwnCacheStore.new - def self.lookup_store(*store_option) - store, *parameters = *Array.wrap(store_option).flatten - - case store - when Symbol - store_class_name = store.to_s.camelize - store_class = - begin - require "active_support/cache/#{store}" - rescue LoadError => e - raise "Could not find cache store adapter for #{store} (#{e})" - else - ActiveSupport::Cache.const_get(store_class_name) - end - store_class.new(*parameters) - when nil - ActiveSupport::Cache::MemoryStore.new - else - store + class << self + # Creates a new CacheStore object according to the given options. + # + # If no arguments are passed to this method, then a new + # ActiveSupport::Cache::MemoryStore object will be returned. + # + # If you pass a Symbol as the first argument, then a corresponding cache + # store class under the ActiveSupport::Cache namespace will be created. + # For example: + # + # ActiveSupport::Cache.lookup_store(:memory_store) + # # => returns a new ActiveSupport::Cache::MemoryStore object + # + # ActiveSupport::Cache.lookup_store(:mem_cache_store) + # # => returns a new ActiveSupport::Cache::MemCacheStore object + # + # Any additional arguments will be passed to the corresponding cache store + # class's constructor: + # + # ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache") + # # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache") + # + # If the first argument is not a Symbol, then it will simply be returned: + # + # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new) + # # => returns MyOwnCacheStore.new + def lookup_store(*store_option) + store, *parameters = *Array.wrap(store_option).flatten + + case store + when Symbol + store_class_name = store.to_s.camelize + store_class = + begin + require "active_support/cache/#{store}" + rescue LoadError => e + raise "Could not find cache store adapter for #{store} (#{e})" + else + ActiveSupport::Cache.const_get(store_class_name) + end + store_class.new(*parameters) + when nil + ActiveSupport::Cache::MemoryStore.new + else + store + end end - end - def self.expand_cache_key(key, namespace = nil) - expanded_cache_key = namespace ? "#{namespace}/" : "" + def expand_cache_key(key, namespace = nil) + expanded_cache_key = namespace ? "#{namespace}/" : "" + + prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"] + if prefix + expanded_cache_key << "#{prefix}/" + end - prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"] - if prefix - expanded_cache_key << "#{prefix}/" + expanded_cache_key << retrieve_cache_key(key) + expanded_cache_key end - expanded_cache_key << + private + + def retrieve_cache_key(key) case when key.respond_to?(:cache_key) then key.cache_key - when key.is_a?(Array) then key.map { |element| expand_cache_key(element) }.to_param + when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param else key.to_param end.to_s - - expanded_cache_key + end end # An abstract cache store class. There are multiple cache store diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 8871b1b0e9..5d7464c623 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -12,11 +12,11 @@ class CacheKeyTest < ActiveSupport::TestCase begin ENV['RAILS_CACHE_ID'] = 'c99' assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key(:foo) - assert_equal 'c99/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo]) - assert_equal 'c99/c99/foo/c99/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar]) + assert_equal 'c99/foo', ActiveSupport::Cache.expand_cache_key([:foo]) + assert_equal 'c99/foo/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar]) assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key(:foo, :nm) - assert_equal 'nm/c99/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm) - assert_equal 'nm/c99/c99/foo/c99/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar], :nm) + assert_equal 'nm/c99/foo', ActiveSupport::Cache.expand_cache_key([:foo], :nm) + assert_equal 'nm/c99/foo/bar', ActiveSupport::Cache.expand_cache_key([:foo, :bar], :nm) ensure ENV['RAILS_CACHE_ID'] = nil end -- cgit v1.2.3 From fd86a1b6b068df87164d5763bdcd4a323a1e76f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 23 Nov 2011 19:06:45 +0000 Subject: Rely on a public contract between railties instead of accessing railtie methods directly. --- .../abstract_controller/railties/routes_helpers.rb | 4 +- actionpack/lib/action_controller/railties/paths.rb | 7 ++-- .../test/activerecord/polymorphic_routes_test.rb | 6 +-- actionpack/test/lib/controller/fake_models.rb | 4 +- actionpack/test/template/form_helper_test.rb | 2 +- activemodel/lib/active_model/naming.rb | 24 ++++++------ activemodel/test/cases/naming_test.rb | 38 +++++++++++++++++-- activemodel/test/models/blog_post.rb | 8 +--- railties/lib/rails/application.rb | 4 ++ railties/lib/rails/engine.rb | 43 +++++++++++++--------- railties/lib/rails/railtie.rb | 2 +- railties/test/railties/engine_test.rb | 6 +-- 12 files changed, 94 insertions(+), 54 deletions(-) diff --git a/actionpack/lib/abstract_controller/railties/routes_helpers.rb b/actionpack/lib/abstract_controller/railties/routes_helpers.rb index dec1e9d6d9..6684f46f64 100644 --- a/actionpack/lib/abstract_controller/railties/routes_helpers.rb +++ b/actionpack/lib/abstract_controller/railties/routes_helpers.rb @@ -5,8 +5,8 @@ module AbstractController Module.new do define_method(:inherited) do |klass| super(klass) - if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) } - klass.send(:include, namespace._railtie.routes.url_helpers) + if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) } + klass.send(:include, namespace.railtie_routes_url_helpers) else klass.send(:include, routes.url_helpers) end diff --git a/actionpack/lib/action_controller/railties/paths.rb b/actionpack/lib/action_controller/railties/paths.rb index 699c44c62c..bbe63149ad 100644 --- a/actionpack/lib/action_controller/railties/paths.rb +++ b/actionpack/lib/action_controller/railties/paths.rb @@ -6,13 +6,14 @@ module ActionController define_method(:inherited) do |klass| super(klass) - if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) } - paths = namespace._railtie.paths["app/helpers"].existent + if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) } + paths = namespace.railtie_helpers_paths else - paths = app.config.helpers_paths + paths = app.helpers_paths end klass.helpers_path = paths + if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers klass.helper :all end diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index 20d11377f6..fc829aa6b4 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -34,10 +34,8 @@ module Blog set_table_name 'projects' end - def self._railtie - o = Object.new - def o.railtie_name; "blog" end - o + def self.use_relative_model_naming? + true end end diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index 363403092b..f2362714d7 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -175,8 +175,8 @@ class HashBackedAuthor < Hash end module Blog - def self._railtie - self + def self.use_relative_model_naming? + true end class Post < Struct.new(:title, :id) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 34486bb151..ccedcd7dac 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -740,7 +740,7 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end - def test_form_for_with_isolated_namespaced_model + def test_form_for_with_model_using_relative_model_naming form_for(@blog_post) do |f| concat f.text_field :title concat f.submit('Edit post') diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index f16459ede2..2566920d63 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -13,18 +13,18 @@ module ActiveModel def initialize(klass, namespace = nil, name = nil) name ||= klass.name super(name) - @unnamespaced = self.sub(/^#{namespace.name}::/, '') if namespace - @klass = klass - @singular = _singularize(self).freeze - @plural = ActiveSupport::Inflector.pluralize(@singular).freeze - @element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze - @human = ActiveSupport::Inflector.humanize(@element).freeze - @collection = ActiveSupport::Inflector.tableize(self).freeze + @unnamespaced = self.sub(/^#{namespace.name}::/, '') if namespace + @klass = klass + @singular = _singularize(self).freeze + @plural = ActiveSupport::Inflector.pluralize(@singular).freeze + @element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze + @human = ActiveSupport::Inflector.humanize(@element).freeze + @collection = ActiveSupport::Inflector.tableize(self).freeze @partial_path = "#{@collection}/#{@element}".freeze - @param_key = (namespace ? _singularize(@unnamespaced) : @singular).freeze - @route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural).freeze - @i18n_key = self.underscore.to_sym + @param_key = (namespace ? _singularize(@unnamespaced) : @singular).freeze + @route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural).freeze + @i18n_key = self.underscore.to_sym end # Transform the model name into a more humane format, using I18n. By default, @@ -79,7 +79,9 @@ module ActiveModel # used to retrieve all kinds of naming-related information. def model_name @_model_name ||= begin - namespace = self.parents.detect { |n| n.respond_to?(:_railtie) } + namespace = self.parents.detect do |n| + n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming? + end ActiveModel::Name.new(self, namespace) end end diff --git a/activemodel/test/cases/naming_test.rb b/activemodel/test/cases/naming_test.rb index 5f943729dd..a5ee2d6090 100644 --- a/activemodel/test/cases/naming_test.rb +++ b/activemodel/test/cases/naming_test.rb @@ -74,10 +74,6 @@ class NamingWithNamespacedModelInIsolatedNamespaceTest < ActiveModel::TestCase def test_param_key assert_equal 'post', @model_name.param_key end - - def test_recognizing_namespace - assert_equal 'Post', Blog::Post.model_name.instance_variable_get("@unnamespaced") - end end class NamingWithNamespacedModelInSharedNamespaceTest < ActiveModel::TestCase @@ -160,6 +156,40 @@ class NamingWithSuppliedModelNameTest < ActiveModel::TestCase end end +class NamingUsingRelativeModelNameTest < ActiveModel::TestCase + def setup + @model_name = Blog::Post.model_name + end + + def test_singular + assert_equal 'blog_post', @model_name.singular + end + + def test_plural + assert_equal 'blog_posts', @model_name.plural + end + + def test_element + assert_equal 'post', @model_name.element + end + + def test_collection + assert_equal 'blog/posts', @model_name.collection + end + + def test_human + assert_equal 'Post', @model_name.human + end + + def test_route_key + assert_equal 'posts', @model_name.route_key + end + + def test_param_key + assert_equal 'post', @model_name.param_key + end +end + class NamingHelpersTest < Test::Unit::TestCase def setup @klass = Contact diff --git a/activemodel/test/models/blog_post.rb b/activemodel/test/models/blog_post.rb index d289177259..46eba857df 100644 --- a/activemodel/test/models/blog_post.rb +++ b/activemodel/test/models/blog_post.rb @@ -1,10 +1,6 @@ module Blog - def self._railtie - Object.new - end - - def self.table_name_prefix - "blog_" + def self.use_relative_model_naming? + true end class Post diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 817fa39cab..0b72a7ed84 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -141,6 +141,10 @@ module Rails self end + def helpers_paths + config.helpers_paths + end + protected alias :build_middleware_stack :app diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index d652c6b7fe..335a0fb1b5 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -371,20 +371,28 @@ module Rails self.routes.default_scope = { :module => ActiveSupport::Inflector.underscore(mod.name) } self.isolated = true - unless mod.respond_to?(:_railtie) - name = engine_name - _railtie = self + unless mod.respond_to?(:railtie_namespace) + name, railtie = engine_name, self + mod.singleton_class.instance_eval do - define_method(:_railtie) do - _railtie - end + define_method(:railtie_namespace) { railtie } unless mod.respond_to?(:table_name_prefix) - define_method(:table_name_prefix) do - "#{name}_" - end + define_method(:table_name_prefix) { "#{name}_" } + end + + unless mod.respond_to?(:use_relative_model_naming?) + class_eval "def use_relative_model_naming?; true; end", __FILE__, __LINE__ + end + + unless mod.respond_to?(:railtie_helpers_paths) + define_method(:railtie_helpers_paths) { railtie.helpers_paths } + end + + unless mod.respond_to?(:railtie_routes_url_helpers) + define_method(:railtie_routes_url_helpers) { railtie.routes_url_helpers } end - end + end end end @@ -429,13 +437,6 @@ module Rails def helpers @helpers ||= begin helpers = Module.new - - helpers_paths = if config.respond_to?(:helpers_paths) - config.helpers_paths - else - paths["app/helpers"].existent - end - all = ActionController::Base.all_helpers_from_path(helpers_paths) ActionController::Base.modules_for_helpers(all).each do |mod| helpers.send(:include, mod) @@ -444,6 +445,14 @@ module Rails end end + def helpers_paths + paths["app/helpers"].existent + end + + def routes_url_helpers + routes.url_helpers + end + def app @app ||= begin config.middleware = config.middleware.merge_into(default_middleware_stack) diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb index e8fb1f3d98..f0991b99af 100644 --- a/railties/lib/rails/railtie.rb +++ b/railties/lib/rails/railtie.rb @@ -196,7 +196,7 @@ module Rails end def railtie_namespace - @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:_railtie) } + @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) } end end end diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 22dbcf9644..e8081c977f 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -323,7 +323,7 @@ module RailtiesTest assert_equal "bukkits_", Bukkits.table_name_prefix assert_equal "bukkits", Bukkits::Engine.engine_name - assert_equal Bukkits._railtie, Bukkits::Engine + assert_equal Bukkits.railtie_namespace, Bukkits::Engine assert ::Bukkits::MyMailer.method_defined?(:foo_path) assert !::Bukkits::MyMailer.method_defined?(:bar_path) @@ -467,7 +467,7 @@ module RailtiesTest assert_nil Rails.application.load_seed end - test "using namespace more than once on one module should not overwrite _railtie method" do + test "using namespace more than once on one module should not overwrite railtie_namespace method" do @plugin.write "lib/bukkits.rb", <<-RUBY module AppTemplate class Engine < ::Rails::Engine @@ -484,7 +484,7 @@ module RailtiesTest boot_rails - assert_equal AppTemplate._railtie, AppTemplate::Engine + assert_equal AppTemplate.railtie_namespace, AppTemplate::Engine end test "properly reload routes" do -- cgit v1.2.3