aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/metal.rb11
-rw-r--r--actionpack/lib/action_controller/metal/rack_delegation.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb43
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionpack/test/dispatch/routing_test.rb47
-rw-r--r--actionpack/test/template/form_options_helper_test.rb30
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb4
-rw-r--r--activerecord/lib/active_record/transactions.rb1
-rw-r--r--activerecord/test/cases/adapter_test.rb15
-rw-r--r--activerecord/test/cases/autosave_association_test.rb1
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb14
-rw-r--r--activesupport/lib/active_support/json/backends/yajl.rb2
-rwxr-xr-xbin/rails2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml60
14 files changed, 165 insertions, 71 deletions
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 775a5002e2..159d1f0748 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -52,8 +52,7 @@ module ActionController
class Metal < AbstractController::Base
abstract!
- # :api: public
- attr_internal :params, :env
+ attr_internal :env
# Returns the last part of the controller's name, underscored, without the ending
# "Controller". For instance, MyApp::MyPostsController would return "my_posts" for
@@ -85,6 +84,14 @@ module ActionController
super
end
+ def params
+ @_params ||= request.parameters
+ end
+
+ def params=(val)
+ @_params = val
+ end
+
# Basic implementations for content_type=, location=, and headers are
# provided to reduce the dependency on the RackDelegation module
# in Renderer and Redirector.
diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb
index 508ea6e2b7..544b4989c7 100644
--- a/actionpack/lib/action_controller/metal/rack_delegation.rb
+++ b/actionpack/lib/action_controller/metal/rack_delegation.rb
@@ -14,10 +14,6 @@ module ActionController
super(action, request)
end
- def params
- @_params ||= @_request.parameters
- end
-
def response_body=(body)
response.body = body if response
super
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 95e56566a3..0018b6485b 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -647,7 +647,9 @@ module ActionDispatch
with_scope_level(:new) do
scope(*parent_resource.new_scope) do
- yield
+ scope(action_path(:new)) do
+ yield
+ end
end
end
end
@@ -723,7 +725,17 @@ module ActionDispatch
options = options_for_action(args.first, options)
with_exclusive_scope do
- return match(path, options)
+ return super(path, options)
+ end
+ elsif resource_method_scope?
+ path = path_for_custom_action
+ options[:as] = name_for_action(options[:as]) if options[:as]
+ args.push(options)
+
+ with_exclusive_scope do
+ scope(path) do
+ return super
+ end
end
end
@@ -737,7 +749,7 @@ module ActionDispatch
def root(options={})
if @scope[:scope_level] == :resources
- with_scope_level(:collection) do
+ with_scope_level(:nested) do
scope(parent_resource.path, :name_prefix => parent_resource.collection_name) do
super(options)
end
@@ -780,12 +792,18 @@ module ActionDispatch
[:resource, :resources].include?(@scope[:scope_level])
end
+ def resource_method_scope?
+ [:collection, :member, :new].include?(@scope[:scope_level])
+ end
+
def with_exclusive_scope
begin
old_name_prefix, old_path = @scope[:name_prefix], @scope[:path]
@scope[:name_prefix], @scope[:path] = nil, nil
- yield
+ with_scope_level(:exclusive) do
+ yield
+ end
ensure
@scope[:name_prefix], @scope[:path] = old_name_prefix, old_path
end
@@ -844,10 +862,8 @@ module ActionDispatch
end
else
case @scope[:scope_level]
- when :collection
+ when :collection, :new
"#{@scope[:path]}/#{action_path(action)}(.:format)"
- when :new
- "#{@scope[:path]}/#{action_path(:new)}/#{action_path(action)}(.:format)"
else
if parent_resource.shallow?
"#{@scope[:module]}/#{parent_resource.path}/:id/#{action_path(action)}(.:format)"
@@ -858,6 +874,19 @@ module ActionDispatch
end
end
+ def path_for_custom_action
+ case @scope[:scope_level]
+ when :collection, :new
+ @scope[:path]
+ else
+ if parent_resource.shallow?
+ "#{@scope[:module]}/#{parent_resource.path}/:id"
+ else
+ @scope[:path]
+ end
+ end
+ end
+
def action_path(name, path_names = nil)
path_names ||= @scope[:path_names]
path_names[name.to_sym] || name.to_s
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index fe71d2cdf7..e48580e0ad 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -398,7 +398,7 @@ module ActionView
options_for_select += "<optgroup label=\"#{html_escape(group_label_string)}\">"
options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key)
options_for_select += '</optgroup>'
- end
+ end.html_safe
end
# Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 0b3bbcc86b..899990c69d 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -180,6 +180,33 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ resources :customers do
+ get "recent" => "customers#recent", :as => :recent, :on => :collection
+ get "profile" => "customers#profile", :as => :profile, :on => :member
+ post "preview" => "customers#preview", :as => :preview, :on => :new
+ resource :avatar do
+ get "thumbnail(.:format)" => "avatars#thumbnail", :as => :thumbnail, :on => :member
+ end
+ resources :invoices do
+ get "outstanding" => "invoices#outstanding", :as => :outstanding, :on => :collection
+ get "overdue", :to => :overdue, :on => :collection
+ get "print" => "invoices#print", :as => :print, :on => :member
+ post "preview" => "invoices#preview", :as => :preview, :on => :new
+ end
+ resources :notes, :shallow => true do
+ get "preview" => "notes#preview", :as => :preview, :on => :new
+ get "print" => "notes#print", :as => :print, :on => :member
+ end
+ end
+
+ namespace :api do
+ resources :customers do
+ get "recent" => "customers#recent", :as => :recent, :on => :collection
+ get "profile" => "customers#profile", :as => :profile, :on => :member
+ post "preview" => "customers#preview", :as => :preview, :on => :new
+ end
+ end
+
match 'sprockets.js' => ::TestRoutingMapper::SprocketsApp
match 'people/:id/update', :to => 'people#update', :as => :update_person
@@ -1295,6 +1322,26 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_custom_resource_routes_are_scoped
+ with_test_routes do
+ assert_equal '/customers/recent', recent_customers_path
+ assert_equal '/customers/1/profile', profile_customer_path(:id => '1')
+ assert_equal '/customers/new/preview', preview_new_customer_path
+ assert_equal '/customers/1/avatar/thumbnail.jpg', thumbnail_customer_avatar_path(:customer_id => '1', :format => :jpg)
+ assert_equal '/customers/1/invoices/outstanding', outstanding_customer_invoices_path(:customer_id => '1')
+ assert_equal '/customers/1/invoices/2/print', print_customer_invoice_path(:customer_id => '1', :id => '2')
+ assert_equal '/customers/1/invoices/new/preview', preview_new_customer_invoice_path(:customer_id => '1')
+ assert_equal '/customers/1/notes/new/preview', preview_new_customer_note_path(:customer_id => '1')
+ assert_equal '/notes/1/print', print_note_path(:id => '1')
+ assert_equal '/api/customers/recent', recent_api_customers_path
+ assert_equal '/api/customers/1/profile', profile_api_customer_path(:id => '1')
+ assert_equal '/api/customers/new/preview', preview_new_api_customer_path
+
+ get '/customers/1/invoices/overdue'
+ assert_equal 'invoices#overdue', @response.body
+ end
+ end
+
private
def with_test_routes
yield
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 19b73aa810..65b5f5ccc1 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -177,17 +177,16 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_option_groups_from_collection_for_select
- @continents = [
- Continent.new("<Africa>", [Country.new("<sa>", "<South Africa>"), Country.new("so", "Somalia")] ),
- Continent.new("Europe", [Country.new("dk", "Denmark"), Country.new("ie", "Ireland")] )
- ]
-
assert_dom_equal(
"<optgroup label=\"&lt;Africa&gt;\"><option value=\"&lt;sa&gt;\">&lt;South Africa&gt;</option>\n<option value=\"so\">Somalia</option></optgroup><optgroup label=\"Europe\"><option value=\"dk\" selected=\"selected\">Denmark</option>\n<option value=\"ie\">Ireland</option></optgroup>",
- option_groups_from_collection_for_select(@continents, "countries", "continent_name", "country_id", "country_name", "dk")
+ option_groups_from_collection_for_select(dummy_continents, "countries", "continent_name", "country_id", "country_name", "dk")
)
end
+ def test_option_groups_from_collection_for_select_returns_html_safe_string
+ assert option_groups_from_collection_for_select(dummy_continents, "countries", "continent_name", "country_id", "country_name", "dk").html_safe?
+ end
+
def test_grouped_options_for_select_with_array
assert_dom_equal(
"<optgroup label=\"North America\"><option value=\"US\">United States</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"Europe\"><option value=\"GB\">Great Britain</option>\n<option value=\"Germany\">Germany</option></optgroup>",
@@ -824,31 +823,21 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_grouped_collection_select
- @continents = [
- Continent.new("<Africa>", [Country.new("<sa>", "<South Africa>"), Country.new("so", "Somalia")] ),
- Continent.new("Europe", [Country.new("dk", "Denmark"), Country.new("ie", "Ireland")] )
- ]
-
@post = Post.new
@post.origin = 'dk'
assert_dom_equal(
%Q{<select id="post_origin" name="post[origin]"><optgroup label="&lt;Africa&gt;"><option value="&lt;sa&gt;">&lt;South Africa&gt;</option>\n<option value="so">Somalia</option></optgroup><optgroup label="Europe"><option value="dk" selected="selected">Denmark</option>\n<option value="ie">Ireland</option></optgroup></select>},
- grouped_collection_select("post", "origin", @continents, :countries, :continent_name, :country_id, :country_name)
+ grouped_collection_select("post", "origin", dummy_continents, :countries, :continent_name, :country_id, :country_name)
)
end
def test_grouped_collection_select_under_fields_for
- @continents = [
- Continent.new("<Africa>", [Country.new("<sa>", "<South Africa>"), Country.new("so", "Somalia")] ),
- Continent.new("Europe", [Country.new("dk", "Denmark"), Country.new("ie", "Ireland")] )
- ]
-
@post = Post.new
@post.origin = 'dk'
output_buffer = fields_for :post, @post do |f|
- concat f.grouped_collection_select("origin", @continents, :countries, :continent_name, :country_id, :country_name)
+ concat f.grouped_collection_select("origin", dummy_continents, :countries, :continent_name, :country_id, :country_name)
end
assert_dom_equal(
@@ -864,4 +853,9 @@ class FormOptionsHelperTest < ActionView::TestCase
Post.new("Babe went home", "Babe", "To a little house", "shh!"),
Post.new("Cabe went home", "Cabe", "To a little house", "shh!") ]
end
+
+ def dummy_continents
+ [ Continent.new("<Africa>", [Country.new("<sa>", "<South Africa>"), Country.new("so", "Somalia")] ),
+ Continent.new("Europe", [Country.new("dk", "Denmark"), Country.new("ie", "Ireland")] ) ]
+ end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index b9fb452eee..25432e9985 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -304,7 +304,7 @@ module ActiveRecord
begin
record.rolledback!(rollback)
rescue Exception => e
- record.logger.error(e) if record.respond_to?(:logger)
+ record.logger.error(e) if record.respond_to?(:logger) && record.logger
end
end
end
@@ -319,7 +319,7 @@ module ActiveRecord
begin
record.committed!
rescue Exception => e
- record.logger.error(e) if record.respond_to?(:logger)
+ record.logger.error(e) if record.respond_to?(:logger) && record.logger
end
end
end
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 620758f5af..775d9f0fb8 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -320,6 +320,7 @@ module ActiveRecord
if @_start_transaction_state[:level] < 1
restore_state = remove_instance_variable(:@_start_transaction_state)
if restore_state
+ @attributes = @attributes.dup if @attributes.frozen?
@new_record = restore_state[:new_record]
@destroyed = restore_state[:destroyed]
if restore_state[:id]
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index fc08c2178a..646aa88d80 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -65,15 +65,14 @@ class AdapterTest < ActiveRecord::TestCase
end
def test_not_specifying_database_name_for_cross_database_selects
- assert_nothing_raised do
- ActiveRecord::Base.establish_connection({
- :adapter => 'mysql',
- :username => 'rails'
- })
- ActiveRecord::Base.connection.execute "SELECT activerecord_unittest.pirates.*, activerecord_unittest2.courses.* FROM activerecord_unittest.pirates, activerecord_unittest2.courses"
+ begin
+ assert_nothing_raised do
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database))
+ ActiveRecord::Base.connection.execute "SELECT activerecord_unittest.pirates.*, activerecord_unittest2.courses.* FROM activerecord_unittest.pirates, activerecord_unittest2.courses"
+ end
+ ensure
+ ActiveRecord::Base.establish_connection 'arunit'
end
-
- ActiveRecord::Base.establish_connection 'arunit'
end
end
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 4e4f9c385c..3b89c12a3f 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -712,7 +712,6 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
end
assert_raise(RuntimeError) { assert !@pirate.save }
- assert before.first.frozen? # the first child was indeed destroyed
assert_equal before, @pirate.reload.send(association_name)
end
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index ebc16653cb..df123c9de8 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -221,20 +221,28 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert_equal 2, @first.rollbacks
end
- def test_after_transaction_callbacks_should_not_raise_errors
+ def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called
def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
def @first.last_after_transaction_error; @last_transaction_error; end
@first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
@first.after_rollback_block{|r| r.last_after_transaction_error = :rollback; raise "fail!";}
+ @second.after_commit_block{|r| r.history << :after_commit}
+ @second.after_rollback_block{|r| r.history << :after_rollback}
- @first.save!
+ Topic.transaction do
+ @first.save!
+ @second.save!
+ end
assert_equal :commit, @first.last_after_transaction_error
+ assert_equal [:after_commit], @second.history
+ @second.history.clear
Topic.transaction do
@first.save!
+ @second.save!
raise ActiveRecord::Rollback
end
-
assert_equal :rollback, @first.last_after_transaction_error
+ assert_equal [:after_rollback], @second.history
end
end
diff --git a/activesupport/lib/active_support/json/backends/yajl.rb b/activesupport/lib/active_support/json/backends/yajl.rb
index d76f8b03e4..64e50e0d87 100644
--- a/activesupport/lib/active_support/json/backends/yajl.rb
+++ b/activesupport/lib/active_support/json/backends/yajl.rb
@@ -1,4 +1,4 @@
-require 'yajl-ruby' unless defined?(Yajl)
+require 'yajl' unless defined?(Yajl)
module ActiveSupport
module JSON
diff --git a/bin/rails b/bin/rails
index 4a74726e9b..a628cc35ca 100755
--- a/bin/rails
+++ b/bin/rails
@@ -1,3 +1,5 @@
+#!/usr/bin/env ruby
+
begin
require "rails/cli"
rescue LoadError
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index 2784a949fb..df5ef33064 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
@@ -32,40 +32,52 @@
# please refer to the latest documents at http://rubyforge.org/docman/?group_id=2361
development:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,4] %>_dev
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,4] %>_dev
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false
test:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,4] %>_tst
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,4] %>_tst
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false
production:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,8] %>
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,8] %>
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false \ No newline at end of file