Merge branch 'master' of github.com:rails/rails

This commit is contained in:
José Valim
2010-06-20 00:12:54 +02:00
14 changed files with 167 additions and 73 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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!";}
@first.save!
assert_equal :commit, @first.last_after_transaction_error
@second.after_commit_block{|r| r.history << :after_commit}
@second.after_rollback_block{|r| r.history << :after_rollback}
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

View File

@@ -1,4 +1,4 @@
require 'yajl-ruby' unless defined?(Yajl)
require 'yajl' unless defined?(Yajl)
module ActiveSupport
module JSON

View File

@@ -1,3 +1,5 @@
#!/usr/bin/env ruby
begin
require "rails/cli"
rescue LoadError

View File

@@ -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