From 38bd60eae4b6d0ec6a29036c6a8d45b79b788af9 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 27 Apr 2009 18:16:55 -0700 Subject: Makes new callbacks support keys with special characters --- activesupport/lib/active_support/new_callbacks.rb | 1 + activesupport/test/new_callbacks_test.rb | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index 7a48dbac04..8a91e1c674 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -356,6 +356,7 @@ module ActiveSupport str = <<-RUBY_EVAL def _run_#{symbol}_callbacks(key = nil) if key + key = key.hash.to_s.gsub(/-/, '_') name = "_run__\#{self.class.name.split("::").last}__#{symbol}__\#{key}__callbacks" if respond_to?(name) diff --git a/activesupport/test/new_callbacks_test.rb b/activesupport/test/new_callbacks_test.rb index abe7790ebf..8c887e1bf1 100644 --- a/activesupport/test/new_callbacks_test.rb +++ b/activesupport/test/new_callbacks_test.rb @@ -255,6 +255,26 @@ module NewCallbacksTest end end + class HyphenatedCallbacks + include ActiveSupport::NewCallbacks + define_callbacks :save + attr_reader :stuff + + save_callback :before, :omg, :per_key => {:if => :yes} + + def yes() true end + + def omg + @stuff = "OMG" + end + + def save + _run_save_callbacks("hyphen-ated") do + @stuff + end + end + end + class AroundCallbacksTest < Test::Unit::TestCase def test_save_around around = AroundPerson.new @@ -381,4 +401,12 @@ module NewCallbacksTest assert_equal ["first", "second", "third", "second", "first"], terminator.history end end + + class HyphenatedKeyTest < Test::Unit::TestCase + def test_save + obj = HyphenatedCallbacks.new + obj.save + assert_equal obj.stuff, "OMG" + end + end end -- cgit v1.2.3 From 34509777fd375e5bc529f21ca66cf63263c2cf64 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 27 Apr 2009 18:16:55 -0700 Subject: Makes new callbacks support keys with special characters --- activesupport/lib/active_support/new_callbacks.rb | 1 + activesupport/test/new_callbacks_test.rb | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index 7a48dbac04..8a91e1c674 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -356,6 +356,7 @@ module ActiveSupport str = <<-RUBY_EVAL def _run_#{symbol}_callbacks(key = nil) if key + key = key.hash.to_s.gsub(/-/, '_') name = "_run__\#{self.class.name.split("::").last}__#{symbol}__\#{key}__callbacks" if respond_to?(name) diff --git a/activesupport/test/new_callbacks_test.rb b/activesupport/test/new_callbacks_test.rb index abe7790ebf..8c887e1bf1 100644 --- a/activesupport/test/new_callbacks_test.rb +++ b/activesupport/test/new_callbacks_test.rb @@ -255,6 +255,26 @@ module NewCallbacksTest end end + class HyphenatedCallbacks + include ActiveSupport::NewCallbacks + define_callbacks :save + attr_reader :stuff + + save_callback :before, :omg, :per_key => {:if => :yes} + + def yes() true end + + def omg + @stuff = "OMG" + end + + def save + _run_save_callbacks("hyphen-ated") do + @stuff + end + end + end + class AroundCallbacksTest < Test::Unit::TestCase def test_save_around around = AroundPerson.new @@ -381,4 +401,12 @@ module NewCallbacksTest assert_equal ["first", "second", "third", "second", "first"], terminator.history end end + + class HyphenatedKeyTest < Test::Unit::TestCase + def test_save + obj = HyphenatedCallbacks.new + obj.save + assert_equal obj.stuff, "OMG" + end + end end -- cgit v1.2.3 From 8a4e77b4200946ba4ed42fe5927a7400a846063a Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 27 Apr 2009 18:21:26 -0700 Subject: OMG, a lot of work --- actionpack/Rakefile | 11 +- .../lib/action_controller/abstract/layouts.rb | 5 +- .../lib/action_controller/abstract/renderer.rb | 2 + .../lib/action_controller/dispatch/dispatcher.rb | 2 +- .../lib/action_controller/dispatch/middlewares.rb | 2 +- actionpack/lib/action_controller/new_base.rb | 11 +- actionpack/lib/action_controller/new_base/base.rb | 2 + .../action_controller/new_base/compatibility.rb | 12 +++ .../abstract_controller_test.rb | 22 ++-- .../test/abstract_controller/layouts_test.rb | 2 +- actionpack/test/controller/render_test.rb | 3 + actionpack/test/lib/fixture_template.rb | 115 ++++++++++++++++----- actionpack/test/new_base/base_test.rb | 8 +- actionpack/test/new_base/render_action_test.rb | 8 +- .../test/new_base/render_implicit_action_test.rb | 30 ++++-- actionpack/test/new_base/render_layout_test.rb | 4 +- actionpack/test/new_base/render_template_test.rb | 39 ++++--- actionpack/test/new_base/render_text_test.rb | 4 +- actionpack/test/new_base/test_helper.rb | 14 ++- 19 files changed, 210 insertions(+), 86 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/compatibility.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 300c2ebf81..18610ed773 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -23,14 +23,14 @@ task :default => [ :test ] # Run the unit tests desc "Run all unit tests" -task :test => [:test_action_pack, :test_active_record_integration] +task :test => [:test_action_pack, :test_active_record_integration, :test_new_base] Rake::TestTask.new(:test_action_pack) do |t| t.libs << "test" # make sure we include the tests in alphabetical order as on some systems # this will not happen automatically and the tests (as a whole) will error - t.test_files = Dir.glob( "test/[cdft]*/**/*_test.rb" ).sort + t.test_files = Dir.glob( "test/{controller,dispatch,template}/**/*_test.rb" ).sort t.verbose = true #t.warning = true @@ -43,6 +43,13 @@ Rake::TestTask.new(:test_active_record_integration) do |t| t.verbose = true end +desc 'New Controller Tests' +Rake::TestTask.new(:test_new_base) do |t| + t.libs << "test" + t.test_files = Dir.glob("test/{abstract_controller,new_base}/*_test.rb") + t.verbose = true +end + # Genereate the RDoc documentation diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 0039e67c5a..315d6151e9 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -50,6 +50,7 @@ module AbstractController end def _render_template(template, options) + # layout = options[:_layout].is_a?(ActionView::Template) ? options[:_layout] : _layout_for_name(options[:_layout]) _action_view._render_template_with_layout(template, options[:_layout]) end @@ -67,10 +68,10 @@ module AbstractController def _default_layout(require_layout = false) if require_layout && !_layout - raise ArgumentError, + raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end - + begin layout = _layout_for_name(_layout) rescue NameError => e diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index e31accbbfc..37da2398ec 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -27,9 +27,11 @@ module AbstractController # # :api: plugin def render_to_body(options = {}) + options = {:_template_name => options} if options.is_a?(String) name = options[:_template_name] || action_name template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) + _render_template(template, options) end diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb index bb9d8bd063..af2da8bfe5 100644 --- a/actionpack/lib/action_controller/dispatch/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb @@ -79,7 +79,7 @@ module ActionController run_callbacks :before_dispatch Routing::Routes.call(env) rescue Exception => exception - if controller ||= (::ApplicationController rescue Base) + if !env["rack.test"] && controller ||= (::ApplicationController rescue Base) controller.call_with_exception(env, exception).to_a else raise exception diff --git a/actionpack/lib/action_controller/dispatch/middlewares.rb b/actionpack/lib/action_controller/dispatch/middlewares.rb index b5adbae746..d87c0f9706 100644 --- a/actionpack/lib/action_controller/dispatch/middlewares.rb +++ b/actionpack/lib/action_controller/dispatch/middlewares.rb @@ -9,4 +9,4 @@ use lambda { ActionController::Base.session_store }, use "ActionDispatch::ParamsParser" use "Rack::MethodOverride" -use "Rack::Head" +use "Rack::Head" \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 7c65f1cdc1..51d9c05a1a 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,7 +1,8 @@ module ActionController - autoload :AbstractBase, "action_controller/new_base/base" - autoload :HideActions, "action_controller/new_base/hide_actions" - autoload :Layouts, "action_controller/new_base/layouts" - autoload :Renderer, "action_controller/new_base/renderer" - autoload :UrlFor, "action_controller/new_base/url_for" + autoload :AbstractBase, "action_controller/new_base/base" + autoload :HideActions, "action_controller/new_base/hide_actions" + autoload :Layouts, "action_controller/new_base/layouts" + autoload :Rails2Compatibility, "action_controller/new_base/compatibility" + autoload :Renderer, "action_controller/new_base/renderer" + autoload :UrlFor, "action_controller/new_base/url_for" end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 08e7a1a0e7..75fe012aed 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -50,6 +50,8 @@ module ActionController @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new process(@_request.parameters[:action]) + @_response.prepare! + self end # :api: private diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb new file mode 100644 index 0000000000..8682493c8e --- /dev/null +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -0,0 +1,12 @@ +module ActionController + module Rails2Compatibility + + def render_to_body(options) + if options.is_a?(Hash) && options.key?(:template) + options[:template].sub!(/^\//, '') + end + super + end + + end +end \ No newline at end of file diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index 331797afcf..cf6fb5140d 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -58,11 +58,11 @@ module AbstractController end def rendering_to_body - render_to_body "naked_render.erb" + self.response_body = render_to_body :_template_name => "naked_render.erb" end def rendering_to_string - render_to_string "naked_render.erb" + self.response_body = render_to_string :_template_name => "naked_render.erb" end end @@ -136,6 +136,11 @@ module AbstractController class WithLayouts < PrefixedViews use Layouts + def self.inherited(klass) + klass._write_layout_method + super + end + private def self.layout(formats) begin @@ -147,13 +152,9 @@ module AbstractController end end end - - def _layout - self.class.layout(formats) - end - + def render_to_body(options = {}) - options[:_layout] = options[:layout] || _layout + options[:_layout] = options[:layout] || _default_layout super end end @@ -175,11 +176,6 @@ module AbstractController result = Me4.process(:index) assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_obj[:body] end - - test "it can fall back to the application layout" do - result = Me5.process(:index) - assert_equal "Application Enter : Hello from me5/index.erb : Exit", result.response_obj[:body] - end end # respond_to_action?(action_name) diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb index 3d4570bfef..078e0037a8 100644 --- a/actionpack/test/abstract_controller/layouts_test.rb +++ b/actionpack/test/abstract_controller/layouts_test.rb @@ -8,7 +8,7 @@ module AbstractControllerTests use AbstractController::Renderer use AbstractController::Layouts - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/hello.erb" => "With String <%= yield %>", "layouts/hello_override.erb" => "With Override <%= yield %>", "layouts/abstract_controller_tests/layouts/with_string_implied_child.erb" => diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 023bf0eeaa..a97e8ac5c1 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -755,6 +755,7 @@ class RenderTest < ActionController::TestCase @request.host = "www.nextangle.com" end + # :ported: def test_simple_show get :hello_world assert_response 200 @@ -763,11 +764,13 @@ class RenderTest < ActionController::TestCase assert_equal "Hello world!", @response.body end + # :ported: def test_renders_default_template_for_missing_action get :'hyphen-ated' assert_template 'test/hyphen-ated' end + # :ported: def test_render get :render_hello_world assert_template "test/hello_world" diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index 26f6ec2d0c..e43e329a9e 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -1,35 +1,104 @@ module ActionView #:nodoc: - class FixtureTemplate < Template - class FixturePath < Template::Path - def initialize(hash = {}) - @hash = {} - - hash.each do |k, v| - @hash[k.sub(/\.\w+$/, '')] = FixtureTemplate.new(v, k.split("/").last, self) +class Template + class FixturePath < Path + def initialize(hash = {}, options = {}) + super(options) + @hash = hash + end + + def find_templates(name, details, prefix, partial) + if regexp = details_to_regexp(name, details, prefix, partial) + cached(regexp) do + templates = [] + @hash.select { |k,v| k =~ regexp }.each do |path, source| + templates << Template.new(source, path, *path_to_details(path)) + end + templates end - - super("fixtures://root") - end - - def find_template(path) - @hash[path] end end - def initialize(body, *args) - @body = body - super(*args) + private + + def formats_regexp + @formats_regexp ||= begin + formats = Mime::SET.map { |m| m.symbol } + '(?:' + formats.map { |l| "\\.#{Regexp.escape(l.to_s)}" }.join('|') + ')?' + end end - def source - @body + def handler_regexp + e = TemplateHandlers.extensions.map{|h| "\\.#{Regexp.escape(h.to_s)}"}.join("|") + "(?:#{e})?" end - private - - def find_full_path(path, load_paths) - return '/', path + def details_to_regexp(name, details, prefix, partial) + path = "" + path << "#{prefix}/" unless prefix.empty? + path << (partial ? "_#{name}" : name) + + extensions = "" + [:locales, :formats].each do |k| + extensions << if exts = details[k] + '(?:' + exts.map {|e| "\\.#{Regexp.escape(e.to_s)}"}.join('|') + ')?' + else + k == :formats ? formats_regexp : '' + end + end + + %r'#{Regexp.escape(path)}#{extensions}#{handler_regexp}' + end + + # TODO: fix me + # :api: plugin + def path_to_details(path) + # [:erb, :format => :html, :locale => :en, :partial => true/false] + if m = path.match(%r'(_)?[\w-]+(\.[\w-]+)*\.(\w+)$') + partial = m[1] == '_' + details = (m[2]||"").split('.').reject { |e| e.empty? } + handler = Template.handler_class_for_extension(m[3]) + + format = Mime[details.last] && details.pop.to_sym + locale = details.last && details.pop.to_sym + + return handler, :format => format, :locale => locale, :partial => partial + end end - end + + + # class FixtureTemplate < Template + # class FixturePath < Template::Path + # def initialize(hash = {}) + # @hash = {} + # + # hash.each do |k, v| + # @hash[k.sub(/\.\w+$/, '')] = FixtureTemplate.new(v, k.split("/").last, self) + # end + # + # super("fixtures://root") + # end + # + # def find_template(path) + # @hash[path] + # end + # end + # + # def initialize(body, *args) + # @body = body + # super(*args) + # end + # + # def source + # @body + # end + # + # private + # + # def find_full_path(path, load_paths) + # return '/', path + # end + # + # end +end end \ No newline at end of file diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb index 4f46cb6492..b0e87b4f5b 100644 --- a/actionpack/test/new_base/base_test.rb +++ b/actionpack/test/new_base/base_test.rb @@ -34,11 +34,11 @@ module HappyPath end test "sets the content type" do - assert_content_type Mime::HTML + assert_content_type "text/html; charset=utf-8" end test "sets the content length" do - assert_header "Content-Length", 7 + assert_header "Content-Length", "7" end end @@ -52,7 +52,7 @@ module HappyPath end test "setting the body manually sets the content length" do - assert_header "Content-Length", 7 + assert_header "Content-Length", "7" end end @@ -65,7 +65,7 @@ module HappyPath end test "updating the response body updates the content length" do - assert_header "Content-Length", 8 + assert_header "Content-Length", "8" end end end diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb index 2bfb374a31..37b83fb681 100644 --- a/actionpack/test/new_base/render_action_test.rb +++ b/actionpack/test/new_base/render_action_test.rb @@ -5,7 +5,7 @@ module RenderAction # This has no layout and it works class BasicController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "render_action/basic/hello_world.html.erb" => "Hello world!" )] @@ -129,7 +129,7 @@ module RenderActionWithApplicationLayout class BasicController < ::ApplicationController # Set the view path to an application view structure with layouts - self.view_paths = self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( "render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!", "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai" @@ -204,7 +204,7 @@ end module RenderActionWithControllerLayout class BasicController < ActionController::Base2 - self.view_paths = self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( "render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!", "layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" )] @@ -267,7 +267,7 @@ end module RenderActionWithBothLayouts class BasicController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new({ + self.view_paths = [ActionView::Template::FixturePath.new({ "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!", "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/new_base/render_implicit_action_test.rb index 798505b539..0a10c070c3 100644 --- a/actionpack/test/new_base/render_implicit_action_test.rb +++ b/actionpack/test/new_base/render_implicit_action_test.rb @@ -1,16 +1,28 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") -module HappyPath - - class RenderImplicitActionController < ActionController::Base2 - # No actions yet, they are implicit +module RenderImplicitAction + class SimpleController < ::ApplicationController + self.view_paths = [ActionView::Template::FixturePath.new( + "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", + "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated" + )] + + def hello_world() end end - class TestRendersActionImplicitly < SimpleRouteCase - - test "renders action implicitly" do - assert true - end + class TestImplicitRender < SimpleRouteCase + describe "render a simple action with new explicit call to render" + + get "/render_implicit_action/simple/hello_world" + assert_body "Hello world!" + assert_status 200 + end + class TestImplicitWithSpecialCharactersRender < SimpleRouteCase + describe "render an action with a missing method and has special characters" + + get "/render_implicit_action/simple/hyphen-ated" + assert_body "Hello hyphen-ated!" + assert_status 200 end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb index facf67ea85..07ea2f191e 100644 --- a/actionpack/test/new_base/render_layout_test.rb +++ b/actionpack/test/new_base/render_layout_test.rb @@ -3,7 +3,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module ControllerLayouts class ImplicitController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", "basic.html.erb" => "Hello world!" )] @@ -23,7 +23,7 @@ module ControllerLayouts class ImplicitNameController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI", "basic.html.erb" => "Hello world!" )] diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index c6c0269b40..fd0519159e 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -4,7 +4,7 @@ module HappyPath class RenderTemplateWithoutLayoutController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica" )] @@ -13,10 +13,6 @@ module HappyPath render :template => "test/basic" end - def render_hello_world_with_forward_slash - render :template => "/test/basic" - end - def render_template_in_top_directory render :template => 'shared' end @@ -34,14 +30,6 @@ module HappyPath assert_status 200 end - class TestTemplateRenderWithForwardSlash < SimpleRouteCase - describe "rendering a normal template with full path starting with a leading slash" - - get "/happy_path/render_template_without_layout/render_hello_world_with_forward_slash" - assert_body "Hello from basic.html.erb" - assert_status 200 - end - class TestTemplateRenderInTopDirectory < SimpleRouteCase describe "rendering a template not in a subdirectory" @@ -60,7 +48,7 @@ module HappyPath class RenderTemplateWithLayoutController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica", "layouts/application.html.erb" => "<%= yield %>, I'm here!", @@ -127,7 +115,26 @@ module HappyPath assert_body "Hello from basic.html.erb, I wish thee well." assert_status 200 end - - +end + +module Compatibility + class RenderTemplateWithoutLayoutController < ActionController::CompatibleBase2 + self.view_paths = [ActionView::Template::FixturePath.new( + "test/basic.html.erb" => "Hello from basic.html.erb", + "shared.html.erb" => "Elastica" + )] + + def render_hello_world_with_forward_slash + render :template => "/test/basic" + end + end + + class TestTemplateRenderWithForwardSlash < SimpleRouteCase + describe "rendering a normal template with full path starting with a leading slash" + + get "/compatibility/render_template_without_layout/render_hello_world_with_forward_slash" + assert_body "Hello from basic.html.erb" + assert_status 200 + end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index a20ca5fb8c..3c11524d1d 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -6,7 +6,7 @@ end module HappyPath class RenderTextWithoutLayoutsController < ActionController::Base2 - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new] + self.view_paths = [ActionView::Template::FixturePath.new] def render_hello_world render :text => "hello david" @@ -14,7 +14,7 @@ module HappyPath end class RenderTextWithLayoutsController < ::ApplicationController - self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "<%= yield %>, I'm here!", "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well." )] diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index d29449ddc1..091fb77f9f 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -24,6 +24,14 @@ require 'pp' # require 'pp' early to prevent hidden_methods from not picking up require 'rubygems' require 'rack/test' +module Rails + def self.env + x = Object.new + def x.test?() true end + x + end +end + module ActionController class Base2 < AbstractBase use AbstractController::Callbacks @@ -54,6 +62,10 @@ module ActionController CORE_METHODS = self.public_instance_methods end + + class CompatibleBase2 < Base2 + use ActionController::Rails2Compatibility + end end # Temporary base class @@ -91,7 +103,7 @@ class Rack::TestCase < ActiveSupport::TestCase end def assert_body(body) - assert_equal [body], last_response.body + assert_equal body, last_response.body end def self.assert_body(body) -- cgit v1.2.3 From 059afb3a3a48106f430a8478072e34a59b4b72d6 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 11:26:01 -0700 Subject: Removed a stray method_missing in the new callbacks system --- activesupport/lib/active_support/new_callbacks.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index 8a91e1c674..2ae7b006c7 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -304,15 +304,6 @@ module ActiveSupport end end - # This method_missing is supplied to catch callbacks with keys and create - # the appropriate callback for future use. - def method_missing(meth, *args, &blk) - if meth.to_s =~ /_run__([\w:]+)__(\w+)__(\w+)__callbacks/ - return self.class._create_and_run_keyed_callback($1, $2.to_sym, $3.to_sym, self, &blk) - end - super - end - # An Array with a compile method class CallbackChain < Array def initialize(symbol) -- cgit v1.2.3 From b692fceb6aa08791074dd9f4fc3b962094c0b056 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 11:28:12 -0700 Subject: Renamed ActionController::AbstractBase to ActionController::Http --- actionpack/lib/action_controller/new_base.rb | 2 +- actionpack/lib/action_controller/new_base/base.rb | 2 +- .../test/new_base/render_implicit_action_test.rb | 30 +++++++++++----------- actionpack/test/new_base/test_helper.rb | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 51d9c05a1a..bfd8120e10 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,6 +1,6 @@ module ActionController - autoload :AbstractBase, "action_controller/new_base/base" autoload :HideActions, "action_controller/new_base/hide_actions" + autoload :Http, "action_controller/new_base/base" autoload :Layouts, "action_controller/new_base/layouts" autoload :Rails2Compatibility, "action_controller/new_base/compatibility" autoload :Renderer, "action_controller/new_base/renderer" diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 75fe012aed..6711cd932a 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -1,5 +1,5 @@ module ActionController - class AbstractBase < AbstractController::Base + class Http < AbstractController::Base # :api: public attr_internal :request, :response, :params diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/new_base/render_implicit_action_test.rb index 0a10c070c3..3afa444e3e 100644 --- a/actionpack/test/new_base/render_implicit_action_test.rb +++ b/actionpack/test/new_base/render_implicit_action_test.rb @@ -10,19 +10,19 @@ module RenderImplicitAction def hello_world() end end - class TestImplicitRender < SimpleRouteCase - describe "render a simple action with new explicit call to render" - - get "/render_implicit_action/simple/hello_world" - assert_body "Hello world!" - assert_status 200 - end - - class TestImplicitWithSpecialCharactersRender < SimpleRouteCase - describe "render an action with a missing method and has special characters" - - get "/render_implicit_action/simple/hyphen-ated" - assert_body "Hello hyphen-ated!" - assert_status 200 - end + # class TestImplicitRender < SimpleRouteCase + # describe "render a simple action with new explicit call to render" + # + # get "/render_implicit_action/simple/hello_world" + # assert_body "Hello world!" + # assert_status 200 + # end + # + # class TestImplicitWithSpecialCharactersRender < SimpleRouteCase + # describe "render an action with a missing method and has special characters" + # + # get "/render_implicit_action/simple/hyphen-ated" + # assert_body "Hello hyphen-ated!" + # assert_status 200 + # end end \ No newline at end of file diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 091fb77f9f..cc79d6faf7 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -33,7 +33,7 @@ module Rails end module ActionController - class Base2 < AbstractBase + class Base2 < Http use AbstractController::Callbacks use AbstractController::Helpers use AbstractController::Logger -- cgit v1.2.3 From 1b459916039259383808625d1758a8bc4a4516d9 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 11:42:27 -0700 Subject: Renamed the new_base tests --- actionpack/test/controller/render_test.rb | 2 + actionpack/test/new_base/base_test.rb | 43 +++++++------- actionpack/test/new_base/render_template_test.rb | 76 ++++++++++++------------ actionpack/test/new_base/render_text_test.rb | 71 ++++++++++++---------- 4 files changed, 98 insertions(+), 94 deletions(-) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index a97e8ac5c1..648e179a15 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -106,6 +106,7 @@ class TestController < ActionController::Base render :template => '/shared' end + # :ported: def render_hello_world_from_variable @person = "david" render :text => "hello #{@person}" @@ -123,6 +124,7 @@ class TestController < ActionController::Base render :action => :hello_world end + # :ported: def render_text_hello_world render :text => "hello world" end diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb index b0e87b4f5b..95fdfd6b56 100644 --- a/actionpack/test/new_base/base_test.rb +++ b/actionpack/test/new_base/base_test.rb @@ -1,8 +1,8 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") # Tests the controller dispatching happy path -module HappyPath - class SimpleDispatchController < ActionController::Base2 +module Dispatching + class SimpleController < ActionController::Base2 def index render :text => "success" end @@ -23,7 +23,7 @@ module HappyPath class TestSimpleDispatch < SimpleRouteCase - get "/happy_path/simple_dispatch/index" + get "/dispatching/simple/index" test "sets the body" do assert_body "success" @@ -45,7 +45,7 @@ module HappyPath # :api: plugin class TestDirectResponseMod < SimpleRouteCase - get "/happy_path/simple_dispatch/modify_response_body" + get "/dispatching/simple/modify_response_body" test "sets the body" do assert_body "success" @@ -58,7 +58,7 @@ module HappyPath # :api: plugin class TestDirectResponseModTwice < SimpleRouteCase - get "/happy_path/simple_dispatch/modify_response_body_twice" + get "/dispatching/simple/modify_response_body_twice" test "self.response_body= returns the body being set" do assert_body "success!" @@ -68,23 +68,22 @@ module HappyPath assert_header "Content-Length", "8" end end -end - - -class EmptyController < ActionController::Base2 ; end -module Submodule - class ContainedEmptyController < ActionController::Base2 ; end -end + + class EmptyController < ActionController::Base2 ; end + module Submodule + class ContainedEmptyController < ActionController::Base2 ; end + end -class ControllerClassTests < Test::Unit::TestCase - def test_controller_path - assert_equal 'empty', EmptyController.controller_path - assert_equal EmptyController.controller_path, EmptyController.new.controller_path - assert_equal 'submodule/contained_empty', Submodule::ContainedEmptyController.controller_path - assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path + class ControllerClassTests < Test::Unit::TestCase + def test_controller_path + assert_equal 'dispatching/empty', EmptyController.controller_path + assert_equal EmptyController.controller_path, EmptyController.new.controller_path + assert_equal 'dispatching/submodule/contained_empty', Submodule::ContainedEmptyController.controller_path + assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path + end + def test_controller_name + assert_equal 'empty', EmptyController.controller_name + assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name + end end - def test_controller_name - assert_equal 'empty', EmptyController.controller_name - assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name - end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index fd0519159e..bc52eb019f 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -1,31 +1,30 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") -module HappyPath - - class RenderTemplateWithoutLayoutController < ActionController::Base2 +module RenderTemplate + class WithoutLayoutController < ActionController::Base2 self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica" )] - def render_hello_world + def index render :template => "test/basic" end - def render_template_in_top_directory + def in_top_directory render :template => 'shared' end - def render_template_in_top_directory_with_slash + def in_top_directory_with_slash render :template => '/shared' end end - class TestTemplateRenderWithoutLayout < SimpleRouteCase + class TestWithoutLayout < SimpleRouteCase describe "rendering a normal template with full path without layout" - get "/happy_path/render_template_without_layout/render_hello_world" + get "/render_template/without_layout" assert_body "Hello from basic.html.erb" assert_status 200 end @@ -33,7 +32,7 @@ module HappyPath class TestTemplateRenderInTopDirectory < SimpleRouteCase describe "rendering a template not in a subdirectory" - get "/happy_path/render_template_without_layout/render_template_in_top_directory" + get "/render_template/without_layout/in_top_directory" assert_body "Elastica" assert_status 200 end @@ -41,12 +40,12 @@ module HappyPath class TestTemplateRenderInTopDirectoryWithSlash < SimpleRouteCase describe "rendering a template not in a subdirectory with a leading slash" - get "/happy_path/render_template_without_layout/render_template_in_top_directory_with_slash" + get "/render_template/without_layout/in_top_directory_with_slash" assert_body "Elastica" assert_status 200 end - class RenderTemplateWithLayoutController < ::ApplicationController + class WithLayoutController < ::ApplicationController self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", @@ -55,23 +54,23 @@ module HappyPath "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well." )] - def render_hello_world + def index render :template => "test/basic" end - def render_hello_world_with_layout + def with_layout render :template => "test/basic", :layout => true end - def render_hello_world_with_layout_false + def with_layout_false render :template => "test/basic", :layout => false end - def render_hello_world_with_layout_nil + def with_layout_nil render :template => "test/basic", :layout => nil end - def render_hello_world_with_custom_layout + def with_custom_layout render :template => "test/basic", :layout => "greetings" end end @@ -79,7 +78,7 @@ module HappyPath class TestTemplateRenderWithLayout < SimpleRouteCase describe "rendering a normal template with full path with layout" - get "/happy_path/render_template_with_layout/render_hello_world" + get "/render_template/with_layout" assert_body "Hello from basic.html.erb, I'm here!" assert_status 200 end @@ -87,7 +86,7 @@ module HappyPath class TestTemplateRenderWithLayoutTrue < SimpleRouteCase describe "rendering a normal template with full path with layout => :true" - get "/happy_path/render_template_with_layout/render_hello_world_with_layout" + get "/render_template/with_layout/with_layout" assert_body "Hello from basic.html.erb, I'm here!" assert_status 200 end @@ -95,7 +94,7 @@ module HappyPath class TestTemplateRenderWithLayoutFalse < SimpleRouteCase describe "rendering a normal template with full path with layout => :false" - get "/happy_path/render_template_with_layout/render_hello_world_with_layout_false" + get "/render_template/with_layout/with_layout_false" assert_body "Hello from basic.html.erb" assert_status 200 end @@ -103,7 +102,7 @@ module HappyPath class TestTemplateRenderWithLayoutNil < SimpleRouteCase describe "rendering a normal template with full path with layout => :nil" - get "/happy_path/render_template_with_layout/render_hello_world_with_layout_nil" + get "/render_template/with_layout/with_layout_nil" assert_body "Hello from basic.html.erb" assert_status 200 end @@ -111,30 +110,29 @@ module HappyPath class TestTemplateRenderWithCustomLayout < SimpleRouteCase describe "rendering a normal template with full path with layout => 'greetings'" - get "/happy_path/render_template_with_layout/render_hello_world_with_custom_layout" + get "/render_template/with_layout/with_custom_layout" assert_body "Hello from basic.html.erb, I wish thee well." assert_status 200 end + + module Compatibility + class WithoutLayoutController < ActionController::CompatibleBase2 + self.view_paths = [ActionView::Template::FixturePath.new( + "test/basic.html.erb" => "Hello from basic.html.erb", + "shared.html.erb" => "Elastica" + )] -end + def with_forward_slash + render :template => "/test/basic" + end + end -module Compatibility - class RenderTemplateWithoutLayoutController < ActionController::CompatibleBase2 - self.view_paths = [ActionView::Template::FixturePath.new( - "test/basic.html.erb" => "Hello from basic.html.erb", - "shared.html.erb" => "Elastica" - )] - - def render_hello_world_with_forward_slash - render :template => "/test/basic" + class TestTemplateRenderWithForwardSlash < SimpleRouteCase + describe "rendering a normal template with full path starting with a leading slash" + + get "/render_template/compatibility/without_layout/with_forward_slash" + assert_body "Hello from basic.html.erb" + assert_status 200 end end - - class TestTemplateRenderWithForwardSlash < SimpleRouteCase - describe "rendering a normal template with full path starting with a leading slash" - - get "/compatibility/render_template_without_layout/render_hello_world_with_forward_slash" - assert_body "Hello from basic.html.erb" - assert_status 200 - end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index 3c11524d1d..d97c2ca0a6 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -3,75 +3,80 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") class ApplicationController < ActionController::Base2 end -module HappyPath - - class RenderTextWithoutLayoutsController < ActionController::Base2 +module RenderText + class SimpleController < ActionController::Base2 self.view_paths = [ActionView::Template::FixturePath.new] - def render_hello_world + def index render :text => "hello david" end end - class RenderTextWithLayoutsController < ::ApplicationController + class TestSimpleTextRenderWithNoLayout < SimpleRouteCase + describe "Rendering text from a action with default options renders the text with the layout" + + get "/render_text/simple" + assert_body "hello david" + assert_status 200 + end + + class WithLayoutController < ::ApplicationController self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "<%= yield %>, I'm here!", - "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well." + "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well.", + "layouts/ivar.html.erb" => "<%= yield %>, <%= @ivar %>" )] - def render_hello_world + def index render :text => "hello david" end - def render_custom_code + def custom_code render :text => "hello world", :status => 404 end - def render_with_custom_code_as_string + def with_custom_code_as_string render :text => "hello world", :status => "404 Not Found" end - def render_text_with_nil + def with_nil render :text => nil end - def render_text_with_nil_and_status + def with_nil_and_status render :text => nil, :status => 403 end - def render_text_with_false + def with_false render :text => false end - def render_text_with_layout + def with_layout_true render :text => "hello world", :layout => true end - def render_text_with_layout_false + def with_layout_false render :text => "hello world", :layout => false end - def render_text_with_layout_nil + def with_layout_nil render :text => "hello world", :layout => nil end - def render_text_with_custom_layout + def with_custom_layout render :text => "hello world", :layout => "greetings" end - end - - class TestSimpleTextRenderWithNoLayout < SimpleRouteCase - describe "Rendering text from a action with default options renders the text with the layout" - get "/happy_path/render_text_without_layouts/render_hello_world" - assert_body "hello david" - assert_status 200 + def with_ivar_in_layout + @ivar = "hello world" + render :text => "hello world", :layout => "ivar" + end end - + class TestSimpleTextRenderWithLayout < SimpleRouteCase describe "Rendering text from a action with default options renders the text without the layout" - get "/happy_path/render_text_with_layouts/render_hello_world" + get "/render_text/with_layout" assert_body "hello david" assert_status 200 end @@ -79,7 +84,7 @@ module HappyPath class TestTextRenderWithStatus < SimpleRouteCase describe "Rendering text, while also providing a custom status code" - get "/happy_path/render_text_with_layouts/render_custom_code" + get "/render_text/with_layout/custom_code" assert_body "hello world" assert_status 404 end @@ -87,7 +92,7 @@ module HappyPath class TestTextRenderWithNil < SimpleRouteCase describe "Rendering text with nil returns a single space character" - get "/happy_path/render_text_with_layouts/render_text_with_nil" + get "/render_text/with_layout/with_nil" assert_body " " assert_status 200 end @@ -95,7 +100,7 @@ module HappyPath class TestTextRenderWithNilAndStatus < SimpleRouteCase describe "Rendering text with nil and custom status code returns a single space character with the status" - get "/happy_path/render_text_with_layouts/render_text_with_nil_and_status" + get "/render_text/with_layout/with_nil_and_status" assert_body " " assert_status 403 end @@ -103,7 +108,7 @@ module HappyPath class TestTextRenderWithFalse < SimpleRouteCase describe "Rendering text with false returns the string 'false'" - get "/happy_path/render_text_with_layouts/render_text_with_false" + get "/render_text/with_layout/with_false" assert_body "false" assert_status 200 end @@ -111,7 +116,7 @@ module HappyPath class TestTextRenderWithLayoutTrue < SimpleRouteCase describe "Rendering text with :layout => true" - get "/happy_path/render_text_with_layouts/render_text_with_layout" + get "/render_text/with_layout/with_layout_true" assert_body "hello world, I'm here!" assert_status 200 end @@ -119,7 +124,7 @@ module HappyPath class TestTextRenderWithCustomLayout < SimpleRouteCase describe "Rendering text with :layout => 'greetings'" - get "/happy_path/render_text_with_layouts/render_text_with_custom_layout" + get "/render_text/with_layout/with_custom_layout" assert_body "hello world, I wish thee well." assert_status 200 end @@ -127,7 +132,7 @@ module HappyPath class TestTextRenderWithLayoutFalse < SimpleRouteCase describe "Rendering text with :layout => false" - get "/happy_path/render_text_with_layouts/render_text_with_layout_false" + get "/render_text/with_layout/with_layout_false" assert_body "hello world" assert_status 200 end @@ -135,7 +140,7 @@ module HappyPath class TestTextRenderWithLayoutNil < SimpleRouteCase describe "Rendering text with :layout => nil" - get "/happy_path/render_text_with_layouts/render_text_with_layout_nil" + get "/render_text/with_layout/with_layout_nil" assert_body "hello world" assert_status 200 end -- cgit v1.2.3 From 4f68311685831b940936130203c240fa23525c84 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 12:19:17 -0700 Subject: Finished implementing render :text in Base2 --- .../lib/action_controller/abstract/renderer.rb | 13 +++++++++++++ actionpack/lib/action_controller/new_base/base.rb | 8 ++------ .../lib/action_controller/new_base/renderer.rb | 2 +- actionpack/test/controller/render_test.rb | 17 +++++++++++++++++ actionpack/test/new_base/base_test.rb | 2 +- actionpack/test/new_base/render_test.rb | 20 ++++++++++++++++++++ 6 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 actionpack/test/new_base/render_test.rb diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index 37da2398ec..c1f420f7b4 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -1,6 +1,15 @@ require "action_controller/abstract/logger" module AbstractController + class AbstractControllerError < StandardError; end + class DoubleRenderError < AbstractControllerError + DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"." + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + module Renderer depends_on AbstractController::Logger @@ -17,6 +26,10 @@ module AbstractController end def render(options = {}) + unless response_body.nil? + raise AbstractController::DoubleRenderError, "OMG" + end + self.response_body = render_to_body(options) end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 6711cd932a..9f7a148b3c 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -40,23 +40,19 @@ module ActionController controller.call(env).to_rack end - # :api: plugin - def response_body=(body) - @_response.body = body - end - # :api: private def call(env) @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new process(@_request.parameters[:action]) + @_response.body = response_body @_response.prepare! self end # :api: private def to_rack - response.to_a + @_response.to_a end end end diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index ed34c46aed..9a965c18e8 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -17,7 +17,7 @@ module ActionController _process_options(options) - self.response_body = render_to_body(options) + super(options) end def render_to_body(options) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 648e179a15..9149212a2d 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -129,6 +129,7 @@ class TestController < ActionController::Base render :text => "hello world" end + # :ported: def render_text_hello_world_with_layout @variable_for_layout = ", I'm here!" render :text => "hello world", :layout => true @@ -220,6 +221,7 @@ class TestController < ActionController::Base render :json => {:hello => render_to_string(:partial => 'partial')} end + # :ported: def render_custom_code render :text => "hello world", :status => 404 end @@ -230,14 +232,17 @@ class TestController < ActionController::Base end end + # :ported: def render_text_with_nil render :text => nil end + # :ported: def render_text_with_false render :text => false end + # :ported: def render_nothing_with_appendix render :text => "appended" end @@ -272,6 +277,7 @@ class TestController < ActionController::Base # let's just rely on the template end + # :ported: def blank_response render :text => ' ' end @@ -405,6 +411,7 @@ class TestController < ActionController::Base render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' } end + # :ported: def double_render render :text => "hello" render :text => "world" @@ -508,6 +515,7 @@ class TestController < ActionController::Base # Action template sets variable that's picked up by layout end + # :addressed: def render_text_with_assigns @hello = "world" render :text => "foo" @@ -807,6 +815,7 @@ class RenderTest < ActionController::TestCase assert_equal "Elastica", @response.body end + # :ported: def test_render_from_variable get :render_hello_world_from_variable assert_equal "hello david", @response.body @@ -828,16 +837,19 @@ class RenderTest < ActionController::TestCase assert_template "test/hello_world" end + # :ported: def test_render_text get :render_text_hello_world assert_equal "hello world", @response.body end + # :ported: def test_do_with_render_text_and_layout get :render_text_hello_world_with_layout assert_equal "hello world, I'm here!", @response.body end + # :ported: def test_do_with_render_action_and_layout_false get :hello_world_with_layout_false assert_equal 'Hello world!', @response.body @@ -932,17 +944,20 @@ class RenderTest < ActionController::TestCase assert_equal %(Element.replace("foo", "partial html");), @response.body end + # :ported: def test_render_text_with_nil get :render_text_with_nil assert_response 200 assert_equal ' ', @response.body end + # :ported: def test_render_text_with_false get :render_text_with_false assert_equal 'false', @response.body end + # :ported: def test_render_nothing_with_appendix get :render_nothing_with_appendix assert_response 200 @@ -1209,6 +1224,7 @@ class RenderTest < ActionController::TestCase assert_equal "Hello world!", @response.body end + # :ported: def test_double_render assert_raise(ActionController::DoubleRenderError) { get :double_render } end @@ -1237,6 +1253,7 @@ class RenderTest < ActionController::TestCase assert_equal "Talking to the layout\nAction was here!", @response.body end + # :addressed: def test_render_text_with_assigns get :render_text_with_assigns assert_equal "world", assigns["hello"] diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb index 95fdfd6b56..27d1a7f026 100644 --- a/actionpack/test/new_base/base_test.rb +++ b/actionpack/test/new_base/base_test.rb @@ -84,6 +84,6 @@ module Dispatching def test_controller_name assert_equal 'empty', EmptyController.controller_name assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name - end + end end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb new file mode 100644 index 0000000000..9ad79124b8 --- /dev/null +++ b/actionpack/test/new_base/render_test.rb @@ -0,0 +1,20 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") + +module Render + class DoubleRenderController < ActionController::Base2 + def index + render :text => "hello" + render :text => "world" + end + end + + class TestBasic < SimpleRouteCase + describe "Rendering more than once" + + test "raises an exception" do + assert_raises(AbstractController::DoubleRenderError) do + get "/render/double_render" + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From 0c3d9bc4c2b329cb754bfed1e465f99d058e1193 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 16:33:24 -0700 Subject: Ported over render :template tests --- actionpack/lib/action_controller/abstract/layouts.rb | 3 +-- actionpack/lib/action_controller/abstract/renderer.rb | 1 - actionpack/lib/action_controller/new_base/renderer.rb | 4 ---- actionpack/test/controller/render_test.rb | 19 +++++++++++++++++++ actionpack/test/new_base/render_template_test.rb | 15 ++++++++++++++- actionpack/test/new_base/test_helper.rb | 5 +++++ 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 315d6151e9..f56b9dd914 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -50,8 +50,7 @@ module AbstractController end def _render_template(template, options) - # layout = options[:_layout].is_a?(ActionView::Template) ? options[:_layout] : _layout_for_name(options[:_layout]) - _action_view._render_template_with_layout(template, options[:_layout]) + _action_view._render_template_with_layout(template, options[:_layout], options) end private diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index c1f420f7b4..e9a7ab4004 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -40,7 +40,6 @@ module AbstractController # # :api: plugin def render_to_body(options = {}) - options = {:_template_name => options} if options.is_a?(String) name = options[:_template_name] || action_name template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 9a965c18e8..df07edbd90 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -21,10 +21,6 @@ module ActionController end def render_to_body(options) - unless options.is_a?(Hash) - options = {:action => options} - end - if options.key?(:text) options[:_template] = ActionView::TextTemplate.new(_text(options)) template = nil diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 9149212a2d..d4a18a673c 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -80,6 +80,7 @@ class TestController < ActionController::Base fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ]) end + # :ported: def render_hello_world render :template => "test/hello_world" end @@ -94,14 +95,17 @@ class TestController < ActionController::Base render :template => "test/hello_world" end + # :ported: compatibility def render_hello_world_with_forward_slash render :template => "/test/hello_world" end + # :ported: def render_template_in_top_directory render :template => 'shared' end + # :deprecated: def render_template_in_top_directory_with_slash render :template => '/shared' end @@ -251,6 +255,10 @@ class TestController < ActionController::Base render :js => "alert('hello')" end + # This test is testing 3 things: + # render :file in AV :ported: + # render :template in AC :ported: + # setting content type def render_xml_hello @name = "David" render :template => "test/hello" @@ -399,6 +407,7 @@ class TestController < ActionController::Base render :layout => true, :inline => "Hello: <%= params[:name] %>" end + # :ported: def render_with_explicit_template render :template => "test/hello_world" end @@ -407,6 +416,7 @@ class TestController < ActionController::Base render "test/hello_world" end + # :ported: def render_with_explicit_template_with_locals render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' } end @@ -443,10 +453,15 @@ class TestController < ActionController::Base render :action => "potential_conflicts" end + # :deprecated: + # Tests being able to pick a .builder template over a .erb + # For instance, being able to have hello.xml.builder and hello.xml.erb + # and select one via "hello.builder" or "hello.erb" def hello_world_from_rxml_using_action render :action => "hello_world_from_rxml.builder" end + # :deprecated: def hello_world_from_rxml_using_template render :template => "test/hello_world_from_rxml.builder" end @@ -798,17 +813,20 @@ class RenderTest < ActionController::TestCase end end + # :ported: compatibility def test_render_with_forward_slash get :render_hello_world_with_forward_slash assert_template "test/hello_world" end + # :ported: def test_render_in_top_directory get :render_template_in_top_directory assert_template "shared" assert_equal "Elastica", @response.body end + # :ported: def test_render_in_top_directory_with_slash get :render_template_in_top_directory_with_slash assert_template "shared" @@ -1259,6 +1277,7 @@ class RenderTest < ActionController::TestCase assert_equal "world", assigns["hello"] end + # :ported: def test_template_with_locals get :render_with_explicit_template_with_locals assert_equal "The secret is area51\n", @response.body diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index bc52eb019f..63769df082 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -5,7 +5,8 @@ module RenderTemplate self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", - "shared.html.erb" => "Elastica" + "shared.html.erb" => "Elastica", + "locals.html.erb" => "The secret is <%= secret %>" )] def index @@ -19,6 +20,10 @@ module RenderTemplate def in_top_directory_with_slash render :template => '/shared' end + + def with_locals + render :template => "locals", :locals => { :secret => 'area51' } + end end class TestWithoutLayout < SimpleRouteCase @@ -44,6 +49,14 @@ module RenderTemplate assert_body "Elastica" assert_status 200 end + + class TestTemplateRenderWithLocals < SimpleRouteCase + describe "rendering a template with local variables" + + get "/render_template/without_layout/with_locals" + assert_body "The secret is area51" + assert_status 200 + end class WithLayoutController < ::ApplicationController diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index cc79d6faf7..b40cbb163f 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -58,6 +58,11 @@ module ActionController end end + def render_to_body(options = {}) + options = {:template => options} if options.is_a?(String) + super + end + # append_view_path File.join(File.dirname(__FILE__), '..', 'fixtures') CORE_METHODS = self.public_instance_methods -- cgit v1.2.3 From 49834e088bf8d02a4f75793a42868f2aea8749a4 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 17:32:39 -0700 Subject: Support implicit render and blank render --- actionpack/lib/action_controller/abstract/base.rb | 13 ++++++++- .../lib/action_controller/abstract/renderer.rb | 4 +-- .../lib/action_controller/new_base/renderer.rb | 9 +----- .../test/new_base/render_implicit_action_test.rb | 32 +++++++++++----------- actionpack/test/new_base/render_test.rb | 18 ++++++++++++ actionpack/test/new_base/test_helper.rb | 20 ++++++++++++++ 6 files changed, 69 insertions(+), 27 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index ade7719cc0..a87a490a2d 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -29,10 +29,21 @@ module AbstractController private + # It is possible for respond_to?(action_name) to be false and + # respond_to?(:action_missing) to be false if respond_to_action? + # is overridden in a subclass. For instance, ActionController::Base + # overrides it to include the case where a template matching the + # action_name is found. def process_action - respond_to?(action_name) ? send(action_name) : send(:action_missing, action_name) + if respond_to?(action_name) then send(action_name) + elsif respond_to?(:action_missing, true) then send(:action_missing, action_name) + end end + # Override this to change the conditions that will raise an + # ActionNotFound error. If you accept a difference case, + # you must handle it by also overriding process_action and + # handling the case. def respond_to_action?(action_name) respond_to?(action_name) || respond_to?(:action_missing, true) end diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index e9a7ab4004..716b213c75 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -42,9 +42,9 @@ module AbstractController def render_to_body(options = {}) name = options[:_template_name] || action_name - template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) + options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) - _render_template(template, options) + _render_template(options[:_template], options) end # Raw rendering of a template to a string. diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index df07edbd90..096a63e406 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -7,14 +7,7 @@ module ActionController super end - def render(action, options = {}) - # TODO: Move this into #render_to_body - if action.is_a?(Hash) - options, action = action, nil - else - options.merge! :action => action - end - + def render(options = {}) _process_options(options) super(options) diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/new_base/render_implicit_action_test.rb index 3afa444e3e..58f5cec181 100644 --- a/actionpack/test/new_base/render_implicit_action_test.rb +++ b/actionpack/test/new_base/render_implicit_action_test.rb @@ -4,25 +4,25 @@ module RenderImplicitAction class SimpleController < ::ApplicationController self.view_paths = [ActionView::Template::FixturePath.new( "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", - "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated" + "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!" )] def hello_world() end end - # class TestImplicitRender < SimpleRouteCase - # describe "render a simple action with new explicit call to render" - # - # get "/render_implicit_action/simple/hello_world" - # assert_body "Hello world!" - # assert_status 200 - # end - # - # class TestImplicitWithSpecialCharactersRender < SimpleRouteCase - # describe "render an action with a missing method and has special characters" - # - # get "/render_implicit_action/simple/hyphen-ated" - # assert_body "Hello hyphen-ated!" - # assert_status 200 - # end + class TestImplicitRender < SimpleRouteCase + describe "render a simple action with new explicit call to render" + + get "/render_implicit_action/simple/hello_world" + assert_body "Hello world!" + assert_status 200 + end + + class TestImplicitWithSpecialCharactersRender < SimpleRouteCase + describe "render an action with a missing method and has special characters" + + get "/render_implicit_action/simple/hyphen-ated" + assert_body "Hello hyphen-ated!" + assert_status 200 + end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb index 9ad79124b8..93bc8d854c 100644 --- a/actionpack/test/new_base/render_test.rb +++ b/actionpack/test/new_base/render_test.rb @@ -1,6 +1,24 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module Render + class BlankRenderController < ActionController::Base2 + self.view_paths = [ActionView::Template::FixturePath.new( + "render/blank_render/index.html.erb" => "Hello world!" + )] + + def index + render + end + end + + class TestBlankRender < SimpleRouteCase + describe "Render with blank" + + get "/render/blank_render" + assert_body "Hello world!" + assert_status 200 + end + class DoubleRenderController < ActionController::Base2 def index render :text => "hello" diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index b40cbb163f..03af5a66a6 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -58,11 +58,31 @@ module ActionController end end + def render(action = action_name, options = {}) + if action.is_a?(Hash) + options, action = action, nil + else + options.merge! :action => action + end + + super(options) + end + def render_to_body(options = {}) options = {:template => options} if options.is_a?(String) super end + def process_action + ret = super + render if response_body.nil? + ret + end + + def respond_to_action?(action_name) + super || view_paths.find_by_parts(action_name, {:formats => formats, :locales => [I18n.locale]}, controller_path) + end + # append_view_path File.join(File.dirname(__FILE__), '..', 'fixtures') CORE_METHODS = self.public_instance_methods -- cgit v1.2.3 From b98e496c039b7bde4a2de9c02809e0b4ee0679ae Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 17:32:55 -0700 Subject: Support implicit and explicit content types --- actionpack/lib/action_controller/new_base.rb | 1 + .../lib/action_controller/new_base/content_type.rb | 15 +++ actionpack/lib/action_view/template/text.rb | 3 +- actionpack/test/controller/content_type_test.rb | 10 ++ actionpack/test/new_base/content_type_test.rb | 111 +++++++++++++++++++++ actionpack/test/new_base/test_helper.rb | 1 + 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/content_type.rb create mode 100644 actionpack/test/new_base/content_type_test.rb diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index bfd8120e10..9c8a6d0216 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,4 +1,5 @@ module ActionController + autoload :ContentType, "action_controller/new_base/content_type" autoload :HideActions, "action_controller/new_base/hide_actions" autoload :Http, "action_controller/new_base/base" autoload :Layouts, "action_controller/new_base/layouts" diff --git a/actionpack/lib/action_controller/new_base/content_type.rb b/actionpack/lib/action_controller/new_base/content_type.rb new file mode 100644 index 0000000000..d2206a31af --- /dev/null +++ b/actionpack/lib/action_controller/new_base/content_type.rb @@ -0,0 +1,15 @@ +module ActionController + module ContentType + + def render_to_body(options = {}) + if content_type = options[:content_type] + response.content_type = content_type + end + + ret = super + response.content_type ||= options[:_template].mime_type + ret + end + + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index f81174d707..446c735ba3 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -3,7 +3,6 @@ module ActionView #:nodoc: def render(*) self end - def exempt_from_layout?() false end - + def mime_type() Mime::HTML end end end diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index 7377546631..64b8b10d5b 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -1,24 +1,29 @@ require 'abstract_unit' class ContentTypeController < ActionController::Base + # :ported: def render_content_type_from_body response.content_type = Mime::RSS render :text => "hello world!" end + # :ported: def render_defaults render :text => "hello world!" end + # :ported: def render_content_type_from_render render :text => "hello world!", :content_type => Mime::RSS end + # :ported: def render_charset_from_body response.charset = "utf-16" render :text => "hello world!" end + # :ported: def render_nil_charset_from_body response.charset = nil render :text => "hello world!" @@ -60,6 +65,7 @@ class ContentTypeTest < ActionController::TestCase @controller.logger = Logger.new(nil) end + # :ported: def test_render_defaults get :render_defaults assert_equal "utf-8", @response.charset @@ -74,24 +80,28 @@ class ContentTypeTest < ActionController::TestCase ContentTypeController.default_charset = "utf-8" end + # :ported: def test_content_type_from_body get :render_content_type_from_body assert_equal "application/rss+xml", @response.content_type assert_equal "utf-8", @response.charset end + # :ported: def test_content_type_from_render get :render_content_type_from_render assert_equal "application/rss+xml", @response.content_type assert_equal "utf-8", @response.charset end + # :ported: def test_charset_from_body get :render_charset_from_body assert_equal Mime::HTML, @response.content_type assert_equal "utf-16", @response.charset end + # :ported: def test_nil_charset_from_body get :render_nil_charset_from_body assert_equal Mime::HTML, @response.content_type diff --git a/actionpack/test/new_base/content_type_test.rb b/actionpack/test/new_base/content_type_test.rb new file mode 100644 index 0000000000..10a28da496 --- /dev/null +++ b/actionpack/test/new_base/content_type_test.rb @@ -0,0 +1,111 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") + +module ContentType + class BaseController < ActionController::Base2 + def index + render :text => "Hello world!" + end + + def set_on_response_obj + response.content_type = Mime::RSS + render :text => "Hello world!" + end + + def set_on_render + render :text => "Hello world!", :content_type => Mime::RSS + end + end + + class TestDefault < SimpleRouteCase + describe "a default response is HTML and UTF8" + + get "/content_type/base" + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-8" + end + + class TestSetOnResponseObj < SimpleRouteCase + describe "setting the content type of the response directly on the response object" + + get "/content_type/base/set_on_response_obj" + assert_body "Hello world!" + assert_header "Content-Type", "application/rss+xml; charset=utf-8" + end + + class TestSetOnRender < SimpleRouteCase + describe "setting the content type of the response as an option to render" + + get "/content_type/base/set_on_render" + assert_body "Hello world!" + assert_header "Content-Type", "application/rss+xml; charset=utf-8" + end + + class ImpliedController < ActionController::Base2 + self.view_paths = [ActionView::Template::FixturePath.new( + "content_type/implied/i_am_html_erb.html.erb" => "Hello world!", + "content_type/implied/i_am_xml_erb.xml.erb" => "Hello world!", + "content_type/implied/i_am_html_builder.html.builder" => "xml.p 'Hello'", + "content_type/implied/i_am_xml_builder.xml.builder" => "xml.awesome 'Hello'" + )] + + def i_am_html_erb() end + def i_am_xml_erb() end + def i_am_html_builder() end + def i_am_xml_builder() end + end + + class TestImpliedController < SimpleRouteCase + describe "the template's mime type is used if no content_type is specified" + + test "sets Content-Type as text/html when rendering *.html.erb" do + get "/content_type/implied/i_am_html_erb" + assert_header "Content-Type", "text/html; charset=utf-8" + end + + test "sets Content-Type as application/xml when rendering *.xml.erb" do + get "/content_type/implied/i_am_xml_erb" + assert_header "Content-Type", "application/xml; charset=utf-8" + end + + test "sets Content-Type as text/html when rendering *.html.builder" do + get "/content_type/implied/i_am_html_builder" + assert_header "Content-Type", "text/html; charset=utf-8" + end + + test "sets Content-Type as application/xml when rendering *.xml.builder" do + get "/content_type/implied/i_am_xml_builder" + assert_header "Content-Type", "application/xml; charset=utf-8" + end + + end +end + +module Charset + class BaseController < ActionController::Base2 + def set_on_response_obj + response.charset = "utf-16" + render :text => "Hello world!" + end + + def set_as_nil_on_response_obj + response.charset = nil + render :text => "Hello world!" + end + end + + class TestSetOnResponseObj < SimpleRouteCase + describe "setting the charset of the response directly on the response object" + + get "/charset/base/set_on_response_obj" + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-16" + end + + class TestSetAsNilOnResponseObj < SimpleRouteCase + describe "setting the charset of the response as nil directly on the response object" + + get "/charset/base/set_as_nil_on_response_obj" + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-8" + end +end \ No newline at end of file diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 03af5a66a6..d41c7283b7 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -42,6 +42,7 @@ module ActionController use ActionController::UrlFor use ActionController::Renderer use ActionController::Layouts + use ActionController::ContentType def self.inherited(klass) ::ActionController::Base2.subclasses << klass.to_s -- cgit v1.2.3 From d58b57a3caf4ad434c2be4f63eecd9a1921c7c4a Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 29 Apr 2009 17:50:11 -0700 Subject: Move ContentType inline for now. Trying to avoid premature proliferation of modules. --- actionpack/lib/action_controller/new_base.rb | 1 - actionpack/lib/action_controller/new_base/content_type.rb | 15 --------------- actionpack/lib/action_controller/new_base/renderer.rb | 10 ++++++---- actionpack/test/new_base/test_helper.rb | 1 - 4 files changed, 6 insertions(+), 21 deletions(-) delete mode 100644 actionpack/lib/action_controller/new_base/content_type.rb diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 9c8a6d0216..bfd8120e10 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,5 +1,4 @@ module ActionController - autoload :ContentType, "action_controller/new_base/content_type" autoload :HideActions, "action_controller/new_base/hide_actions" autoload :Http, "action_controller/new_base/base" autoload :Layouts, "action_controller/new_base/layouts" diff --git a/actionpack/lib/action_controller/new_base/content_type.rb b/actionpack/lib/action_controller/new_base/content_type.rb deleted file mode 100644 index d2206a31af..0000000000 --- a/actionpack/lib/action_controller/new_base/content_type.rb +++ /dev/null @@ -1,15 +0,0 @@ -module ActionController - module ContentType - - def render_to_body(options = {}) - if content_type = options[:content_type] - response.content_type = content_type - end - - ret = super - response.content_type ||= options[:_template].mime_type - ret - end - - end -end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 096a63e406..f21fd746b7 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -24,7 +24,9 @@ module ActionController options[:_prefix] = _prefix end - super(options) + ret = super(options) + response.content_type ||= options[:_template].mime_type + ret end private @@ -43,9 +45,9 @@ module ActionController end def _process_options(options) - if status = options[:status] - response.status = status.to_i - end + status, content_type = options.values_at(:status, :content_type) + response.status = status.to_i if status + response.content_type = content_type if content_type end end end diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index d41c7283b7..03af5a66a6 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -42,7 +42,6 @@ module ActionController use ActionController::UrlFor use ActionController::Renderer use ActionController::Layouts - use ActionController::ContentType def self.inherited(klass) ::ActionController::Base2.subclasses << klass.to_s -- cgit v1.2.3 From 4ee3e5b094463383891789f484e927b19fccc744 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 30 Apr 2009 15:13:40 -0700 Subject: Ported over the concept of public instance methods on controller child classes as callable action methods --- actionpack/lib/action_controller/abstract/base.rb | 48 +++++++++++++++++++---- actionpack/lib/action_controller/new_base/base.rb | 14 +++---- actionpack/test/controller/render_test.rb | 7 ++++ actionpack/test/new_base/render_test.rb | 10 +++++ actionpack/test/new_base/test_helper.rb | 10 ++--- 5 files changed, 69 insertions(+), 20 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index a87a490a2d..3b85ba5565 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -4,13 +4,44 @@ module AbstractController attr_internal :response_body attr_internal :response_obj attr_internal :action_name - - def self.process(action) - new.process(action) + + class << self + attr_reader :abstract + + def abstract! + @abstract = true + end + + alias_method :abstract?, :abstract + + def internal_methods + controller = self + controller = controller.superclass until controller.abstract? + controller.public_instance_methods(true) + end + + def process(action) + new.process(action) + end + + def hidden_actions + [] + end + + def action_methods + @action_methods ||= + # All public instance methods of this class, including ancestors + public_instance_methods(true).map { |m| m.to_sym }.to_set - + # Except for public instance methods of Base and its ancestors + internal_methods.map { |m| m.to_sym } + + # Be sure to include shadowed public instance methods of this class + public_instance_methods(false).map { |m| m.to_sym } - + # And always exclude explicitly hidden actions + hidden_actions + end end - def self.inherited(klass) - end + abstract! def initialize self.response_obj = {} @@ -29,6 +60,10 @@ module AbstractController private + def action_methods + self.class.action_methods + end + # It is possible for respond_to?(action_name) to be false and # respond_to?(:action_missing) to be false if respond_to_action? # is overridden in a subclass. For instance, ActionController::Base @@ -45,8 +80,7 @@ module AbstractController # you must handle it by also overriding process_action and # handling the case. def respond_to_action?(action_name) - respond_to?(action_name) || respond_to?(:action_missing, true) + action_methods.include?(action_name) || respond_to?(:action_missing, true) end - end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 9f7a148b3c..00d161289e 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -1,5 +1,6 @@ module ActionController class Http < AbstractController::Base + abstract! # :api: public attr_internal :request, :response, :params @@ -19,18 +20,15 @@ module ActionController # :api: public def controller_path() self.class.controller_path end - - # :api: private - def self.action_methods - @action_names ||= Set.new(self.public_instance_methods - self::CORE_METHODS) + + # :api: private + def self.internal_methods + ActionController::Http.public_instance_methods(true) end # :api: private def self.action_names() action_methods end - # :api: private - def action_methods() self.class.action_names end - # :api: private def action_names() action_methods end @@ -44,7 +42,7 @@ module ActionController def call(env) @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new - process(@_request.parameters[:action]) + process(@_request.parameters[:action].to_sym) @_response.body = response_body @_response.prepare! self diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index d4a18a673c..e6b2ee7e9f 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -4,6 +4,7 @@ require 'pathname' module Fun class GamesController < ActionController::Base + # :ported: def hello_world end end @@ -116,6 +117,7 @@ class TestController < ActionController::Base render :text => "hello #{@person}" end + # :ported: def render_action_hello_world render :action => "hello_world" end @@ -839,17 +841,20 @@ class RenderTest < ActionController::TestCase assert_equal "hello david", @response.body end + # :ported: def test_render_action get :render_action_hello_world assert_template "test/hello_world" end + # :ported: def test_render_action_hello_world_as_string get :render_action_hello_world_as_string assert_equal "Hello world!", @response.body assert_template "test/hello_world" end + # :ported: def test_render_action_with_symbol get :render_action_hello_world_with_symbol assert_template "test/hello_world" @@ -949,6 +954,7 @@ class RenderTest < ActionController::TestCase assert_equal 'application/json', @response.content_type end + # :ported: def test_render_custom_code get :render_custom_code assert_response 404 @@ -1082,6 +1088,7 @@ class RenderTest < ActionController::TestCase assert_template "test/hello_world" end + # :ported: def test_nested_rendering @controller = Fun::GamesController.new get :hello_world diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb index 93bc8d854c..bc7203f294 100644 --- a/actionpack/test/new_base/render_test.rb +++ b/actionpack/test/new_base/render_test.rb @@ -35,4 +35,14 @@ module Render end end end + + class TestRenderObjectMethod < SimpleRouteCase + describe "Methods on Object are not actions" + + test "raises an exception" do + assert_raises(AbstractController::ActionNotFound) do + get "/render/blank_render/clone" + end + end + end end \ No newline at end of file diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 03af5a66a6..d58b83cf7b 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -34,6 +34,8 @@ end module ActionController class Base2 < Http + abstract! + use AbstractController::Callbacks use AbstractController::Helpers use AbstractController::Logger @@ -80,15 +82,13 @@ module ActionController end def respond_to_action?(action_name) - super || view_paths.find_by_parts(action_name, {:formats => formats, :locales => [I18n.locale]}, controller_path) + super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path) end - - # append_view_path File.join(File.dirname(__FILE__), '..', 'fixtures') - - CORE_METHODS = self.public_instance_methods end class CompatibleBase2 < Base2 + abstract! + use ActionController::Rails2Compatibility end end -- cgit v1.2.3 From 69fd66916566f402620cc385689c36f61deb6ba1 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 11:40:32 -0700 Subject: Committing the last changes before we start trying to get the old tests to pass on the new base --- actionpack/test/controller/render_test.rb | 11 +++++- actionpack/test/new_base/render_layout_test.rb | 18 ++++++++-- actionpack/test/new_base/render_test.rb | 48 +++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index e6b2ee7e9f..fb9b121fc9 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -292,6 +292,7 @@ class TestController < ActionController::Base render :text => ' ' end + # :ported: def layout_test render :action => "hello_world" end @@ -299,7 +300,8 @@ class TestController < ActionController::Base def builder_layout_test render :action => "hello", :layout => "layouts/builder" end - + + # :move: test this in ActionView def builder_partial_test render :action => "hello_world_container" end @@ -988,14 +990,17 @@ class RenderTest < ActionController::TestCase assert_equal 'appended', @response.body end + # :ported: def test_attempt_to_access_object_method assert_raise(ActionController::UnknownAction, "No action responded to [clone]") { get :clone } end + # :ported: def test_private_methods assert_raise(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout } end + # :ported: def test_access_to_request_in_view get :accessing_request_in_template assert_equal "Hello: www.nextangle.com", @response.body @@ -1006,11 +1011,13 @@ class RenderTest < ActionController::TestCase assert_equal "Logger", @response.body end + # :ported: def test_access_to_action_name_in_view get :accessing_action_name_in_template assert_equal "accessing_action_name_in_template", @response.body end + # :ported: def test_access_to_controller_name_in_view get :accessing_controller_name_in_template assert_equal "test", @response.body # name is explicitly set to 'test' inside the controller. @@ -1022,6 +1029,7 @@ class RenderTest < ActionController::TestCase assert_equal "text/javascript", @response.content_type end + # :ported: def test_render_xml get :render_xml_hello assert_equal "\n

Hello David

\n

This is grand!

\n\n", @response.body @@ -1034,6 +1042,7 @@ class RenderTest < ActionController::TestCase assert_equal "application/xml", @response.content_type end + # :ported: def test_render_xml_with_default get :greeting assert_equal "

This is grand!

\n", @response.body diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb index 07ea2f191e..5d28926cc6 100644 --- a/actionpack/test/new_base/render_layout_test.rb +++ b/actionpack/test/new_base/render_layout_test.rb @@ -5,12 +5,21 @@ module ControllerLayouts self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", - "basic.html.erb" => "Hello world!" + "layouts/override.html.erb" => "Override! <%= yield %>", + "basic.html.erb" => "Hello world!" )] def index render :template => "basic" end + + def override + render :template => "basic", :layout => "override" + end + + def builder_override + + end end class TestImplicitLayout < SimpleRouteCase @@ -41,5 +50,10 @@ module ControllerLayouts assert_status 200 end - + class TestOverridingImplicitLayout < SimpleRouteCase + describe "overriding an implicit layout with render :layout option" + + get "/controller_layouts/implicit/override" + assert_body "Override! Hello world!" + end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb index bc7203f294..647aa01628 100644 --- a/actionpack/test/new_base/render_test.rb +++ b/actionpack/test/new_base/render_test.rb @@ -3,12 +3,29 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module Render class BlankRenderController < ActionController::Base2 self.view_paths = [ActionView::Template::FixturePath.new( - "render/blank_render/index.html.erb" => "Hello world!" + "render/blank_render/index.html.erb" => "Hello world!", + "render/blank_render/access_request.html.erb" => "The request: <%= request.method.to_s.upcase %>", + "render/blank_render/access_action_name.html.erb" => "Action Name: <%= action_name %>", + "render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>" )] def index render end + + def access_request + render :action => "access_request" + end + + def render_action_name + render :action => "access_action_name" + end + + private + + def secretz + render :text => "FAIL WHALE!" + end end class TestBlankRender < SimpleRouteCase @@ -36,13 +53,36 @@ module Render end end - class TestRenderObjectMethod < SimpleRouteCase - describe "Methods on Object are not actions" + class TestOnlyRenderPublicActions < SimpleRouteCase + describe "Only public methods on actual controllers are callable actions" - test "raises an exception" do + test "raises an exception when a method of Object is called" do assert_raises(AbstractController::ActionNotFound) do get "/render/blank_render/clone" end end + + test "raises an exception when a private method is called" do + assert_raises(AbstractController::ActionNotFound) do + get "/render/blank_render/secretz" + end + end + end + + class TestVariousObjectsAvailableInView < SimpleRouteCase + test "The request object is accessible in the view" do + get "/render/blank_render/access_request" + assert_body "The request: GET" + end + + test "The action_name is accessible in the view" do + get "/render/blank_render/render_action_name" + assert_body "Action Name: render_action_name" + end + + test "The controller_name is accessible in the view" do + get "/render/blank_render/access_controller_name" + assert_body "Controller Name: blank_render" + end end end \ No newline at end of file -- cgit v1.2.3 From b4903a8e34da77b96ea136ccd015c1634a8a5c2b Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 16:01:37 -0700 Subject: Modify new_base to use String action_names for back-compat --- actionpack/lib/action_controller/abstract/base.rb | 8 ++++---- actionpack/lib/action_controller/abstract/callbacks.rb | 4 ++-- actionpack/lib/action_controller/new_base/base.rb | 2 +- actionpack/test/abstract_controller/abstract_controller_test.rb | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index 3b85ba5565..8a8e748c0e 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -21,7 +21,7 @@ module AbstractController end def process(action) - new.process(action) + new.process(action.to_s) end def hidden_actions @@ -31,11 +31,11 @@ module AbstractController def action_methods @action_methods ||= # All public instance methods of this class, including ancestors - public_instance_methods(true).map { |m| m.to_sym }.to_set - + public_instance_methods(true).map { |m| m.to_s }.to_set - # Except for public instance methods of Base and its ancestors - internal_methods.map { |m| m.to_sym } + + internal_methods.map { |m| m.to_s } + # Be sure to include shadowed public instance methods of this class - public_instance_methods(false).map { |m| m.to_sym } - + public_instance_methods(false).map { |m| m.to_s } - # And always exclude explicitly hidden actions hidden_actions end diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb index c8b509081c..5f1607940a 100644 --- a/actionpack/lib/action_controller/abstract/callbacks.rb +++ b/actionpack/lib/action_controller/abstract/callbacks.rb @@ -14,11 +14,11 @@ module AbstractController module ClassMethods def _normalize_callback_options(options) if only = options[:only] - only = Array(only).map {|o| "action_name == :#{o}"}.join(" || ") + only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ") options[:per_key] = {:if => only} end if except = options[:except] - except = Array(except).map {|e| "action_name == :#{e}"}.join(" || ") + except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ") options[:per_key] = {:unless => except} end end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 00d161289e..f663900944 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -42,7 +42,7 @@ module ActionController def call(env) @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new - process(@_request.parameters[:action].to_sym) + process(@_request.parameters[:action]) @_response.body = response_body @_response.prepare! self diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index cf6fb5140d..c283a7319d 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -203,7 +203,7 @@ module AbstractController private def respond_to_action?(action_name) - action_name != :fail + action_name.to_s != "fail" end end -- cgit v1.2.3 From 918b119bd3310c15dab4eb8a3317cc2a32503119 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 16:02:37 -0700 Subject: Add support for stripping "layouts/" from the layout name --- actionpack/lib/action_controller/abstract/layouts.rb | 3 +++ actionpack/lib/action_controller/new_base/compatibility.rb | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index f56b9dd914..eb3b73289d 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -57,6 +57,9 @@ module AbstractController def _layout() end # This will be overwritten + # :api: plugin + # ==== + # Override this to mutate the inbound layout name def _layout_for_name(name) unless [String, FalseClass, NilClass].include?(name.class) raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}" diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 8682493c8e..275a18abfd 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -8,5 +8,10 @@ module ActionController super end + def _layout_for_name(name) + name &&= name.sub(%r{^/?layouts/}, '') + super + end + end end \ No newline at end of file -- cgit v1.2.3 From b1d34b3aa42beaf6a9fb93f114aed8fe08ebd9db Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 16:03:46 -0700 Subject: Starting to get new_base to run on old tests --- actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 3 + .../lib/action_controller/new_base/testing.rb | 23 +++ .../lib/action_controller/testing/process2.rb | 68 +++++++ actionpack/test/abstract_controller/test_helper.rb | 7 +- actionpack/test/abstract_unit2.rb | 210 +++++++++++++++++++++ actionpack/test/controller/render_test.rb | 2 +- actionpack/test/new_base/test_helper.rb | 2 + 8 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/testing.rb create mode 100644 actionpack/lib/action_controller/testing/process2.rb create mode 100644 actionpack/test/abstract_unit2.rb diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index bfd8120e10..47621f0847 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -4,5 +4,6 @@ module ActionController autoload :Layouts, "action_controller/new_base/layouts" autoload :Rails2Compatibility, "action_controller/new_base/compatibility" autoload :Renderer, "action_controller/new_base/renderer" + autoload :Testing, "action_controller/new_base/testing" autoload :UrlFor, "action_controller/new_base/url_for" end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index f663900944..e24c494652 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -53,4 +53,7 @@ module ActionController @_response.to_a end end + + class Base < Http + end end diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb new file mode 100644 index 0000000000..428f339b3d --- /dev/null +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -0,0 +1,23 @@ +module ActionController + module Testing + + # OMG MEGA HAX + def process_with_test(request, response) + @_request = request + @_response = response + ret = process(request.parameters[:action]) + @_response.body = self.response_body + set_test_assigns + ret + end + + def set_test_assigns + @assigns = {} + (instance_variable_names - self.class.protected_instance_variables).each do |var| + name, value = var[1..-1], instance_variable_get(var) + @assigns[name] = value + end + end + + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb new file mode 100644 index 0000000000..7111733d0d --- /dev/null +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -0,0 +1,68 @@ +require "action_controller/testing/process" + +module ActionController + module TestProcess2 + + # Executes a request simulating GET HTTP method and set/volley the response + def get(action, parameters = nil, session = nil, flash = nil) + process(action, parameters, session, flash, "GET") + end + + # Executes a request simulating POST HTTP method and set/volley the response + def post(action, parameters = nil, session = nil, flash = nil) + process(action, parameters, session, flash, "POST") + end + + # Executes a request simulating PUT HTTP method and set/volley the response + def put(action, parameters = nil, session = nil, flash = nil) + process(action, parameters, session, flash, "PUT") + end + + # Executes a request simulating DELETE HTTP method and set/volley the response + def delete(action, parameters = nil, session = nil, flash = nil) + process(action, parameters, session, flash, "DELETE") + end + + # Executes a request simulating HEAD HTTP method and set/volley the response + def head(action, parameters = nil, session = nil, flash = nil) + process(action, parameters, session, flash, "HEAD") + end + + def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET') + # Sanity check for required instance variables so we can give an + # understandable error message. + %w(@controller @request @response).each do |iv_name| + if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil? + raise "#{iv_name} is nil: make sure you set it in your test's setup method." + end + end + + @request.recycle! + @response.recycle! + + @html_document = nil + @request.env['REQUEST_METHOD'] = http_method + + parameters ||= {} + @request.assign_parameters(@controller.class.controller_path, action.to_s, parameters) + + @request.session = ActionController::TestSession.new(session) unless session.nil? + @request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash + build_request_uri(action, parameters) + + # Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest + @controller.process_with_test(@request, @response) + end + + def build_request_uri(action, parameters) + unless @request.env['REQUEST_URI'] + options = @controller.__send__(:rewrite_options, parameters) + options.update(:only_path => true, :action => action) + + url = ActionController::UrlRewriter.new(@request, parameters) + @request.set_REQUEST_URI(url.rewrite(options)) + end + end + + end +end \ No newline at end of file diff --git a/actionpack/test/abstract_controller/test_helper.rb b/actionpack/test/abstract_controller/test_helper.rb index b9248c6bbd..a0375a0e99 100644 --- a/actionpack/test/abstract_controller/test_helper.rb +++ b/actionpack/test/abstract_controller/test_helper.rb @@ -2,9 +2,13 @@ $:.unshift(File.dirname(__FILE__) + '/../../lib') $:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib') $:.unshift(File.dirname(__FILE__) + '/../lib') +require 'rubygems' require 'test/unit' -require 'active_support' +require 'active_support/core/all' require 'active_support/test_case' +require 'action_controller/abstract' +require 'action_controller/new_base/base' +require 'action_controller/new_base/renderer' require 'action_controller' require 'action_view/base' require 'fixture_template' @@ -17,7 +21,6 @@ rescue LoadError # Debugging disabled. `gem install ruby-debug` to enable. end -require 'action_controller/abstract' # require 'action_controller/abstract/base' # require 'action_controller/abstract/renderer' # require 'action_controller/abstract/layouts' diff --git a/actionpack/test/abstract_unit2.rb b/actionpack/test/abstract_unit2.rb new file mode 100644 index 0000000000..c1e2631ac2 --- /dev/null +++ b/actionpack/test/abstract_unit2.rb @@ -0,0 +1,210 @@ +$:.unshift(File.dirname(__FILE__) + '/../lib') +$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') +$:.unshift(File.dirname(__FILE__) + '/lib') + +# HAX +module ActionController + +end + +# TestCase +# include TestProcess2 + + +require 'test/unit' +require 'active_support' +require 'active_support/core/all' +require 'active_support/test_case' +require 'action_controller/abstract' +require 'action_controller/new_base' +require 'action_controller/new_base/base' +require 'action_controller/new_base/renderer' # HAX +require 'action_controller' +require 'fixture_template' +require 'action_view/test_case' + +FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') + +module ActionController + autoload :TestProcess2, 'action_controller/testing/process2' + + class ActionControllerError < StandardError #:nodoc: + end + + class SessionRestoreError < ActionControllerError #:nodoc: + end + + class RenderError < ActionControllerError #:nodoc: + end + + class RoutingError < ActionControllerError #:nodoc: + attr_reader :failures + def initialize(message, failures=[]) + super(message) + @failures = failures + end + end + + class MethodNotAllowed < ActionControllerError #:nodoc: + attr_reader :allowed_methods + + def initialize(*allowed_methods) + super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.") + @allowed_methods = allowed_methods + end + + def allowed_methods_header + allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', ' + end + + def handle_response!(response) + response.headers['Allow'] ||= allowed_methods_header + end + end + + class NotImplemented < MethodNotAllowed #:nodoc: + end + + class UnknownController < ActionControllerError #:nodoc: + end + + class UnknownAction < ActionControllerError #:nodoc: + end + + class MissingFile < ActionControllerError #:nodoc: + end + + class RenderError < ActionControllerError #:nodoc: + end + + class SessionOverflowError < ActionControllerError #:nodoc: + DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.' + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + + class UnknownHttpMethod < ActionControllerError #:nodoc: + end + + class Base < Http + abstract! + # + cattr_accessor :relative_url_root + self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] + + cattr_reader :protected_instance_variables + # Controller specific instance variables which will not be accessible inside views. + @@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller + @action_name @before_filter_chain_aborted @action_cache_path @_headers @_params + @_flash @_response) + # + + use AbstractController::Callbacks + use AbstractController::Helpers + use AbstractController::Logger + + use ActionController::HideActions + use ActionController::UrlFor + use ActionController::Renderer + use ActionController::Layouts + use ActionController::Rails2Compatibility + use ActionController::Testing + + def self.protect_from_forgery() end + + def self.inherited(klass) + ::ActionController::Base.subclasses << klass.to_s + super + end + + def self.subclasses + @subclasses ||= [] + end + + def self.app_loaded! + @subclasses.each do |subclass| + subclass.constantize._write_layout_method + end + end + + def render(action = action_name, options = {}) + if action.is_a?(Hash) + options, action = action, nil + else + options.merge! :action => action + end + + super(options) + end + + def render_to_body(options = {}) + options = {:template => options} if options.is_a?(String) + super + end + + def process_action + ret = super + render if response_body.nil? + ret + end + + def respond_to_action?(action_name) + super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path) + end + end + + Base.view_paths = FIXTURE_LOAD_PATH + + class TestCase + include TestProcess2 + setup do + ActionController::Routing::Routes.draw do |map| + map.connect ':controller/:action/:id' + end + end + + def assert_template(options = {}, message = nil) + validate_response! + + clean_backtrace do + case options + when NilClass, String + hax = @controller._action_view.instance_variable_get(:@_rendered) + rendered = (hax[:template] || []).map { |t| t.identifier } + msg = build_message(message, + "expecting but rendering with ", + options, rendered.join(', ')) + assert_block(msg) do + if options.nil? + hax[:template].blank? + else + rendered.any? { |t| t.match(options) } + end + end + when Hash + if expected_partial = options[:partial] + partials = hax[:partials] + if expected_count = options[:count] + found = partials.detect { |p, _| p.identifier.match(expected_partial) } + actual_count = found.nil? ? 0 : found.second + msg = build_message(message, + "expecting ? to be rendered ? time(s) but rendered ? time(s)", + expected_partial, expected_count, actual_count) + assert(actual_count == expected_count.to_i, msg) + else + msg = build_message(message, + "expecting partial but action rendered ", + options[:partial], partials.keys) + assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg) + end + else + assert hax[:partials].empty?, + "Expected no partials to be rendered" + end + end + end + end + end +end \ No newline at end of file diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index fb9b121fc9..1e69ca894f 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1,4 +1,4 @@ -require 'abstract_unit' +require ENV['new_base'] ? 'abstract_unit2' : 'abstract_unit' require 'controller/fake_models' require 'pathname' diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index d58b83cf7b..6a71bd29c4 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -5,6 +5,8 @@ $:.unshift(File.dirname(__FILE__) + '/../lib') require 'test/unit' require 'active_support' require 'active_support/test_case' +require 'action_controller/new_base/base' +require 'action_controller/new_base/renderer' require 'action_controller' require 'action_view/base' require 'fixture_template' -- cgit v1.2.3 From e046f36824fcc164c284a13524c6b4153010a4e1 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 17:27:44 -0700 Subject: Renamed Base2 to Base and don't require old action_controller for new Base --- actionpack/lib/action_controller/new_base.rb | 17 ++++- actionpack/lib/action_controller/new_base/base.rb | 87 +++++++++++----------- .../action_controller/new_base/compatibility.rb | 21 ++++++ actionpack/lib/action_controller/new_base/http.rb | 56 ++++++++++++++ actionpack/lib/action_dispatch/middleware/stack.rb | 2 - actionpack/test/abstract_controller/test_helper.rb | 13 +--- actionpack/test/new_base/base_test.rb | 6 +- actionpack/test/new_base/content_type_test.rb | 6 +- actionpack/test/new_base/render_action_test.rb | 6 +- actionpack/test/new_base/render_template_test.rb | 4 +- actionpack/test/new_base/render_test.rb | 4 +- actionpack/test/new_base/render_text_test.rb | 6 +- actionpack/test/new_base/test_helper.rb | 70 +---------------- 13 files changed, 157 insertions(+), 141 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/http.rb diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 47621f0847..b292fd579d 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,9 +1,22 @@ module ActionController + autoload :Base, "action_controller/new_base/base" autoload :HideActions, "action_controller/new_base/hide_actions" - autoload :Http, "action_controller/new_base/base" + autoload :Http, "action_controller/new_base/http" autoload :Layouts, "action_controller/new_base/layouts" autoload :Rails2Compatibility, "action_controller/new_base/compatibility" autoload :Renderer, "action_controller/new_base/renderer" autoload :Testing, "action_controller/new_base/testing" autoload :UrlFor, "action_controller/new_base/url_for" -end \ No newline at end of file + + # Ported modules + # require 'action_controller/routing' + autoload :Dispatcher, 'action_controller/dispatch/dispatcher' + autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes' + autoload :Resources, 'action_controller/routing/resources' + autoload :SessionManagement, 'action_controller/base/session_management' + + require 'action_controller/routing' +end + +require 'action_dispatch' +require 'action_view' \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index e24c494652..8af6ffbc92 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -1,59 +1,60 @@ module ActionController - class Http < AbstractController::Base + class Base < Http abstract! - # :api: public - attr_internal :request, :response, :params - - # :api: public - def self.controller_name - @controller_name ||= controller_path.split("/").last - end + use AbstractController::Callbacks + use AbstractController::Helpers + use AbstractController::Logger - # :api: public - def controller_name() self.class.controller_name end - - # :api: public - def self.controller_path - @controller_path ||= self.name.sub(/Controller$/, '').underscore - end + use ActionController::HideActions + use ActionController::UrlFor + use ActionController::Renderer + use ActionController::Layouts + + # Legacy modules + include SessionManagement - # :api: public - def controller_path() self.class.controller_path end + # Rails 2.x compatibility + use ActionController::Rails2Compatibility - # :api: private - def self.internal_methods - ActionController::Http.public_instance_methods(true) + def self.inherited(klass) + ::ActionController::Base.subclasses << klass.to_s + super end - # :api: private - def self.action_names() action_methods end + def self.subclasses + @subclasses ||= [] + end - # :api: private - def action_names() action_methods end + def self.app_loaded! + @subclasses.each do |subclass| + subclass.constantize._write_layout_method + end + end - # :api: plugin - def self.call(env) - controller = new - controller.call(env).to_rack + def render(action = action_name, options = {}) + if action.is_a?(Hash) + options, action = action, nil + else + options.merge! :action => action + end + + super(options) end - # :api: private - def call(env) - @_request = ActionDispatch::Request.new(env) - @_response = ActionDispatch::Response.new - process(@_request.parameters[:action]) - @_response.body = response_body - @_response.prepare! - self + def render_to_body(options = {}) + options = {:template => options} if options.is_a?(String) + super end - # :api: private - def to_rack - @_response.to_a + def process_action + ret = super + render if response_body.nil? + ret + end + + def respond_to_action?(action_name) + super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path) end end - - class Base < Http - end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 275a18abfd..db471f7658 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -1,6 +1,27 @@ module ActionController module Rails2Compatibility + # Temporary hax + setup do + cattr_accessor :session_options + self.send(:class_variable_set, "@@session_options", {}) + + cattr_accessor :allow_concurrency + self.send(:class_variable_set, "@@allow_concurrency", false) + + cattr_accessor :param_parsers + self.send(:class_variable_set, "@@param_parsers", { Mime::MULTIPART_FORM => :multipart_form, + Mime::URL_ENCODED_FORM => :url_encoded_form, + Mime::XML => :xml_simple, + Mime::JSON => :json }) + + cattr_accessor :relative_url_root + self.send(:class_variable_set, "@@relative_url_root", ENV['RAILS_RELATIVE_URL_ROOT']) + + cattr_accessor :default_charset + self.send(:class_variable_set, "@@default_charset", "utf-8") + end + def render_to_body(options) if options.is_a?(Hash) && options.key?(:template) options[:template].sub!(/^\//, '') diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb new file mode 100644 index 0000000000..f663900944 --- /dev/null +++ b/actionpack/lib/action_controller/new_base/http.rb @@ -0,0 +1,56 @@ +module ActionController + class Http < AbstractController::Base + abstract! + + # :api: public + attr_internal :request, :response, :params + + # :api: public + def self.controller_name + @controller_name ||= controller_path.split("/").last + end + + # :api: public + def controller_name() self.class.controller_name end + + # :api: public + def self.controller_path + @controller_path ||= self.name.sub(/Controller$/, '').underscore + end + + # :api: public + def controller_path() self.class.controller_path end + + # :api: private + def self.internal_methods + ActionController::Http.public_instance_methods(true) + end + + # :api: private + def self.action_names() action_methods end + + # :api: private + def action_names() action_methods end + + # :api: plugin + def self.call(env) + controller = new + controller.call(env).to_rack + end + + # :api: private + def call(env) + @_request = ActionDispatch::Request.new(env) + @_response = ActionDispatch::Response.new + process(@_request.parameters[:action]) + @_response.body = response_body + @_response.prepare! + self + end + + # :api: private + def to_rack + @_response.to_a + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index ee5f28d5cb..52abd69a42 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -34,8 +34,6 @@ module ActionDispatch else @klass.to_s.constantize end - rescue NameError - @klass end def active? diff --git a/actionpack/test/abstract_controller/test_helper.rb b/actionpack/test/abstract_controller/test_helper.rb index a0375a0e99..f0556e63e2 100644 --- a/actionpack/test/abstract_controller/test_helper.rb +++ b/actionpack/test/abstract_controller/test_helper.rb @@ -7,10 +7,7 @@ require 'test/unit' require 'active_support/core/all' require 'active_support/test_case' require 'action_controller/abstract' -require 'action_controller/new_base/base' -require 'action_controller/new_base/renderer' -require 'action_controller' -require 'action_view/base' +require 'action_view' require 'fixture_template' begin @@ -19,10 +16,4 @@ begin Debugger.start rescue LoadError # Debugging disabled. `gem install ruby-debug` to enable. -end - -# require 'action_controller/abstract/base' -# require 'action_controller/abstract/renderer' -# require 'action_controller/abstract/layouts' -# require 'action_controller/abstract/callbacks' -# require 'action_controller/abstract/helpers' \ No newline at end of file +end \ No newline at end of file diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb index 27d1a7f026..a32653f128 100644 --- a/actionpack/test/new_base/base_test.rb +++ b/actionpack/test/new_base/base_test.rb @@ -2,7 +2,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") # Tests the controller dispatching happy path module Dispatching - class SimpleController < ActionController::Base2 + class SimpleController < ActionController::Base def index render :text => "success" end @@ -69,9 +69,9 @@ module Dispatching end end - class EmptyController < ActionController::Base2 ; end + class EmptyController < ActionController::Base ; end module Submodule - class ContainedEmptyController < ActionController::Base2 ; end + class ContainedEmptyController < ActionController::Base ; end end class ControllerClassTests < Test::Unit::TestCase diff --git a/actionpack/test/new_base/content_type_test.rb b/actionpack/test/new_base/content_type_test.rb index 10a28da496..a5c04e9cb6 100644 --- a/actionpack/test/new_base/content_type_test.rb +++ b/actionpack/test/new_base/content_type_test.rb @@ -1,7 +1,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module ContentType - class BaseController < ActionController::Base2 + class BaseController < ActionController::Base def index render :text => "Hello world!" end @@ -40,7 +40,7 @@ module ContentType assert_header "Content-Type", "application/rss+xml; charset=utf-8" end - class ImpliedController < ActionController::Base2 + class ImpliedController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new( "content_type/implied/i_am_html_erb.html.erb" => "Hello world!", "content_type/implied/i_am_xml_erb.xml.erb" => "Hello world!", @@ -81,7 +81,7 @@ module ContentType end module Charset - class BaseController < ActionController::Base2 + class BaseController < ActionController::Base def set_on_response_obj response.charset = "utf-16" render :text => "Hello world!" diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb index 37b83fb681..348d70381b 100644 --- a/actionpack/test/new_base/render_action_test.rb +++ b/actionpack/test/new_base/render_action_test.rb @@ -3,7 +3,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module RenderAction # This has no layout and it works - class BasicController < ActionController::Base2 + class BasicController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new( "render_action/basic/hello_world.html.erb" => "Hello world!" @@ -203,7 +203,7 @@ end module RenderActionWithControllerLayout - class BasicController < ActionController::Base2 + class BasicController < ActionController::Base self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( "render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!", "layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" @@ -266,7 +266,7 @@ end module RenderActionWithBothLayouts - class BasicController < ActionController::Base2 + class BasicController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new({ "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!", "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index 63769df082..c09eeb1926 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -1,7 +1,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module RenderTemplate - class WithoutLayoutController < ActionController::Base2 + class WithoutLayoutController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", @@ -129,7 +129,7 @@ module RenderTemplate end module Compatibility - class WithoutLayoutController < ActionController::CompatibleBase2 + class WithoutLayoutController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica" diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb index 647aa01628..b1867fdcc2 100644 --- a/actionpack/test/new_base/render_test.rb +++ b/actionpack/test/new_base/render_test.rb @@ -1,7 +1,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module Render - class BlankRenderController < ActionController::Base2 + class BlankRenderController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new( "render/blank_render/index.html.erb" => "Hello world!", "render/blank_render/access_request.html.erb" => "The request: <%= request.method.to_s.upcase %>", @@ -36,7 +36,7 @@ module Render assert_status 200 end - class DoubleRenderController < ActionController::Base2 + class DoubleRenderController < ActionController::Base def index render :text => "hello" render :text => "world" diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index d97c2ca0a6..39f2f7abbf 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -1,10 +1,10 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") -class ApplicationController < ActionController::Base2 +class ApplicationController < ActionController::Base end module RenderText - class SimpleController < ActionController::Base2 + class SimpleController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new] def index @@ -146,4 +146,4 @@ module RenderText end end -ActionController::Base2.app_loaded! \ No newline at end of file +ActionController::Base.app_loaded! \ No newline at end of file diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 6a71bd29c4..547eb1ef72 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -5,10 +5,7 @@ $:.unshift(File.dirname(__FILE__) + '/../lib') require 'test/unit' require 'active_support' require 'active_support/test_case' -require 'action_controller/new_base/base' -require 'action_controller/new_base/renderer' -require 'action_controller' -require 'action_view/base' +require 'action_view' require 'fixture_template' begin @@ -34,67 +31,6 @@ module Rails end end -module ActionController - class Base2 < Http - abstract! - - use AbstractController::Callbacks - use AbstractController::Helpers - use AbstractController::Logger - - use ActionController::HideActions - use ActionController::UrlFor - use ActionController::Renderer - use ActionController::Layouts - - def self.inherited(klass) - ::ActionController::Base2.subclasses << klass.to_s - super - end - - def self.subclasses - @subclasses ||= [] - end - - def self.app_loaded! - @subclasses.each do |subclass| - subclass.constantize._write_layout_method - end - end - - def render(action = action_name, options = {}) - if action.is_a?(Hash) - options, action = action, nil - else - options.merge! :action => action - end - - super(options) - end - - def render_to_body(options = {}) - options = {:template => options} if options.is_a?(String) - super - end - - def process_action - ret = super - render if response_body.nil? - ret - end - - def respond_to_action?(action_name) - super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path) - end - end - - class CompatibleBase2 < Base2 - abstract! - - use ActionController::Rails2Compatibility - end -end - # Temporary base class class Rack::TestCase < ActiveSupport::TestCase include Rack::Test::Methods @@ -103,7 +39,7 @@ class Rack::TestCase < ActiveSupport::TestCase ActionController::Base.session_options[:key] = "abc" ActionController::Base.session_options[:secret] = ("*" * 30) - controllers = ActionController::Base2.subclasses.map do |k| + controllers = ActionController::Base.subclasses.map do |k| k.underscore.sub(/_controller$/, '') end @@ -171,7 +107,7 @@ class Rack::TestCase < ActiveSupport::TestCase end -class ::ApplicationController < ActionController::Base2 +class ::ApplicationController < ActionController::Base end class SimpleRouteCase < Rack::TestCase -- cgit v1.2.3 From 7dd072d333040d2bb1197baa55fddfb9b72053bd Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 17:53:20 -0700 Subject: A few more tweaks to get new Base running old render tests again --- actionpack/lib/action_controller/new_base.rb | 8 ++++++-- actionpack/lib/action_controller/testing/process2.rb | 4 ++-- actionpack/test/abstract_unit2.rb | 15 ++------------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index b292fd579d..7098b812f6 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -10,10 +10,14 @@ module ActionController # Ported modules # require 'action_controller/routing' - autoload :Dispatcher, 'action_controller/dispatch/dispatcher' + autoload :Dispatcher, 'action_controller/dispatch/dispatcher' autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes' - autoload :Resources, 'action_controller/routing/resources' + autoload :RecordIdentifier, 'action_controller/record_identifier' + autoload :Resources, 'action_controller/routing/resources' autoload :SessionManagement, 'action_controller/base/session_management' + autoload :TestCase, 'action_controller/testing/test_case' + autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter' + autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter' require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index 7111733d0d..d9af7add5f 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -1,7 +1,7 @@ require "action_controller/testing/process" module ActionController - module TestProcess2 + module TestProcess # Executes a request simulating GET HTTP method and set/volley the response def get(action, parameters = nil, session = nil, flash = nil) @@ -60,7 +60,7 @@ module ActionController options.update(:only_path => true, :action => action) url = ActionController::UrlRewriter.new(@request, parameters) - @request.set_REQUEST_URI(url.rewrite(options)) + @request.request_uri = url.rewrite(options) end end diff --git a/actionpack/test/abstract_unit2.rb b/actionpack/test/abstract_unit2.rb index c1e2631ac2..b95bfa0202 100644 --- a/actionpack/test/abstract_unit2.rb +++ b/actionpack/test/abstract_unit2.rb @@ -2,14 +2,6 @@ $:.unshift(File.dirname(__FILE__) + '/../lib') $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') $:.unshift(File.dirname(__FILE__) + '/lib') -# HAX -module ActionController - -end - -# TestCase -# include TestProcess2 - require 'test/unit' require 'active_support' @@ -17,16 +9,13 @@ require 'active_support/core/all' require 'active_support/test_case' require 'action_controller/abstract' require 'action_controller/new_base' -require 'action_controller/new_base/base' -require 'action_controller/new_base/renderer' # HAX -require 'action_controller' require 'fixture_template' +require 'action_controller/testing/process2' require 'action_view/test_case' FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') module ActionController - autoload :TestProcess2, 'action_controller/testing/process2' class ActionControllerError < StandardError #:nodoc: end @@ -158,7 +147,7 @@ module ActionController Base.view_paths = FIXTURE_LOAD_PATH class TestCase - include TestProcess2 + include TestProcess setup do ActionController::Routing::Routes.draw do |map| map.connect ':controller/:action/:id' -- cgit v1.2.3 From ad2a1b5cb1afb0ea810cfdcac2ba1be95c55f1aa Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 1 May 2009 18:17:08 -0700 Subject: Get render :inline working --- actionpack/lib/action_controller/new_base/layouts.rb | 2 +- actionpack/lib/action_controller/new_base/renderer.rb | 4 ++++ actionpack/lib/action_controller/testing/process2.rb | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb index a8e0809ac6..79abe40389 100644 --- a/actionpack/lib/action_controller/new_base/layouts.rb +++ b/actionpack/lib/action_controller/new_base/layouts.rb @@ -13,7 +13,7 @@ module ActionController # render :text => ..., :layout => ... # or # render :anything_else - if !options.key?(:text) || options.key?(:layout) + if (!options.key?(:text) && !options.key?(:inline)) || options.key?(:layout) options[:_layout] = options.key?(:layout) ? _layout_for_option(options[:layout]) : _default_layout end diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index f21fd746b7..4c4a74979b 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -17,6 +17,10 @@ module ActionController if options.key?(:text) options[:_template] = ActionView::TextTemplate.new(_text(options)) template = nil + elsif options.key?(:inline) + handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") + template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) + options[:_template] = template elsif options.key?(:template) options[:_template_name] = options[:template] elsif options.key?(:action) diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index d9af7add5f..67b5afb9c5 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -49,7 +49,7 @@ module ActionController @request.session = ActionController::TestSession.new(session) unless session.nil? @request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash build_request_uri(action, parameters) - + @controller.params.merge!(parameters) # Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest @controller.process_with_test(@request, @response) end -- cgit v1.2.3 From 72160d9f89481ea60c8268ff026099f07b1e5ed6 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Sat, 2 May 2009 02:15:09 -0700 Subject: Implement FooController.action(:name) * Rails actions are now Rack endpoints, and can be retrieved via FooController.action(name) and called with an env * Updated some tests that relied on the old internal #process/#call implementation --- actionpack/lib/action_controller/base/base.rb | 27 ++++++--------- actionpack/lib/action_controller/new_base/http.rb | 13 +++++-- .../lib/action_controller/routing/route_set.rb | 2 +- .../lib/action_controller/testing/process.rb | 4 +++ actionpack/test/controller/filters_test.rb | 3 +- actionpack/test/controller/helper_test.rb | 40 +++++++++++++++------- actionpack/test/new_base/test_helper.rb | 2 +- 7 files changed, 57 insertions(+), 34 deletions(-) diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb index 99b5963891..243b7f8ae3 100644 --- a/actionpack/lib/action_controller/base/base.rb +++ b/actionpack/lib/action_controller/base/base.rb @@ -370,18 +370,18 @@ module ActionController #:nodoc: attr_reader :template class << self - def call(env) - # HACK: For global rescue to have access to the original request and response - request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env) - response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new - process(request, response) - end - - # Factory for the standard create, process loop where the controller is discarded after processing. - def process(request, response) #:nodoc: - new.process(request, response) + def action(name = nil) + @actions ||= {} + @actions[name] ||= proc do |env| + controller = new + # HACK: For global rescue to have access to the original request and response + request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env) + response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new + controller.action_name = name && name.to_s + controller.process(request, response).to_a + end end - + # Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController". def controller_class_name @controller_class_name ||= name.demodulize @@ -518,7 +518,6 @@ module ActionController #:nodoc: assign_shortcuts(request, response) initialize_template_class(response) initialize_current_url - assign_names log_processing send(method, *arguments) @@ -883,10 +882,6 @@ module ActionController #:nodoc: @performed_render || @performed_redirect end - def assign_names - @action_name = (params['action'] || 'index') - end - def reset_variables_added_to_assigns @template.instance_variable_set("@assigns_added", nil) end diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb index f663900944..b7e3bfaa7e 100644 --- a/actionpack/lib/action_controller/new_base/http.rb +++ b/actionpack/lib/action_controller/new_base/http.rb @@ -39,13 +39,20 @@ module ActionController end # :api: private - def call(env) + def call(name, env) @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new - process(@_request.parameters[:action]) + process(name) @_response.body = response_body @_response.prepare! - self + to_rack + end + + def self.action(name) + @actions ||= {} + @actions[name] ||= proc do |env| + new.call(name, env) + end end # :api: private diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb index 70cd1f642d..45ad8a3a3b 100644 --- a/actionpack/lib/action_controller/routing/route_set.rb +++ b/actionpack/lib/action_controller/routing/route_set.rb @@ -430,7 +430,7 @@ module ActionController def call(env) request = ActionDispatch::Request.new(env) app = Routing::Routes.recognize(request) - app.call(env).to_a + app.action(request.parameters[:action] || 'index').call(env) end def recognize(request) diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb index 8315a160ad..3aad94cc10 100644 --- a/actionpack/lib/action_controller/testing/process.rb +++ b/actionpack/lib/action_controller/testing/process.rb @@ -131,7 +131,11 @@ module ActionController #:nodoc: @request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash build_request_uri(action, parameters) + @request.env["action_controller.rescue.request"] = @request + @request.env["action_controller.rescue.request"] = @response + Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest + @controller.action_name = action.to_s @controller.process(@request, @response) end diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index 9e74538310..3b113131ae 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -602,8 +602,9 @@ class FilterTest < Test::Unit::TestCase def test_dynamic_dispatch %w(foo bar baz).each do |action| request = ActionController::TestRequest.new + request.env["action_controller.rescue.request"] = request request.query_parameters[:choose] = action - response = DynamicDispatchController.process(request, ActionController::TestResponse.new) + response = DynamicDispatchController.action.call(request.env).last assert_equal action, response.body end end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 58addc123d..19cd5f4db2 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -101,20 +101,30 @@ class HelperTest < Test::Unit::TestCase assert master_helper_methods.include?('delegate_attr=') end - def test_helper_for_nested_controller + def call_controller(klass, action) request = ActionController::TestRequest.new - response = ActionController::TestResponse.new - request.action = 'render_hello_world' + request.env["action_controller.rescue.request"] = request + klass.action(action).call(request.env) + end - assert_equal 'hello: Iz guuut!', Fun::GamesController.process(request, response).body + def test_helper_for_nested_controller + assert_equal 'hello: Iz guuut!', + call_controller(Fun::GamesController, "render_hello_world").last.body + # request = ActionController::TestRequest.new + # request.env["action_controller.rescue.request"] = request + # + # resp = Fun::GamesController.action(:render_hello_world).call(request.env) + # assert_equal 'hello: Iz guuut!', resp.last.body end def test_helper_for_acronym_controller - request = ActionController::TestRequest.new - response = ActionController::TestResponse.new - request.action = 'test' - - assert_equal 'test: baz', Fun::PdfController.process(request, response).body + assert_equal "test: baz", call_controller(Fun::PdfController, "test").last.body + # + # request = ActionController::TestRequest.new + # response = ActionController::TestResponse.new + # request.action = 'test' + # + # assert_equal 'test: baz', Fun::PdfController.process(request, response).body end def test_all_helpers @@ -204,6 +214,12 @@ class IsolatedHelpersTest < Test::Unit::TestCase end end + def call_controller(klass, action) + request = ActionController::TestRequest.new + request.env["action_controller.rescue.request"] = request + klass.action(action).call(request.env) + end + def setup @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @@ -211,14 +227,14 @@ class IsolatedHelpersTest < Test::Unit::TestCase end def test_helper_in_a - assert_raise(ActionView::TemplateError) { A.process(@request, @response) } + assert_raise(ActionView::TemplateError) { call_controller(A, "index") } end def test_helper_in_b - assert_equal 'B', B.process(@request, @response).body + assert_equal 'B', call_controller(B, "index").last.body end def test_helper_in_c - assert_equal 'C', C.process(@request, @response).body + assert_equal 'C', call_controller(C, "index").last.body end end diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 547eb1ef72..78662dc989 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -66,7 +66,7 @@ class Rack::TestCase < ActiveSupport::TestCase end def assert_body(body) - assert_equal body, last_response.body + assert_equal body, Array.wrap(last_response.body).join end def self.assert_body(body) -- cgit v1.2.3 From 9047c9809deeb1aaa3735472287265720e5cd37f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 2 May 2009 15:30:00 -0700 Subject: Fix implicit ordering expectation --- actionpack/test/dispatch/test_request_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb index 19b5e2988b..5da02b2ea6 100644 --- a/actionpack/test/dispatch/test_request_test.rb +++ b/actionpack/test/dispatch/test_request_test.rb @@ -40,6 +40,6 @@ class TestRequestTest < ActiveSupport::TestCase req.cookies["login"] = "XJ-122" assert_equal({"user_name" => "david", "login" => "XJ-122"}, req.cookies) - assert_equal "login=XJ-122; user_name=david;", req.env["HTTP_COOKIE"] + assert_equal %w(login=XJ-122 user_name=david), req.env["HTTP_COOKIE"].split(/; ?/).sort end end -- cgit v1.2.3 From 49ed45213607ed6ce7e6c13c319bf55f916a0ac4 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 7 May 2009 18:27:50 -0700 Subject: Defer rake/contrib/sshpublisher require so basic tasks don't need the full rake gem --- activeresource/Rakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/activeresource/Rakefile b/activeresource/Rakefile index bf7bbb0201..c3cde26b6c 100644 --- a/activeresource/Rakefile +++ b/activeresource/Rakefile @@ -4,7 +4,6 @@ require 'rake/testtask' require 'rake/rdoctask' require 'rake/packagetask' require 'rake/gempackagetask' -require 'rake/contrib/sshpublisher' require File.join(File.dirname(__FILE__), 'lib', 'active_resource', 'version') @@ -117,12 +116,14 @@ end desc "Publish the beta gem" task :pgem => [:package] do + require 'rake/contrib/sshpublisher' Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload `ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'` end desc "Publish the API documentation" task :pdoc => [:rdoc] do + require 'rake/contrib/sshpublisher' Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ar", "doc").upload end -- cgit v1.2.3 From 4817bf94d135c44ddfae1a30acb15de989e3c86c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 7 May 2009 18:39:03 -0700 Subject: Check for date/time methods that moved upstream in 1.9 --- activesupport/lib/active_support/core_ext/date/calculations.rb | 4 ++-- activesupport/lib/active_support/core_ext/date_time/conversions.rb | 6 +++--- activesupport/lib/active_support/core_ext/time/conversions.rb | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 04a32edefd..1fe4ffb8e1 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -132,7 +132,7 @@ class Date # Short-hand for years_since(1) def next_year years_since(1) - end + end unless method_defined?(:next_year) # Short-hand for months_ago(1) def last_month @@ -142,7 +142,7 @@ class Date # Short-hand for months_since(1) def next_month months_since(1) - end + end unless method_defined?(:next_month) # Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00) def beginning_of_week diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index ddfa8d610d..5f01bc4fd6 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -58,7 +58,7 @@ class DateTime # Converts self to a Ruby Date object; time portion is discarded def to_date ::Date.new(year, month, day) - end + end unless method_defined?(:to_date) # Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class # If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time @@ -69,12 +69,12 @@ class DateTime # To be able to keep Times, Dates and DateTimes interchangeable on conversions def to_datetime self - end + end unless method_defined?(:to_datetime) # Converts datetime to an appropriate format for use in XML def xmlschema strftime("%Y-%m-%dT%H:%M:%S%Z") - end if RUBY_VERSION < '1.9' + end unless method_defined?(:xmlschema) # Converts self to a floating-point number of seconds since the Unix epoch def to_f diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb index 94e01597a9..6d9c080442 100644 --- a/activesupport/lib/active_support/core_ext/time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/time/conversions.rb @@ -69,7 +69,7 @@ class Time # In this case, it simply returns +self+. def to_time self - end + end unless method_defined?(:to_time) # Converts a Time instance to a Ruby DateTime instance, preserving UTC offset. # -- cgit v1.2.3 From ef6f22ab2aadf619c993527150490d6d48a719c6 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Thu, 7 May 2009 01:03:52 +0100 Subject: honour inverse_of when preloading associations Signed-off-by: Michael Koziarski --- .../lib/active_record/association_preload.rb | 4 ++- .../associations/inverse_associations_test.rb | 33 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index e4ab69aa1b..967fff4d6f 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -126,6 +126,7 @@ module ActiveRecord association_proxy = parent_record.send(reflection_name) association_proxy.loaded association_proxy.target.push(*[associated_record].flatten) + association_proxy.__send__(:set_inverse_instance, associated_record, parent_record) end end @@ -152,7 +153,8 @@ module ActiveRecord seen_keys[associated_record[key].to_s] = true mapped_records = id_to_record_map[associated_record[key].to_s] mapped_records.each do |mapped_record| - mapped_record.send("set_#{reflection_name}_target", associated_record) + association_proxy = mapped_record.send("set_#{reflection_name}_target", associated_record) + association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record) end end end diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb index 616f8dfbbe..d123837efd 100644 --- a/activerecord/test/cases/associations/inverse_associations_test.rb +++ b/activerecord/test/cases/associations/inverse_associations_test.rb @@ -94,6 +94,17 @@ class InverseHasOneTests < ActiveRecord::TestCase assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" end + + def test_parent_instance_should_be_shared_with_eager_loaded_child_on_find + m = Man.find(:first, :include => :face) + f = m.face + assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" + m.name = 'Bongo' + assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" + f.man.name = 'Mungo' + assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" + end + def test_parent_instance_should_be_shared_with_newly_built_child m = Man.find(:first) f = m.build_face(:description => 'haunted') @@ -136,6 +147,18 @@ class InverseHasManyTests < ActiveRecord::TestCase end end + def test_parent_instance_should_be_shared_with_eager_loaded_children + m = Man.find(:first, :include => :interests) + is = m.interests + is.each do |i| + assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" + m.name = 'Bongo' + assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" + i.man.name = 'Mungo' + assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance" + end + end + def test_parent_instance_should_be_shared_with_newly_built_child m = Man.find(:first) i = m.interests.build(:topic => 'Industrial Revolution Re-enactment') @@ -188,6 +211,16 @@ class InverseBelongsToTests < ActiveRecord::TestCase assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" end + def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find + f = Face.find(:first, :include => :man) + m = f.man + assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" + f.description = 'gormless' + assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" + m.face.description = 'pleasing' + assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" + end + def test_child_instance_should_be_shared_with_newly_built_parent f = Face.find(:first) m = f.build_man(:name => 'Charles') -- cgit v1.2.3 From 235775de291787bba6b7bc3c58e791216c3b5090 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Thu, 7 May 2009 01:43:15 +0100 Subject: honour :inverse_of for joins based include Signed-off-by: Michael Koziarski --- activerecord/lib/active_record/associations.rb | 10 ++++++-- .../associations/inverse_associations_test.rb | 28 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 0952b087d1..2928b0bf83 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1916,21 +1916,27 @@ module ActiveRecord return nil if record.id.to_s != join.parent.record_id(row).to_s or row[join.aliased_primary_key].nil? association = join.instantiate(row) collection.target.push(association) + collection.__send__(:set_inverse_instance, association, record) when :has_one return if record.id.to_s != join.parent.record_id(row).to_s return if record.instance_variable_defined?("@#{join.reflection.name}") association = join.instantiate(row) unless row[join.aliased_primary_key].nil? - record.send("set_#{join.reflection.name}_target", association) + set_target_and_inverse(join, association, record) when :belongs_to return if record.id.to_s != join.parent.record_id(row).to_s or row[join.aliased_primary_key].nil? association = join.instantiate(row) - record.send("set_#{join.reflection.name}_target", association) + set_target_and_inverse(join, association, record) else raise ConfigurationError, "unknown macro: #{join.reflection.macro}" end return association end + def set_target_and_inverse(join, association, record) + association_proxy = record.send("set_#{join.reflection.name}_target", association) + association_proxy.__send__(:set_inverse_instance, association, record) + end + class JoinBase # :nodoc: attr_reader :active_record, :table_joins delegate :table_name, :column_names, :primary_key, :reflections, :sanitize_sql, :to => :active_record diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb index d123837efd..47f83db112 100644 --- a/activerecord/test/cases/associations/inverse_associations_test.rb +++ b/activerecord/test/cases/associations/inverse_associations_test.rb @@ -103,6 +103,14 @@ class InverseHasOneTests < ActiveRecord::TestCase assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" f.man.name = 'Mungo' assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" + + m = Man.find(:first, :include => :face, :order => 'faces.id') + f = m.face + assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" + m.name = 'Bongo' + assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" + f.man.name = 'Mungo' + assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" end def test_parent_instance_should_be_shared_with_newly_built_child @@ -157,6 +165,17 @@ class InverseHasManyTests < ActiveRecord::TestCase i.man.name = 'Mungo' assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance" end + + m = Man.find(:first, :include => :interests, :order => 'interests.id') + is = m.interests + is.each do |i| + assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" + m.name = 'Bongo' + assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" + i.man.name = 'Mungo' + assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance" + end + end def test_parent_instance_should_be_shared_with_newly_built_child @@ -219,6 +238,15 @@ class InverseBelongsToTests < ActiveRecord::TestCase assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" m.face.description = 'pleasing' assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" + + + f = Face.find(:first, :include => :man, :order => 'men.id') + m = f.man + assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" + f.description = 'gormless' + assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" + m.face.description = 'pleasing' + assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" end def test_child_instance_should_be_shared_with_newly_built_parent -- cgit v1.2.3 From 9e0cfdb7f951c0446cdfd3b2cc26443712fe657a Mon Sep 17 00:00:00 2001 From: Ken Collins Date: Sat, 9 May 2009 18:35:31 -0400 Subject: ActiveSupport::OrderedHash#to_a method returns an ordered set of arrays. Matches ruby1.9's Hash#to_a. Signed-off-by: Michael Koziarski [#2629 state:committed] --- activesupport/lib/active_support/ordered_hash.rb | 4 ++++ activesupport/test/ordered_hash_test.rb | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index fed8094a24..33fd2a29b9 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -57,6 +57,10 @@ module ActiveSupport self end + def to_a + @keys.map { |key| [ key, self[key] ] } + end + def each_key @keys.each { |key| yield key } end diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index 7cd8c8a8f4..6fccbbdc41 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -51,6 +51,10 @@ class OrderedHashTest < Test::Unit::TestCase assert_same @ordered_hash, @ordered_hash.to_hash end + def test_to_a + assert_equal @keys.zip(@values), @ordered_hash.to_a + end + def test_has_key assert_equal true, @ordered_hash.has_key?('blue') assert_equal true, @ordered_hash.key?('blue') -- cgit v1.2.3 From 026b78f9076216990bddb1aa5d83d23a647c02a5 Mon Sep 17 00:00:00 2001 From: Anthony Crumley Date: Mon, 4 May 2009 09:49:43 -0500 Subject: Fixed eager load error on find with include => [:table_name] and hash conditions like {:table_name => {:column => 'value'}} Signed-off-by: Michael Koziarski --- activerecord/lib/active_record/associations.rb | 20 ++++++++++++++++---- activerecord/test/cases/associations/eager_test.rb | 12 ++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 2928b0bf83..781a0290e8 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1671,17 +1671,29 @@ module ActiveRecord string.scan(/([\.a-zA-Z_]+).?\./).flatten end + def tables_in_hash(hash) + return [] if hash.blank? + tables = hash.map do |key, value| + if value.is_a?(Hash) + key.to_s + else + tables_in_string(key) if key.is_a?(String) + end + end + tables.flatten.compact + end + def conditions_tables(options) # look in both sets of conditions conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| case cond when nil then all - when Array then all << cond.first - when Hash then all << cond.keys - else all << cond + when Array then all << tables_in_string(cond.first) + when Hash then all << tables_in_hash(cond) + else all << tables_in_string(cond) end end - tables_in_string(conditions.join(' ')) + conditions.flatten end def order_tables(options) diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 40723814c5..d23f86b700 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -223,6 +223,18 @@ class EagerAssociationTest < ActiveRecord::TestCase end end + def test_eager_association_loading_with_belongs_to_and_conditions_hash + comments = [] + assert_nothing_raised do + comments = Comment.find(:all, :include => :post, :conditions => {:posts => {:id => 4}}, :limit => 3, :order => 'comments.id') + end + assert_equal 3, comments.length + assert_equal [5,6,7], comments.collect { |c| c.id } + assert_no_queries do + comments.first.post + end + end + def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id') assert_nothing_raised do -- cgit v1.2.3 From 9010ed27559ed5ab89ea71b4b16f4c8e56d03dbb Mon Sep 17 00:00:00 2001 From: Mike Breen Date: Sun, 10 May 2009 15:02:00 +1200 Subject: Allow you to pass :all_blank to :reject_if option to automatically create a Proc that will reject any record with blank attributes. --- activerecord/lib/active_record/nested_attributes.rb | 11 ++++++++++- activerecord/test/cases/nested_attributes_test.rb | 18 +++++++++++++++++- activerecord/test/models/pirate.rb | 2 ++ activerecord/test/schema/schema.rb | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index e3122d195a..dfad2901c5 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -180,10 +180,14 @@ module ActiveRecord # and the Proc should return either +true+ or +false+. When no Proc # is specified a record will be built for all attribute hashes that # do not have a _delete 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. # # Examples: # # creates avatar_attributes= # accepts_nested_attributes_for :avatar, :reject_if => proc { |attributes| attributes['name'].blank? } + # # creates avatar_attributes= + # accepts_nested_attributes_for :avatar, :reject_if => :all_blank # # creates avatar_attributes= and posts_attributes= # accepts_nested_attributes_for :avatar, :posts, :allow_destroy => true def accepts_nested_attributes_for(*attr_names) @@ -201,7 +205,12 @@ module ActiveRecord end reflection.options[:autosave] = true - self.reject_new_nested_attributes_procs[association_name.to_sym] = options[:reject_if] + + self.reject_new_nested_attributes_procs[association_name.to_sym] = if options[:reject_if] == :all_blank + proc { |attributes| attributes.all? {|k,v| v.blank?} } + else + options[:reject_if] + end # def pirate_attributes=(attributes) # assign_nested_attributes_for_one_to_one_association(:pirate, attributes, false) diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index cd6277c24b..f1741ed54d 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -31,11 +31,27 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end def test_should_add_a_proc_to_reject_new_nested_attributes_procs - [:parrots, :birds].each do |name| + [:parrots, :birds, :birds_with_reject_all_blank].each do |name| assert_instance_of Proc, Pirate.reject_new_nested_attributes_procs[name] end 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 => ''}] + pirate.save! + + assert pirate.birds_with_reject_all_blank.empty? + end + + def test_should_build_a_new_record_if_reject_all_blank_does_not_return_false + pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{:name => 'Tweetie', :color => ''}] + pirate.save! + + assert_equal 1, pirate.birds_with_reject_all_blank.count + end + def test_should_raise_an_ArgumentError_for_non_existing_associations assert_raise_with_message ArgumentError, "No association found for name `honesty'. Has it been defined yet?" do Pirate.accepts_nested_attributes_for :honesty diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index 238917bf30..acf53fce8b 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -28,11 +28,13 @@ class Pirate < ActiveRecord::Base :after_add => proc {|p,b| p.ship_log << "after_adding_proc_bird_#{b.id || ''}"}, :before_remove => proc {|p,b| p.ship_log << "before_removing_proc_bird_#{b.id}"}, :after_remove => proc {|p,b| p.ship_log << "after_removing_proc_bird_#{b.id}"} + has_many :birds_with_reject_all_blank, :class_name => "Bird" accepts_nested_attributes_for :parrots, :birds, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } accepts_nested_attributes_for :parrots_with_method_callbacks, :parrots_with_proc_callbacks, :birds_with_method_callbacks, :birds_with_proc_callbacks, :allow_destroy => true + accepts_nested_attributes_for :birds_with_reject_all_blank, :reject_if => :all_blank validates_presence_of :catchphrase diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 3b0e17c867..6fb918c60e 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -57,6 +57,7 @@ ActiveRecord::Schema.define do create_table :birds, :force => true do |t| t.string :name + t.string :color t.integer :pirate_id end -- cgit v1.2.3 From 2e7409f035236c719c5b1567c4bb3e65a5e543bc Mon Sep 17 00:00:00 2001 From: Alexander Dymo Date: Thu, 7 May 2009 03:19:17 +0300 Subject: Change spelling of Kyev timezone to Kyiv [#2613 state:resolved] --- activesupport/CHANGELOG | 2 ++ activesupport/lib/active_support/values/time_zone.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index ca5ab13a46..032f0fb9c1 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Change spelling of Kyev timezone to Kyiv #2613 [Alexander Dymo] + * Add ActiveSupport.parse_json_times to disable time parsing in JSON backends that don't support it or don't need it. [rick] * Add pluggable JSON backends with support for the JSON gem. [rick] diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index e2d759aa50..b37dae1c2a 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -92,7 +92,7 @@ module ActiveSupport "Bucharest" => "Europe/Bucharest", "Cairo" => "Africa/Cairo", "Helsinki" => "Europe/Helsinki", - "Kyev" => "Europe/Kiev", + "Kyiv" => "Europe/Kiev", "Riga" => "Europe/Riga", "Sofia" => "Europe/Sofia", "Tallinn" => "Europe/Tallinn", @@ -336,7 +336,7 @@ module ActiveSupport "Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin", "Bern", "Rome", "Stockholm", "Vienna", "West Central Africa" ], - [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia", + [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyiv", "Riga", "Sofia", "Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk", "Jerusalem", "Harare", "Pretoria" ], [ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh", -- cgit v1.2.3 From 4932f7b38f72104819022abca0c952ba6f9888cb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 11 May 2009 19:08:13 +0200 Subject: Added db/seeds.rb as a default file for storing seed data for the database. Can be loaded with rake db:seed (or created alongside the db with db:setup). (This is also known as the "Stop Putting Gawd Damn Seed Data In Your Migrations" feature) [DHH] --- railties/CHANGELOG | 5 +++++ railties/Rakefile | 3 +++ railties/configs/seeds.rb | 7 +++++++ .../generators/applications/app/app_generator.rb | 5 +++++ railties/lib/tasks/databases.rake | 13 +++++++++++-- 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 railties/configs/seeds.rb diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 98e3a861e8..8e7dfb38cc 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,3 +1,8 @@ +*Edge* + +* Added db/seeds.rb as a default file for storing seed data for the database. Can be loaded with rake db:seed (or created alongside the db with db:setup). (This is also known as the "Stop Putting Gawd Damn Seed Data In Your Migrations" feature) [DHH] + + *2.3.2 [Final] (March 15, 2009)* * Remove outdated script/plugin options [Pratik Naik] diff --git a/railties/Rakefile b/railties/Rakefile index 9cd102df0f..4247742664 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -200,11 +200,14 @@ task :copy_configs do cp "configs/locales/en.yml", "#{PKG_DESTINATION}/config/locales/en.yml" + cp "configs/seeds.rb", "#{PKG_DESTINATION}/db/seeds.rb" + cp "environments/boot.rb", "#{PKG_DESTINATION}/config/boot.rb" cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb" cp "environments/production.rb", "#{PKG_DESTINATION}/config/environments/production.rb" cp "environments/development.rb", "#{PKG_DESTINATION}/config/environments/development.rb" cp "environments/test.rb", "#{PKG_DESTINATION}/config/environments/test.rb" + end task :copy_binfiles do diff --git a/railties/configs/seeds.rb b/railties/configs/seeds.rb new file mode 100644 index 0000000000..3174d0cb8a --- /dev/null +++ b/railties/configs/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) +# Major.create(:name => 'Daley', :city => cities.first) diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb index 2c31d89538..c8c2239f34 100644 --- a/railties/lib/rails_generator/generators/applications/app/app_generator.rb +++ b/railties/lib/rails_generator/generators/applications/app/app_generator.rb @@ -125,6 +125,7 @@ class AppGenerator < Rails::Generator::Base create_database_configuration_file(m) create_routes_file(m) create_locale_file(m) + create_seeds_file(m) create_initializer_files(m) create_environment_files(m) end @@ -176,6 +177,10 @@ class AppGenerator < Rails::Generator::Base m.file "configs/routes.rb", "config/routes.rb" end + def create_seeds_file(m) + m.file "configs/seeds.rb", "db/seeds.rb" + end + def create_initializer_files(m) %w( backtrace_silencers diff --git a/railties/lib/tasks/databases.rake b/railties/lib/tasks/databases.rake index 9588fabb2d..cdab5d8bb0 100644 --- a/railties/lib/tasks/databases.rake +++ b/railties/lib/tasks/databases.rake @@ -156,8 +156,8 @@ namespace :db do Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby end - desc 'Drops and recreates the database from db/schema.rb for the current environment.' - task :reset => ['db:drop', 'db:create', 'db:schema:load'] + desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.' + task :reset => [ 'db:drop', 'db:setup' ] desc "Retrieves the charset for the current environment's database" task :charset => :environment do @@ -206,6 +206,15 @@ namespace :db do end end + desc 'Create the database, load the schema, and initialize with the seed data' + task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ] + + desc 'Load the seed data from db/seeds.rb' + task :seed => :environment do + seed_file = File.join(Rails.root, 'db', 'seeds.rb') + load(seed_file) if File.exist?(seed_file) + end + namespace :fixtures do desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures." task :load => :environment do -- cgit v1.2.3 From 030dfe3f831aacd60bbfa525dfac4cd5921b6530 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Mon, 11 May 2009 10:22:07 -0700 Subject: More community code review :) --- actionpack/lib/action_controller/abstract/base.rb | 3 +-- .../lib/action_controller/abstract/helpers.rb | 9 +-------- .../lib/action_controller/abstract/renderer.rb | 4 ++-- actionpack/lib/action_view/template/text.rb | 2 ++ .../abstract_controller_test.rb | 20 ++++++++++---------- .../test/abstract_controller/callbacks_test.rb | 18 +++++++++--------- actionpack/test/abstract_controller/helper_test.rb | 2 +- .../test/abstract_controller/layouts_test.rb | 22 +++++++++++----------- 8 files changed, 37 insertions(+), 43 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index 8a8e748c0e..ab9aed0b26 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -54,7 +54,6 @@ module AbstractController @_action_name = action_name process_action - self.response_obj[:body] = self.response_body self end @@ -71,7 +70,7 @@ module AbstractController # action_name is found. def process_action if respond_to?(action_name) then send(action_name) - elsif respond_to?(:action_missing, true) then send(:action_missing, action_name) + elsif respond_to?(:action_missing, true) then action_missing(action_name) end end diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb index 1f0b38417b..370e3a79ee 100644 --- a/actionpack/lib/action_controller/abstract/helpers.rb +++ b/actionpack/lib/action_controller/abstract/helpers.rb @@ -6,14 +6,7 @@ module AbstractController extlib_inheritable_accessor :master_helper_module self.master_helper_module = Module.new end - - # def self.included(klass) - # klass.class_eval do - # extlib_inheritable_accessor :master_helper_module - # self.master_helper_module = Module.new - # end - # end - + def _action_view @_action_view ||= begin av = super diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index 716b213c75..bed7f75b2f 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -20,13 +20,13 @@ module AbstractController self._view_paths ||= ActionView::PathSet.new end - + def _action_view @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) end def render(options = {}) - unless response_body.nil? + if response_body raise AbstractController::DoubleRenderError, "OMG" end diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 446c735ba3..8477115211 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -1,5 +1,7 @@ module ActionView #:nodoc: class TextTemplate < String #:nodoc: + + def identifier() self end def render(*) self end diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index c283a7319d..28f9ac5820 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -20,7 +20,7 @@ module AbstractController class TestBasic < ActiveSupport::TestCase test "dispatching works" do result = Me.process(:index) - assert_equal "Hello world", result.response_obj[:body] + assert_equal "Hello world", result.response_body end end @@ -69,27 +69,27 @@ module AbstractController class TestRenderer < ActiveSupport::TestCase test "rendering templates works" do result = Me2.process(:index) - assert_equal "Hello from index.erb", result.response_obj[:body] + assert_equal "Hello from index.erb", result.response_body end test "rendering passes ivars to the view" do result = Me2.process(:action_with_ivars) - assert_equal "Hello from index_with_ivars.erb", result.response_obj[:body] + assert_equal "Hello from index_with_ivars.erb", result.response_body end test "rendering with no template name" do result = Me2.process(:naked_render) - assert_equal "Hello from naked_render.erb", result.response_obj[:body] + assert_equal "Hello from naked_render.erb", result.response_body end test "rendering to a rack body" do result = Me2.process(:rendering_to_body) - assert_equal "Hello from naked_render.erb", result.response_obj[:body] + assert_equal "Hello from naked_render.erb", result.response_body end test "rendering to a string" do result = Me2.process(:rendering_to_string) - assert_equal "Hello from naked_render.erb", result.response_obj[:body] + assert_equal "Hello from naked_render.erb", result.response_body end end @@ -121,12 +121,12 @@ module AbstractController class TestPrefixedViews < ActiveSupport::TestCase test "templates are located inside their 'prefix' folder" do result = Me3.process(:index) - assert_equal "Hello from me3/index.erb", result.response_obj[:body] + assert_equal "Hello from me3/index.erb", result.response_body end test "templates included their format" do result = Me3.process(:formatted) - assert_equal "Hello from me3/formatted.html.erb", result.response_obj[:body] + assert_equal "Hello from me3/formatted.html.erb", result.response_body end end @@ -174,7 +174,7 @@ module AbstractController class TestLayouts < ActiveSupport::TestCase test "layouts are included" do result = Me4.process(:index) - assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_obj[:body] + assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_body end end @@ -211,7 +211,7 @@ module AbstractController class TestRespondToAction < ActiveSupport::TestCase def assert_dispatch(klass, body = "success", action = :index) - response = klass.process(action).response_obj[:body] + response = klass.process(action).response_body assert_equal body, response end diff --git a/actionpack/test/abstract_controller/callbacks_test.rb b/actionpack/test/abstract_controller/callbacks_test.rb index 5fce30f478..7137129823 100644 --- a/actionpack/test/abstract_controller/callbacks_test.rb +++ b/actionpack/test/abstract_controller/callbacks_test.rb @@ -22,7 +22,7 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "basic callbacks work" do result = Callback1.process(:index) - assert_equal "Hello world", result.response_obj[:body] + assert_equal "Hello world", result.response_body end end @@ -53,7 +53,7 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "before_filter works" do result = Callback2.process(:index) - assert_equal "Hello world", result.response_obj[:body] + assert_equal "Hello world", result.response_body end test "after_filter works" do @@ -84,7 +84,7 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "before_filter works with procs" do result = Callback3.process(:index) - assert_equal "Hello world", result.response_obj[:body] + assert_equal "Hello world", result.response_body end test "after_filter works with procs" do @@ -119,12 +119,12 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "when :only is specified, a before filter is triggered on that action" do result = CallbacksWithConditions.process(:index) - assert_equal "Hello, World", result.response_obj[:body] + assert_equal "Hello, World", result.response_body end test "when :only is specified, a before filter is not triggered on other actions" do result = CallbacksWithConditions.process(:sekrit_data) - assert_equal "true", result.response_obj[:body] + assert_equal "true", result.response_body end test "when :except is specified, an after filter is not triggered on that action" do @@ -159,12 +159,12 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "when :only is specified with an array, a before filter is triggered on that action" do result = CallbacksWithArrayConditions.process(:index) - assert_equal "Hello, World", result.response_obj[:body] + assert_equal "Hello, World", result.response_body end test "when :only is specified with an array, a before filter is not triggered on other actions" do result = CallbacksWithArrayConditions.process(:sekrit_data) - assert_equal "true", result.response_obj[:body] + assert_equal "true", result.response_body end test "when :except is specified with an array, an after filter is not triggered on that action" do @@ -184,12 +184,12 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "when a callback is modified in a child with :only, it works for the :only action" do result = ChangedConditions.process(:index) - assert_equal "Hello world", result.response_obj[:body] + assert_equal "Hello world", result.response_body end test "when a callback is modified in a child with :only, it does not work for other actions" do result = ChangedConditions.process(:not_index) - assert_equal "", result.response_obj[:body] + assert_equal "", result.response_body end end diff --git a/actionpack/test/abstract_controller/helper_test.rb b/actionpack/test/abstract_controller/helper_test.rb index 6284fa4f70..15c89b4d24 100644 --- a/actionpack/test/abstract_controller/helper_test.rb +++ b/actionpack/test/abstract_controller/helper_test.rb @@ -35,7 +35,7 @@ module AbstractController class TestHelpers < ActiveSupport::TestCase def test_helpers result = MyHelpers1.process(:index) - assert_equal "Hello World : Included", result.response_obj[:body] + assert_equal "Hello World : Included", result.response_body end end diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb index 078e0037a8..961e7ce6d3 100644 --- a/actionpack/test/abstract_controller/layouts_test.rb +++ b/actionpack/test/abstract_controller/layouts_test.rb @@ -152,12 +152,12 @@ module AbstractControllerTests class TestBase < ActiveSupport::TestCase test "when no layout is specified, and no default is available, render without a layout" do result = Blank.process(:index) - assert_equal "Hello blank!", result.response_obj[:body] + assert_equal "Hello blank!", result.response_body end test "when layout is specified as a string, render with that layout" do result = WithString.process(:index) - assert_equal "With String Hello string!", result.response_obj[:body] + assert_equal "With String Hello string!", result.response_body end test "when layout is specified as a string, but the layout is missing, raise an exception" do @@ -166,22 +166,22 @@ module AbstractControllerTests test "when layout is specified as false, do not use a layout" do result = WithFalseLayout.process(:index) - assert_equal "Hello false!", result.response_obj[:body] + assert_equal "Hello false!", result.response_body end test "when layout is specified as nil, do not use a layout" do result = WithNilLayout.process(:index) - assert_equal "Hello nil!", result.response_obj[:body] + assert_equal "Hello nil!", result.response_body end test "when layout is specified as a symbol, call the requested method and use the layout returned" do result = WithSymbol.process(:index) - assert_equal "OMGHI2U Hello symbol!", result.response_obj[:body] + assert_equal "OMGHI2U Hello symbol!", result.response_body end test "when layout is specified as a symbol and the method returns nil, don't use a layout" do result = WithSymbolReturningNil.process(:index) - assert_equal "Hello nilz!", result.response_obj[:body] + assert_equal "Hello nilz!", result.response_body end test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do @@ -194,28 +194,28 @@ module AbstractControllerTests test "when a child controller does not have a layout, use the parent controller layout" do result = WithStringChild.process(:index) - assert_equal "With String Hello string!", result.response_obj[:body] + assert_equal "With String Hello string!", result.response_body end test "when a child controller has specified a layout, use that layout and not the parent controller layout" do result = WithStringOverriddenChild.process(:index) - assert_equal "With Override Hello string!", result.response_obj[:body] + assert_equal "With Override Hello string!", result.response_body end test "when a child controller has an implied layout, use that layout and not the parent controller layout" do result = WithStringImpliedChild.process(:index) - assert_equal "With Implied Hello string!", result.response_obj[:body] + assert_equal "With Implied Hello string!", result.response_body end test "when a child controller specifies layout nil, do not use the parent layout" do result = WithNilChild.process(:index) - assert_equal "Hello string!", result.response_obj[:body] + assert_equal "Hello string!", result.response_body end test "when a grandchild has no layout specified, the child has an implied layout, and the " \ "parent has specified a layout, use the child controller layout" do result = WithChildOfImplied.process(:index) - assert_equal "With Implied Hello string!", result.response_obj[:body] + assert_equal "With Implied Hello string!", result.response_body end test "raises an exception when specifying layout true" do -- cgit v1.2.3 From a2f3684cecb361db2bf5f7ec0b6de0603868ffd5 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 11 May 2009 10:57:59 -0700 Subject: Ported fresh_when into a ConditionalGet module --- actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 1 + .../action_controller/new_base/conditional_get.rb | 42 +++++++++++++++++++ .../lib/action_controller/new_base/testing.rb | 1 + actionpack/test/new_base/etag_test.rb | 47 ++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 actionpack/lib/action_controller/new_base/conditional_get.rb create mode 100644 actionpack/test/new_base/etag_test.rb diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 7098b812f6..8a7de1476c 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,5 +1,6 @@ module ActionController autoload :Base, "action_controller/new_base/base" + autoload :ConditionalGet, "action_controller/new_base/conditional_get" autoload :HideActions, "action_controller/new_base/hide_actions" autoload :Http, "action_controller/new_base/http" autoload :Layouts, "action_controller/new_base/layouts" diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 8af6ffbc92..40f507b6e7 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -10,6 +10,7 @@ module ActionController use ActionController::UrlFor use ActionController::Renderer use ActionController::Layouts + use ActionController::ConditionalGet # Legacy modules include SessionManagement diff --git a/actionpack/lib/action_controller/new_base/conditional_get.rb b/actionpack/lib/action_controller/new_base/conditional_get.rb new file mode 100644 index 0000000000..16104c51fc --- /dev/null +++ b/actionpack/lib/action_controller/new_base/conditional_get.rb @@ -0,0 +1,42 @@ +module ActionController + module ConditionalGet + + # Sets the etag, last_modified, or both on the response and renders a + # "304 Not Modified" response if the request is already fresh. + # + # Parameters: + # * :etag + # * :last_modified + # * :public By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches). + # + # Example: + # + # def show + # @article = Article.find(params[:id]) + # fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true) + # end + # + # This will render the show template if the request isn't sending a matching etag or + # If-Modified-Since header and just a "304 Not Modified" response if there's a match. + # + def fresh_when(options) + options.assert_valid_keys(:etag, :last_modified, :public) + + response.etag = options[:etag] if options[:etag] + response.last_modified = options[:last_modified] if options[:last_modified] + + if options[:public] + cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip } + cache_control.delete("private") + cache_control.delete("no-cache") + cache_control << "public" + response.headers["Cache-Control"] = cache_control.join(', ') + end + + if request.fresh?(response) + head :not_modified + end + end + + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index 428f339b3d..181c5c0ecd 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -7,6 +7,7 @@ module ActionController @_response = response ret = process(request.parameters[:action]) @_response.body = self.response_body + @_response.prepare! set_test_assigns ret end diff --git a/actionpack/test/new_base/etag_test.rb b/actionpack/test/new_base/etag_test.rb new file mode 100644 index 0000000000..7af5febfb3 --- /dev/null +++ b/actionpack/test/new_base/etag_test.rb @@ -0,0 +1,47 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") + +module Etags + + class BasicController < ActionController::Base + + self.view_paths = [ActionView::Template::FixturePath.new( + "etags/basic/base.html.erb" => "Hello from without_layout.html.erb", + "layouts/etags.html.erb" => "teh <%= yield %> tagz" + )] + + def without_layout + render :action => "base" + end + + def with_layout + render :action => "base", :layout => "etag" + end + + end + + class TestBasic < SimpleRouteCase + describe "Rendering without any special etag options returns an etag that is an MD5 hash of its text" + + test "an action without a layout" do + get "/etags/basic/without_layout" + body = "Hello from without_layout.html.erb" + assert_body body + assert_header "Etag", etag_for(body) + assert_status 200 + end + + test "an action with a layout" do + get "/etags/basic/with_layout" + body = "teh Hello from without_layout.html.erb tagz" + assert_body body + assert_header "Etag", etag_for(body) + assert_status 200 + end + + def etag_for(text) + %("#{Digest::MD5.hexdigest(text)}") + end + end + + +end \ No newline at end of file -- cgit v1.2.3 From e1854e0b199fba352ddcaa58a3af168e8cc70e3a Mon Sep 17 00:00:00 2001 From: Douglas F Shearer Date: Thu, 7 May 2009 23:58:07 +0100 Subject: ActiveSupport::OrderedHash[1,2,3,4] creates an OrderedHash instead of a Hash. [#2615 state:committed] Signed-off-by: Jeremy Kemper --- activesupport/lib/active_support/ordered_hash.rb | 10 ++++++++++ activesupport/test/ordered_hash_test.rb | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index 33fd2a29b9..8d1c0f5160 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -10,6 +10,16 @@ module ActiveSupport @keys = [] end + def self.[](*args) + ordered_hash = new + args.each_with_index { |val,ind| + # Only every second value is a key. + next if ind % 2 != 0 + ordered_hash[val] = args[ind + 1] + } + ordered_hash + end + def initialize_copy(other) super # make a deep copy of keys diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index 6fccbbdc41..647938dd87 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -162,4 +162,10 @@ class OrderedHashTest < Test::Unit::TestCase def test_inspect assert @ordered_hash.inspect.include?(@hash.inspect) end + + def test_alternate_initialization + alternate = ActiveSupport::OrderedHash[1,2,3,4] + assert_kind_of ActiveSupport::OrderedHash, alternate + assert_equal [1, 3], alternate.keys + end end -- cgit v1.2.3 From c1d120a71e74aa3ccab6dc28a5406b87a51a69c1 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 11 May 2009 11:48:38 -0700 Subject: Don't run the action if callbacks are halted. In AbstractController, this means that response_body is not empty --- actionpack/lib/action_controller/abstract/callbacks.rb | 2 +- activesupport/lib/active_support/new_callbacks.rb | 2 +- activesupport/test/new_callbacks_test.rb | 14 +++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb index 5f1607940a..f3210a040a 100644 --- a/actionpack/lib/action_controller/abstract/callbacks.rb +++ b/actionpack/lib/action_controller/abstract/callbacks.rb @@ -2,7 +2,7 @@ module AbstractController module Callbacks setup do include ActiveSupport::NewCallbacks - define_callbacks :process_action + define_callbacks :process_action, "response_body" end def process_action diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index 2ae7b006c7..9316d6d2b6 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -316,7 +316,7 @@ module ActiveSupport each do |callback| method << callback.start(key, options) end - method << "yield self if block_given?" + method << "yield self if block_given? && !halted" reverse_each do |callback| method << callback.end(key, options) end diff --git a/activesupport/test/new_callbacks_test.rb b/activesupport/test/new_callbacks_test.rb index 8c887e1bf1..dec6106ac1 100644 --- a/activesupport/test/new_callbacks_test.rb +++ b/activesupport/test/new_callbacks_test.rb @@ -365,7 +365,7 @@ module NewCallbacksTest save_callback :after, :third - attr_reader :history + attr_reader :history, :saved def initialize @history = [] end @@ -390,7 +390,9 @@ module NewCallbacksTest end def save - _run_save_callbacks + _run_save_callbacks do + @saved = true + end end end @@ -400,6 +402,12 @@ module NewCallbacksTest terminator.save assert_equal ["first", "second", "third", "second", "first"], terminator.history end + + def test_block_never_called_if_terminated + obj = CallbackTerminator.new + obj.save + assert !obj.saved + end end class HyphenatedKeyTest < Test::Unit::TestCase @@ -407,6 +415,6 @@ module NewCallbacksTest obj = HyphenatedCallbacks.new obj.save assert_equal obj.stuff, "OMG" - end + end end end -- cgit v1.2.3 From 94ee9d245289a36207847a684b51dbd1c7a6a4eb Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 11 May 2009 12:04:43 -0700 Subject: Ported ConditionalGet to new Base --- actionpack/lib/action_controller/new_base/base.rb | 1 + .../action_controller/new_base/compatibility.rb | 3 + .../action_controller/new_base/conditional_get.rb | 91 +++++++++++++++++++++- actionpack/lib/action_controller/new_base/http.rb | 1 + .../lib/action_controller/new_base/testing.rb | 1 + actionpack/lib/action_view/template/text.rb | 2 + actionpack/test/controller/render_test.rb | 8 +- 7 files changed, 102 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 40f507b6e7..313b9a5e1f 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -14,6 +14,7 @@ module ActionController # Legacy modules include SessionManagement + include ActionDispatch::StatusCodes # Rails 2.x compatibility use ActionController::Rails2Compatibility diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index db471f7658..3b1a74ec0c 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -26,6 +26,9 @@ module ActionController if options.is_a?(Hash) && options.key?(:template) options[:template].sub!(/^\//, '') end + + options[:text] = nil if options[:nothing] == true + super end diff --git a/actionpack/lib/action_controller/new_base/conditional_get.rb b/actionpack/lib/action_controller/new_base/conditional_get.rb index 16104c51fc..e1407e671a 100644 --- a/actionpack/lib/action_controller/new_base/conditional_get.rb +++ b/actionpack/lib/action_controller/new_base/conditional_get.rb @@ -36,7 +36,96 @@ module ActionController if request.fresh?(response) head :not_modified end - end + end + + # Return a response that has no content (merely headers). The options + # argument is interpreted to be a hash of header names and values. + # This allows you to easily return a response that consists only of + # significant headers: + # + # head :created, :location => person_path(@person) + # + # It can also be used to return exceptional conditions: + # + # return head(:method_not_allowed) unless request.post? + # return head(:bad_request) unless valid_request? + # render + def head(*args) + if args.length > 2 + raise ArgumentError, "too many arguments to head" + elsif args.empty? + raise ArgumentError, "too few arguments to head" + end + options = args.extract_options! + status = interpret_status(args.shift || options.delete(:status) || :ok) + + options.each do |key, value| + headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s + end + + render :nothing => true, :status => status + end + + # Sets the etag and/or last_modified on the response and checks it against + # the client request. If the request doesn't match the options provided, the + # request is considered stale and should be generated from scratch. Otherwise, + # it's fresh and we don't need to generate anything and a reply of "304 Not Modified" is sent. + # + # Parameters: + # * :etag + # * :last_modified + # * :public By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches). + # + # Example: + # + # def show + # @article = Article.find(params[:id]) + # + # if stale?(:etag => @article, :last_modified => @article.created_at.utc) + # @statistics = @article.really_expensive_call + # respond_to do |format| + # # all the supported formats + # end + # end + # end + def stale?(options) + fresh_when(options) + !request.fresh?(response) + end + + # Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a "private" instruction, so that + # intermediate caches shouldn't cache the response. + # + # Examples: + # expires_in 20.minutes + # expires_in 3.hours, :public => true + # expires in 3.hours, 'max-stale' => 5.hours, :public => true + # + # This method will overwrite an existing Cache-Control header. + # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities. + def expires_in(seconds, options = {}) #:doc: + cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip } + + cache_control << "max-age=#{seconds}" + cache_control.delete("no-cache") + if options[:public] + cache_control.delete("private") + cache_control << "public" + else + cache_control << "private" + end + + # This allows for additional headers to be passed through like 'max-stale' => 5.hours + cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"} + + response.headers["Cache-Control"] = cache_control.join(', ') + end + + # Sets a HTTP 1.1 Cache-Control header of "no-cache" so no caching should occur by the browser or + # intermediate caches (like caching proxy servers). + def expires_now #:doc: + response.headers["Cache-Control"] = "no-cache" + end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb index b7e3bfaa7e..f269fe70db 100644 --- a/actionpack/lib/action_controller/new_base/http.rb +++ b/actionpack/lib/action_controller/new_base/http.rb @@ -42,6 +42,7 @@ module ActionController def call(name, env) @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new + @_response.request = request process(name) @_response.body = response_body @_response.prepare! diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index 181c5c0ecd..106990b9ba 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -5,6 +5,7 @@ module ActionController def process_with_test(request, response) @_request = request @_response = response + @_response.request = request ret = process(request.parameters[:action]) @_response.body = self.response_body @_response.prepare! diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 8477115211..a777021a12 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -6,5 +6,7 @@ module ActionView #:nodoc: def render(*) self end def mime_type() Mime::HTML end + + def partial?() false end end end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 1e69ca894f..635b0f5342 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1660,13 +1660,13 @@ class EtagRenderTest < ActionController::TestCase def test_render_against_etag_request_should_200_when_no_match @request.if_none_match = etag_for("hello somewhere else") get :render_hello_world_from_variable - assert_equal "200 OK", @response.status + assert_equal 200, @response.status.to_i assert !@response.body.empty? end def test_render_should_not_set_etag_when_last_modified_has_been_specified get :render_hello_world_with_last_modified_set - assert_equal "200 OK", @response.status + assert_equal 200, @response.status.to_i assert_not_nil @response.last_modified assert_nil @response.etag assert @response.body.present? @@ -1752,7 +1752,7 @@ class LastModifiedRenderTest < ActionController::TestCase def test_request_not_modified @request.if_modified_since = @last_modified get :conditional_hello - assert_equal "304 Not Modified", @response.status + assert_equal 304, @response.status.to_i assert @response.body.blank?, @response.body assert_equal @last_modified, @response.headers['Last-Modified'] end @@ -1767,7 +1767,7 @@ class LastModifiedRenderTest < ActionController::TestCase def test_request_modified @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT' get :conditional_hello - assert_equal "200 OK", @response.status + assert_equal 200, @response.status.to_i assert !@response.body.blank? assert_equal @last_modified, @response.headers['Last-Modified'] end -- cgit v1.2.3 From ddbeb15a5e7e0c3c5f316ccf65b557bc5311a6c4 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 11 May 2009 12:01:08 -0700 Subject: Revert "Fixed bug with polymorphic has_one :as pointing to an STI record" [#2594 state:open] This reverts commit 99c103be1165da9c8299bc0977188ecf167e06a5. --- .../lib/active_record/associations/has_one_association.rb | 2 +- .../test/cases/associations/has_one_associations_test.rb | 9 +-------- activerecord/test/fixtures/organizations.yml | 4 +--- activerecord/test/fixtures/sponsors.yml | 4 +--- activerecord/test/models/organization.rb | 4 ---- activerecord/test/schema/schema.rb | 3 +-- 6 files changed, 5 insertions(+), 21 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 4908005d2e..b72b84343b 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -90,7 +90,7 @@ module ActiveRecord when @reflection.options[:as] @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " + - "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.name.to_s)}" + "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}" else @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}" end diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 3984945f9f..1ddb3f49bf 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -2,11 +2,9 @@ require "cases/helper" require 'models/developer' require 'models/project' require 'models/company' -require 'models/sponsor' -require 'models/organization' class HasOneAssociationsTest < ActiveRecord::TestCase - fixtures :accounts, :companies, :developers, :projects, :developers_projects, :organizations, :sponsors + fixtures :accounts, :companies, :developers, :projects, :developers_projects def setup Account.destroyed_account_ids.clear @@ -308,9 +306,4 @@ class HasOneAssociationsTest < ActiveRecord::TestCase Firm.find(@firm.id, :include => :account).save! end end - - def test_polymorphic_sti - assert_equal organizations(:sponsorable), sponsors(:org_sponsor).sponsorable - assert_equal sponsors(:org_sponsor), organizations(:sponsorable).sponsor - end end diff --git a/activerecord/test/fixtures/organizations.yml b/activerecord/test/fixtures/organizations.yml index 05d620fbc6..25295bff87 100644 --- a/activerecord/test/fixtures/organizations.yml +++ b/activerecord/test/fixtures/organizations.yml @@ -2,6 +2,4 @@ nsa: name: No Such Agency discordians: name: Discordians -sponsorable: - name: We Need Money - type: SponsorableOrganization + diff --git a/activerecord/test/fixtures/sponsors.yml b/activerecord/test/fixtures/sponsors.yml index 97a7784047..42df8957d1 100644 --- a/activerecord/test/fixtures/sponsors.yml +++ b/activerecord/test/fixtures/sponsors.yml @@ -6,6 +6,4 @@ boring_club_sponsor_for_groucho: sponsorable: some_other_guy (Member) crazy_club_sponsor_for_groucho: sponsor_club: crazy_club - sponsorable: some_other_guy (Member) -org_sponsor: - sponsorable: sponsorable (SponsorableOrganization) \ No newline at end of file + sponsorable: some_other_guy (Member) \ No newline at end of file diff --git a/activerecord/test/models/organization.rb b/activerecord/test/models/organization.rb index 5d1308354d..d79d5037c8 100644 --- a/activerecord/test/models/organization.rb +++ b/activerecord/test/models/organization.rb @@ -1,8 +1,4 @@ class Organization < ActiveRecord::Base has_many :member_details has_many :members, :through => :member_details -end - -class SponsorableOrganization < Organization - has_one :sponsor, :as => :sponsorable end \ No newline at end of file diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 6fb918c60e..a776cd974b 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -284,7 +284,6 @@ ActiveRecord::Schema.define do create_table :organizations, :force => true do |t| t.string :name - t.string :type end create_table :owners, :primary_key => :owner_id ,:force => true do |t| @@ -390,7 +389,7 @@ ActiveRecord::Schema.define do create_table :sponsors, :force => true do |t| t.integer :club_id t.integer :sponsorable_id - t.string :sponsorable_type + t.string :sponsorable_type end create_table :subscribers, :force => true, :id => false do |t| -- cgit v1.2.3 From 6694bd46f59eb9b9b23afbd0d9484fd87e8fe350 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 11 May 2009 12:45:26 -0700 Subject: Aliased AbstractController::ActionNotFound to ActionController::UnknownAction --- actionpack/lib/action_controller/new_base/compatibility.rb | 13 ++++++++----- actionpack/lib/action_controller/testing/process2.rb | 1 + actionpack/test/abstract_unit2.rb | 3 --- actionpack/test/controller/render_test.rb | 5 +++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 3b1a74ec0c..b6e15a4e0d 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -3,6 +3,9 @@ module ActionController # Temporary hax setup do + ::ActionController::UnknownAction = ::AbstractController::ActionNotFound + ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError + cattr_accessor :session_options self.send(:class_variable_set, "@@session_options", {}) @@ -31,11 +34,11 @@ module ActionController super end - - def _layout_for_name(name) - name &&= name.sub(%r{^/?layouts/}, '') - super - end + + def _layout_for_name(name) + name &&= name.sub(%r{^/?layouts/}, '') + super + end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index 67b5afb9c5..18b7335450 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -39,6 +39,7 @@ module ActionController @request.recycle! @response.recycle! + @controller.response_body = nil @html_document = nil @request.env['REQUEST_METHOD'] = http_method diff --git a/actionpack/test/abstract_unit2.rb b/actionpack/test/abstract_unit2.rb index b95bfa0202..680043fab0 100644 --- a/actionpack/test/abstract_unit2.rb +++ b/actionpack/test/abstract_unit2.rb @@ -57,9 +57,6 @@ module ActionController class UnknownController < ActionControllerError #:nodoc: end - class UnknownAction < ActionControllerError #:nodoc: - end - class MissingFile < ActionControllerError #:nodoc: end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 635b0f5342..414b84c029 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1680,11 +1680,12 @@ class EtagRenderTest < ActionController::TestCase @request.if_none_match = expected_etag get :render_hello_world_from_variable - assert_equal "304 Not Modified", @response.status + assert_equal 304, @response.status.to_i + @response = ActionController::TestResponse.new @request.if_none_match = "\"diftag\"" get :render_hello_world_from_variable - assert_equal "200 OK", @response.status + assert_equal 200, @response.status.to_i end def render_with_404_shouldnt_have_etag -- cgit v1.2.3 From 0f6e764e4060b75ea8a335e6971209a08bf8b40a Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 11 May 2009 14:48:58 -0700 Subject: Fixed a bug with handling render options --- .../action_controller/new_base/compatibility.rb | 9 +++ .../lib/action_controller/new_base/renderer.rb | 4 +- actionpack/test/abstract_unit2.rb | 65 +--------------------- 3 files changed, 12 insertions(+), 66 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index b6e15a4e0d..505675ec4d 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -23,6 +23,15 @@ module ActionController cattr_accessor :default_charset self.send(:class_variable_set, "@@default_charset", "utf-8") + + cattr_reader :protected_instance_variables + self.send(:class_variable_set, "@@protected_instance_variables", %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller + @action_name @before_filter_chain_aborted @action_cache_path @_headers @_params + @_flash @_response)) + end + + module ClassMethods + def protect_from_forgery() end end def render_to_body(options) diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 4c4a74979b..bedd1d7a23 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -23,8 +23,8 @@ module ActionController options[:_template] = template elsif options.key?(:template) options[:_template_name] = options[:template] - elsif options.key?(:action) - options[:_template_name] = options[:action].to_s + else + options[:_template_name] = (options[:action] || action_name).to_s options[:_prefix] = _prefix end diff --git a/actionpack/test/abstract_unit2.rb b/actionpack/test/abstract_unit2.rb index 680043fab0..95e7b2e273 100644 --- a/actionpack/test/abstract_unit2.rb +++ b/actionpack/test/abstract_unit2.rb @@ -74,71 +74,8 @@ module ActionController class UnknownHttpMethod < ActionControllerError #:nodoc: end - class Base < Http - abstract! - # - cattr_accessor :relative_url_root - self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] - - cattr_reader :protected_instance_variables - # Controller specific instance variables which will not be accessible inside views. - @@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller - @action_name @before_filter_chain_aborted @action_cache_path @_headers @_params - @_flash @_response) - # - - use AbstractController::Callbacks - use AbstractController::Helpers - use AbstractController::Logger - - use ActionController::HideActions - use ActionController::UrlFor - use ActionController::Renderer - use ActionController::Layouts - use ActionController::Rails2Compatibility + class Base use ActionController::Testing - - def self.protect_from_forgery() end - - def self.inherited(klass) - ::ActionController::Base.subclasses << klass.to_s - super - end - - def self.subclasses - @subclasses ||= [] - end - - def self.app_loaded! - @subclasses.each do |subclass| - subclass.constantize._write_layout_method - end - end - - def render(action = action_name, options = {}) - if action.is_a?(Hash) - options, action = action, nil - else - options.merge! :action => action - end - - super(options) - end - - def render_to_body(options = {}) - options = {:template => options} if options.is_a?(String) - super - end - - def process_action - ret = super - render if response_body.nil? - ret - end - - def respond_to_action?(action_name) - super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path) - end end Base.view_paths = FIXTURE_LOAD_PATH -- cgit v1.2.3 From 0cac68d3bed3e6bf8ec2eb994858e4a179046941 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Mon, 11 May 2009 15:03:24 -0700 Subject: Revert "Whitespace!" This reverts commit a747ab5b20b9d543e9d311070e3b720c761ae716. --- actionpack/lib/action_controller/abstract.rb | 2 +- actionpack/lib/action_controller/abstract/base.rb | 19 ++++++++------- .../lib/action_controller/abstract/callbacks.rb | 8 +++---- .../lib/action_controller/abstract/exceptions.rb | 2 +- .../lib/action_controller/abstract/helpers.rb | 17 +++++++------- .../lib/action_controller/abstract/layouts.rb | 27 +++++++++++----------- .../lib/action_controller/abstract/logger.rb | 2 +- .../lib/action_controller/abstract/renderer.rb | 19 +++++++-------- actionpack/lib/action_controller/new_base.rb | 2 +- actionpack/lib/action_controller/new_base/base.rb | 27 +++++++++++----------- .../lib/action_controller/new_base/hide_actions.rb | 11 +++++---- .../lib/action_controller/new_base/layouts.rb | 14 ++++++----- .../lib/action_controller/new_base/renderer.rb | 23 +++++++++--------- .../lib/action_controller/new_base/url_for.rb | 6 ++--- 14 files changed, 95 insertions(+), 84 deletions(-) diff --git a/actionpack/lib/action_controller/abstract.rb b/actionpack/lib/action_controller/abstract.rb index 9442d4559f..3f5c4a185f 100644 --- a/actionpack/lib/action_controller/abstract.rb +++ b/actionpack/lib/action_controller/abstract.rb @@ -7,4 +7,4 @@ module AbstractController autoload :Renderer, "action_controller/abstract/renderer" # === Exceptions autoload :ActionNotFound, "action_controller/abstract/exceptions" -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index 39e9ad0440..ade7719cc0 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -1,38 +1,41 @@ module AbstractController class Base + attr_internal :response_body attr_internal :response_obj attr_internal :action_name - + def self.process(action) new.process(action) end - + def self.inherited(klass) end - + def initialize self.response_obj = {} end - + def process(action_name) unless respond_to_action?(action_name) raise ActionNotFound, "The action '#{action_name}' could not be found" end - + @_action_name = action_name process_action self.response_obj[:body] = self.response_body self end - + private + def process_action respond_to?(action_name) ? send(action_name) : send(:action_missing, action_name) end - + def respond_to_action?(action_name) respond_to?(action_name) || respond_to?(:action_missing, true) end + end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb index cb8aade0be..d7faaf4236 100644 --- a/actionpack/lib/action_controller/abstract/callbacks.rb +++ b/actionpack/lib/action_controller/abstract/callbacks.rb @@ -13,7 +13,7 @@ module AbstractController super end end - + module ClassMethods def _normalize_callback_options(options) if only = options[:only] @@ -21,11 +21,11 @@ module AbstractController options[:per_key] = {:if => only} end if except = options[:except] - except = Array(except).map {|e| "action_name == :#{e}"}.join(" || ") + except = Array(except).map {|e| "action_name == :#{e}"}.join(" || ") options[:per_key] = {:unless => except} end end - + [:before, :after, :around].each do |filter| class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{filter}_filter(*names, &blk) @@ -40,4 +40,4 @@ module AbstractController end end end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/exceptions.rb b/actionpack/lib/action_controller/abstract/exceptions.rb index a7d07868bb..ec4680629b 100644 --- a/actionpack/lib/action_controller/abstract/exceptions.rb +++ b/actionpack/lib/action_controller/abstract/exceptions.rb @@ -1,3 +1,3 @@ module AbstractController class ActionNotFound < StandardError ; end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb index 38e3ce8127..62caa119e7 100644 --- a/actionpack/lib/action_controller/abstract/helpers.rb +++ b/actionpack/lib/action_controller/abstract/helpers.rb @@ -8,14 +8,14 @@ module AbstractController extlib_inheritable_accessor :master_helper_module self.master_helper_module = Module.new end - + # def self.included(klass) # klass.class_eval do # extlib_inheritable_accessor :master_helper_module # self.master_helper_module = Module.new # end # end - + def _action_view @_action_view ||= begin av = super @@ -23,19 +23,19 @@ module AbstractController av end end - + module ClassMethods def inherited(klass) klass.master_helper_module = Module.new klass.master_helper_module.__send__ :include, master_helper_module - + super end - + def add_template_helper(mod) master_helper_module.module_eval { include mod } end - + def helper_method(*meths) meths.flatten.each do |meth| master_helper_module.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 @@ -45,7 +45,7 @@ module AbstractController ruby_eval end end - + def helper(*args, &blk) args.flatten.each do |arg| case arg @@ -56,5 +56,6 @@ module AbstractController master_helper_module.module_eval(&blk) if block_given? end end + end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 69fe4efc19..76130f8dc0 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -9,18 +9,18 @@ module AbstractController unless [String, Symbol, FalseClass, NilClass].include?(layout.class) raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" end - + @_layout = layout || false # Converts nil to false _write_layout_method end - + def _implied_layout_name name.underscore end - + # Takes the specified layout and creates a _layout method to be called # by _default_layout - # + # # If the specified layout is a: # String:: return the string # Symbol:: call the method specified by the symbol @@ -49,34 +49,35 @@ module AbstractController end end end - + def _render_template(template, options) _action_view._render_template_with_layout(template, options[:_layout]) end - + private + def _layout() end # This will be overwritten - + def _layout_for_name(name) unless [String, FalseClass, NilClass].include?(name.class) raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}" end - + name && view_paths.find_by_parts(name, {:formats => formats}, "layouts") end - + def _default_layout(require_layout = false) if require_layout && !_layout - raise ArgumentError, + raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end - + begin layout = _layout_for_name(_layout) rescue NameError => e - raise NoMethodError, + raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" end end end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/logger.rb b/actionpack/lib/action_controller/abstract/logger.rb index c3bccd7778..5fb78f1755 100644 --- a/actionpack/lib/action_controller/abstract/logger.rb +++ b/actionpack/lib/action_controller/abstract/logger.rb @@ -6,4 +6,4 @@ module AbstractController cattr_accessor :logger end end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index b5c31a27ee..beb848f90e 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -15,22 +15,22 @@ module AbstractController end def _action_view - @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) + @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) end - + def render(options = {}) self.response_body = render_to_body(options) end - + # Raw rendering of a template to a Rack-compatible body. # ==== # @option _prefix The template's path prefix # @option _layout The relative path to the layout template to use - # + # # :api: plugin def render_to_body(options = {}) name = options[:_template_name] || action_name - + template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) _render_template(template, options) end @@ -39,7 +39,7 @@ module AbstractController # ==== # @option _prefix The template's path prefix # @option _layout The relative path to the layout template to use - # + # # :api: plugin def render_to_string(options = {}) AbstractController::Renderer.body_to_s(render_to_body(options)) @@ -48,7 +48,7 @@ module AbstractController def _render_template(template, options) _action_view._render_template_with_layout(template) end - + def view_paths() _view_paths end # Return a string representation of a Rack-compatible response body. @@ -64,14 +64,15 @@ module AbstractController end module ClassMethods + def append_view_path(path) self.view_paths << path end - + def view_paths self._view_paths end - + def view_paths=(paths) self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 29dc3aaddc..7c65f1cdc1 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -4,4 +4,4 @@ module ActionController autoload :Layouts, "action_controller/new_base/layouts" autoload :Renderer, "action_controller/new_base/renderer" autoload :UrlFor, "action_controller/new_base/url_for" -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 2dd5390c99..08e7a1a0e7 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -1,5 +1,6 @@ module ActionController class AbstractBase < AbstractController::Base + # :api: public attr_internal :request, :response, :params @@ -11,46 +12,46 @@ module ActionController # :api: public def controller_name() self.class.controller_name end - # :api: public + # :api: public def self.controller_path @controller_path ||= self.name.sub(/Controller$/, '').underscore end - - # :api: public + + # :api: public def controller_path() self.class.controller_path end - - # :api: private + + # :api: private def self.action_methods @action_names ||= Set.new(self.public_instance_methods - self::CORE_METHODS) end - - # :api: private + + # :api: private def self.action_names() action_methods end - - # :api: private + + # :api: private def action_methods() self.class.action_names end # :api: private def action_names() action_methods end - + # :api: plugin def self.call(env) controller = new controller.call(env).to_rack end - + # :api: plugin def response_body=(body) @_response.body = body end - + # :api: private def call(env) @_request = ActionDispatch::Request.new(env) @_response = ActionDispatch::Response.new process(@_request.parameters[:action]) end - + # :api: private def to_rack response.to_a diff --git a/actionpack/lib/action_controller/new_base/hide_actions.rb b/actionpack/lib/action_controller/new_base/hide_actions.rb index 422ea180c4..aa420442fb 100644 --- a/actionpack/lib/action_controller/new_base/hide_actions.rb +++ b/actionpack/lib/action_controller/new_base/hide_actions.rb @@ -6,20 +6,21 @@ module ActionController end def action_methods() self.class.action_names end - def action_names() action_methods end - + def action_names() action_methods end + private + def respond_to_action?(action_name) !hidden_actions.include?(action_name) && (super || respond_to?(:method_missing)) end - + module ClassMethods def hide_action(*args) args.each do |arg| self.hidden_actions << arg.to_s end end - + def action_methods @action_names ||= Set.new(super.reject {|name| self.hidden_actions.include?(name.to_s)}) end @@ -27,4 +28,4 @@ module ActionController def self.action_names() action_methods end end end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb index 228162421d..89d24fe92d 100644 --- a/actionpack/lib/action_controller/new_base/layouts.rb +++ b/actionpack/lib/action_controller/new_base/layouts.rb @@ -4,13 +4,13 @@ module ActionController depends_on ActionController::Renderer depends_on AbstractController::Layouts - + module ClassMethods def _implied_layout_name controller_path end end - + def render_to_body(options) # render :text => ..., :layout => ... # or @@ -18,20 +18,22 @@ module ActionController if !options.key?(:text) || options.key?(:layout) options[:_layout] = options.key?(:layout) ? _layout_for_option(options[:layout]) : _default_layout end - + super end - + private + def _layout_for_option(name) case name when String then _layout_for_name(name) when true then _default_layout(true) when false, nil then nil else - raise ArgumentError, - "String, true, or false, expected for `layout'; you passed #{name.inspect}" + raise ArgumentError, + "String, true, or false, expected for `layout'; you passed #{name.inspect}" end end + end end diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index d7ea9ec4a5..be4ea54c3b 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -3,22 +3,22 @@ module ActionController extend ActiveSupport::DependencyModule depends_on AbstractController::Renderer - + def initialize(*) self.formats = [:html] super end - + def render(action, options = {}) # TODO: Move this into #render_to_body if action.is_a?(Hash) - options, action = action, nil + options, action = action, nil else options.merge! :action => action end - + _process_options(options) - + self.response_body = render_to_body(options) end @@ -34,17 +34,18 @@ module ActionController options[:_template_name] = options[:template] elsif options.key?(:action) options[:_template_name] = options[:action].to_s - options[:_prefix] = _prefix + options[:_prefix] = _prefix end - + super(options) end - + private + def _prefix controller_path - end - + end + def _text(options) text = options[:text] @@ -53,7 +54,7 @@ module ActionController else text.to_s end end - + def _process_options(options) if status = options[:status] response.status = status.to_i diff --git a/actionpack/lib/action_controller/new_base/url_for.rb b/actionpack/lib/action_controller/new_base/url_for.rb index 3179c8cd5b..af5b21012b 100644 --- a/actionpack/lib/action_controller/new_base/url_for.rb +++ b/actionpack/lib/action_controller/new_base/url_for.rb @@ -16,7 +16,7 @@ module ActionController # by this method. def default_url_options(options = nil) end - + def rewrite_options(options) #:nodoc: if defaults = default_url_options(options) defaults.merge(options) @@ -24,7 +24,7 @@ module ActionController options end end - + def url_for(options = {}) options ||= {} case options @@ -37,4 +37,4 @@ module ActionController end end end -end +end \ No newline at end of file -- cgit v1.2.3 From a2875bec9a31702a385d2f34e66843ddbe4e9db2 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 11 May 2009 22:23:47 -0400 Subject: Use DependencyModule for included hooks in ActiveRecord --- activerecord/lib/active_record/aggregations.rb | 4 +-- .../lib/active_record/association_preload.rb | 4 +-- activerecord/lib/active_record/associations.rb | 6 ++-- .../lib/active_record/attribute_methods.rb | 22 ++++++++----- .../lib/active_record/autosave_association.rb | 13 ++++---- activerecord/lib/active_record/batches.rb | 4 +-- activerecord/lib/active_record/calculations.rb | 5 ++- activerecord/lib/active_record/callbacks.rb | 12 ++++--- activerecord/lib/active_record/dirty.rb | 21 ++++++------ activerecord/lib/active_record/fixtures.rb | 38 ++++++++++------------ .../lib/active_record/locking/optimistic.rb | 16 ++++----- activerecord/lib/active_record/named_scope.rb | 9 +++-- .../lib/active_record/nested_attributes.rb | 9 ++--- activerecord/lib/active_record/observer.rb | 4 +-- activerecord/lib/active_record/reflection.rb | 4 +-- .../active_record/serializers/json_serializer.rb | 7 ++-- activerecord/lib/active_record/timestamp.rb | 12 ++++--- activerecord/lib/active_record/transactions.rb | 12 +++---- activerecord/lib/active_record/validations.rb | 15 ++++----- .../associations/eager_load_nested_include_test.rb | 13 ++++---- activerecord/test/cases/repair_helper.rb | 6 +--- 21 files changed, 111 insertions(+), 125 deletions(-) diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index 1eefebb3b3..359e70f5ed 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -1,8 +1,6 @@ module ActiveRecord module Aggregations # :nodoc: - def self.included(base) - base.extend(ClassMethods) - end + extend ActiveSupport::DependencyModule def clear_aggregation_cache #:nodoc: self.class.reflect_on_all_aggregations.to_a.each do |assoc| diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 967fff4d6f..5df76bb183 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -1,9 +1,7 @@ module ActiveRecord # See ActiveRecord::AssociationPreload::ClassMethods for documentation. module AssociationPreload #:nodoc: - def self.included(base) - base.extend(ClassMethods) - end + extend ActiveSupport::DependencyModule # Implements the details of eager loading of ActiveRecord associations. # Application developers should not use this module directly. diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 781a0290e8..e2dd36158f 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -77,6 +77,8 @@ module ActiveRecord # See ActiveRecord::Associations::ClassMethods for documentation. module Associations # :nodoc: + extend ActiveSupport::DependencyModule + # These classes will be loaded when associations are created. # So there is no need to eager load them. autoload :AssociationCollection, 'active_record/associations/association_collection' @@ -89,10 +91,6 @@ module ActiveRecord autoload :HasOneAssociation, 'active_record/associations/has_one_association' autoload :HasOneThroughAssociation, 'active_record/associations/has_one_through_association' - def self.included(base) - base.extend(ClassMethods) - end - # Clears out the association cache def clear_association_cache #:nodoc: self.class.reflect_on_all_associations.to_a.each do |assoc| diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 3ffc48941c..8d68d77eac 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -1,17 +1,21 @@ module ActiveRecord module AttributeMethods #:nodoc: + extend ActiveSupport::DependencyModule + DEFAULT_SUFFIXES = %w(= ? _before_type_cast) ATTRIBUTE_TYPES_CACHED_BY_DEFAULT = [:datetime, :timestamp, :time, :date] - def self.included(base) - base.extend ClassMethods - base.attribute_method_suffix(*DEFAULT_SUFFIXES) - base.cattr_accessor :attribute_types_cached_by_default, :instance_writer => false - base.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT - base.cattr_accessor :time_zone_aware_attributes, :instance_writer => false - base.time_zone_aware_attributes = false - base.class_inheritable_accessor :skip_time_zone_conversion_for_attributes, :instance_writer => false - base.skip_time_zone_conversion_for_attributes = [] + included do + attribute_method_suffix(*DEFAULT_SUFFIXES) + + cattr_accessor :attribute_types_cached_by_default, :instance_writer => false + self.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT + + cattr_accessor :time_zone_aware_attributes, :instance_writer => false + self.time_zone_aware_attributes = false + + class_inheritable_accessor :skip_time_zone_conversion_for_attributes, :instance_writer => false + self.skip_time_zone_conversion_for_attributes = [] end # Declare and check for suffixed attribute methods. diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 9717ca3d8b..4ab2818282 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -125,16 +125,15 @@ module ActiveRecord # post.author.name = '' # post.save(false) # => true module AutosaveAssociation + extend ActiveSupport::DependencyModule + ASSOCIATION_TYPES = %w{ has_one belongs_to has_many has_and_belongs_to_many } - def self.included(base) - base.class_eval do - base.extend(ClassMethods) - alias_method_chain :reload, :autosave_associations + included do + alias_method_chain :reload, :autosave_associations - ASSOCIATION_TYPES.each do |type| - base.send("valid_keys_for_#{type}_association") << :autosave - end + ASSOCIATION_TYPES.each do |type| + send("valid_keys_for_#{type}_association") << :autosave end end diff --git a/activerecord/lib/active_record/batches.rb b/activerecord/lib/active_record/batches.rb index 5a6cecd4ad..4836601297 100644 --- a/activerecord/lib/active_record/batches.rb +++ b/activerecord/lib/active_record/batches.rb @@ -1,8 +1,6 @@ module ActiveRecord module Batches # :nodoc: - def self.included(base) - base.extend(ClassMethods) - end + extend ActiveSupport::DependencyModule # When processing large numbers of records, it's often a good idea to do # so in batches to prevent memory ballooning. diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index f077818d3b..7afa7c49bd 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -1,9 +1,8 @@ module ActiveRecord module Calculations #:nodoc: + extend ActiveSupport::DependencyModule + CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include, :from] - def self.included(base) - base.extend(ClassMethods) - end module ClassMethods # Count operates using three different approaches. diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index e375037b5b..a77fdb1c13 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -211,21 +211,23 @@ module ActiveRecord # needs to be aware of it because an ordinary +save+ will raise such exception # instead of quietly returning +false+. module Callbacks + extend ActiveSupport::DependencyModule + CALLBACKS = %w( after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation after_validation before_validation_on_create after_validation_on_create before_validation_on_update after_validation_on_update before_destroy after_destroy ) - def self.included(base) #:nodoc: - base.extend Observable + included do + extend Observable [:create_or_update, :valid?, :create, :update, :destroy].each do |method| - base.send :alias_method_chain, method, :callbacks + alias_method_chain method, :callbacks end - base.send :include, ActiveSupport::Callbacks - base.define_callbacks *CALLBACKS + include ActiveSupport::Callbacks + define_callbacks *CALLBACKS end # Is called when the object was instantiated by one of the finders, like Base.find. diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index 4a2510aa63..fac6ca40d3 100644 --- a/activerecord/lib/active_record/dirty.rb +++ b/activerecord/lib/active_record/dirty.rb @@ -34,20 +34,21 @@ module ActiveRecord # person.name << 'by' # person.name_change # => ['uncle bob', 'uncle bobby'] module Dirty + extend ActiveSupport::DependencyModule + DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was'] - def self.included(base) - base.attribute_method_suffix *DIRTY_SUFFIXES - base.alias_method_chain :write_attribute, :dirty - base.alias_method_chain :save, :dirty - base.alias_method_chain :save!, :dirty - base.alias_method_chain :update, :dirty - base.alias_method_chain :reload, :dirty + included do + attribute_method_suffix *DIRTY_SUFFIXES - base.superclass_delegating_accessor :partial_updates - base.partial_updates = true + alias_method_chain :write_attribute, :dirty + alias_method_chain :save, :dirty + alias_method_chain :save!, :dirty + alias_method_chain :update, :dirty + alias_method_chain :reload, :dirty - base.send(:extend, ClassMethods) + superclass_delegating_accessor :partial_updates + self.partial_updates = true end # Do any attributes have unsaved changes? diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index c6501113bf..91b4b4e182 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -805,27 +805,25 @@ end module ActiveRecord module TestFixtures - def self.included(base) - base.class_eval do - setup :setup_fixtures - teardown :teardown_fixtures - - superclass_delegating_accessor :fixture_path - superclass_delegating_accessor :fixture_table_names - superclass_delegating_accessor :fixture_class_names - superclass_delegating_accessor :use_transactional_fixtures - superclass_delegating_accessor :use_instantiated_fixtures # true, false, or :no_instances - superclass_delegating_accessor :pre_loaded_fixtures - - self.fixture_table_names = [] - self.use_transactional_fixtures = false - self.use_instantiated_fixtures = true - self.pre_loaded_fixtures = false - - self.fixture_class_names = {} - end + extend ActiveSupport::DependencyModule + + included do + setup :setup_fixtures + teardown :teardown_fixtures + + superclass_delegating_accessor :fixture_path + superclass_delegating_accessor :fixture_table_names + superclass_delegating_accessor :fixture_class_names + superclass_delegating_accessor :use_transactional_fixtures + superclass_delegating_accessor :use_instantiated_fixtures # true, false, or :no_instances + superclass_delegating_accessor :pre_loaded_fixtures + + self.fixture_table_names = [] + self.use_transactional_fixtures = false + self.use_instantiated_fixtures = true + self.pre_loaded_fixtures = false - base.extend ClassMethods + self.fixture_class_names = {} end module ClassMethods diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index 7fa7e267d8..cf4f8864c6 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -42,17 +42,17 @@ module ActiveRecord # To override the name of the lock_version column, invoke the set_locking_column method. # This method uses the same syntax as set_table_name module Optimistic - def self.included(base) #:nodoc: - base.extend ClassMethods + extend ActiveSupport::DependencyModule - base.cattr_accessor :lock_optimistically, :instance_writer => false - base.lock_optimistically = true + included do + cattr_accessor :lock_optimistically, :instance_writer => false + self.lock_optimistically = true - base.alias_method_chain :update, :lock - base.alias_method_chain :destroy, :lock - base.alias_method_chain :attributes_from_column_definition, :lock + alias_method_chain :update, :lock + alias_method_chain :destroy, :lock + alias_method_chain :attributes_from_column_definition, :lock - class << base + class << self alias_method :locking_column=, :set_locking_column end end diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 3df7089096..32bb36c07c 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -1,5 +1,7 @@ module ActiveRecord module NamedScope + extend ActiveSupport::DependencyModule + # All subclasses of ActiveRecord::Base have one named scope: # * scoped - which allows for the creation of anonymous \scopes, on the fly: Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions) # @@ -7,11 +9,8 @@ module ActiveRecord # intermediate values (scopes) around as first-class objects is convenient. # # You can define a scope that applies to all finders using ActiveRecord::Base.default_scope. - def self.included(base) - base.class_eval do - extend ClassMethods - named_scope :scoped, lambda { |scope| scope } - end + included do + named_scope :scoped, lambda { |scope| scope } end module ClassMethods diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index dfad2901c5..1ea2f53fd8 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -1,9 +1,10 @@ module ActiveRecord module NestedAttributes #:nodoc: - def self.included(base) - base.extend(ClassMethods) - base.class_inheritable_accessor :reject_new_nested_attributes_procs, :instance_writer => false - base.reject_new_nested_attributes_procs = {} + extend ActiveSupport::DependencyModule + + included do + class_inheritable_accessor :reject_new_nested_attributes_procs, :instance_writer => false + self.reject_new_nested_attributes_procs = {} end # == Nested Attributes diff --git a/activerecord/lib/active_record/observer.rb b/activerecord/lib/active_record/observer.rb index b35e407cc1..1ca76c7b2f 100644 --- a/activerecord/lib/active_record/observer.rb +++ b/activerecord/lib/active_record/observer.rb @@ -3,9 +3,7 @@ require 'set' module ActiveRecord module Observing # :nodoc: - def self.included(base) - base.extend ClassMethods - end + extend ActiveSupport::DependencyModule module ClassMethods # Activates the observers assigned. Examples: diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index ec0175497d..3747ba449d 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -1,8 +1,6 @@ module ActiveRecord module Reflection # :nodoc: - def self.included(base) - base.extend(ClassMethods) - end + extend ActiveSupport::DependencyModule # Reflection allows you to interrogate Active Record classes and objects about their associations and aggregations. # This information can, for example, be used in a form builder that took an Active Record object and created input diff --git a/activerecord/lib/active_record/serializers/json_serializer.rb b/activerecord/lib/active_record/serializers/json_serializer.rb index 48df15d2c0..d376fd5e1b 100644 --- a/activerecord/lib/active_record/serializers/json_serializer.rb +++ b/activerecord/lib/active_record/serializers/json_serializer.rb @@ -2,9 +2,10 @@ require 'active_support/json' module ActiveRecord #:nodoc: module Serialization - def self.included(base) - base.cattr_accessor :include_root_in_json, :instance_writer => false - base.extend ClassMethods + extend ActiveSupport::DependencyModule + + included do + cattr_accessor :include_root_in_json, :instance_writer => false end # Returns a JSON string representing the model. Some configuration is diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index d9e1ef351f..3734e170af 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -8,12 +8,14 @@ module ActiveRecord # Timestamps are in the local timezone by default but you can use UTC by setting # ActiveRecord::Base.default_timezone = :utc module Timestamp - def self.included(base) #:nodoc: - base.alias_method_chain :create, :timestamps - base.alias_method_chain :update, :timestamps + extend ActiveSupport::DependencyModule - base.class_inheritable_accessor :record_timestamps, :instance_writer => false - base.record_timestamps = true + included do + alias_method_chain :create, :timestamps + alias_method_chain :update, :timestamps + + class_inheritable_accessor :record_timestamps, :instance_writer => false + self.record_timestamps = true end # Saves the record with the updated_at/on attributes set to the current time. diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index b059eb7f6f..471a81dfb5 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -3,16 +3,14 @@ require 'thread' module ActiveRecord # See ActiveRecord::Transactions::ClassMethods for documentation. module Transactions + extend ActiveSupport::DependencyModule + class TransactionError < ActiveRecordError # :nodoc: end - def self.included(base) - base.extend(ClassMethods) - - base.class_eval do - [:destroy, :save, :save!].each do |method| - alias_method_chain method, :transactions - end + included do + [:destroy, :save, :save!].each do |method| + alias_method_chain method, :transactions end end diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index e6b61e0b35..9907a3c9b7 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -301,17 +301,16 @@ module ActiveRecord # # An Errors object is automatically created for every Active Record. module Validations + extend ActiveSupport::DependencyModule + VALIDATIONS = %w( validate validate_on_create validate_on_update ) - def self.included(base) # :nodoc: - base.extend ClassMethods - base.class_eval do - alias_method_chain :save, :validation - alias_method_chain :save!, :validation - end + included do + alias_method_chain :save, :validation + alias_method_chain :save!, :validation - base.send :include, ActiveSupport::Callbacks - base.define_callbacks *VALIDATIONS + include ActiveSupport::Callbacks + define_callbacks *VALIDATIONS end # Active Record classes can implement validations in several ways. The highest level, easiest to read, diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb index 677226ec89..5f824f9c74 100644 --- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb +++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb @@ -6,13 +6,12 @@ require 'models/category' require 'models/categorization' module Remembered - def self.included(base) - base.extend ClassMethods - base.class_eval do - after_create :remember - protected - def remember; self.class.remembered << self; end - end + extend ActiveSupport::DependencyModule + + included do + after_create :remember + protected + def remember; self.class.remembered << self; end end module ClassMethods diff --git a/activerecord/test/cases/repair_helper.rb b/activerecord/test/cases/repair_helper.rb index 0155668811..686bfee46d 100644 --- a/activerecord/test/cases/repair_helper.rb +++ b/activerecord/test/cases/repair_helper.rb @@ -1,11 +1,7 @@ module ActiveRecord module Testing module RepairHelper - def self.included(base) - base.class_eval do - extend ClassMethods - end - end + extend ActiveSupport::DependencyModule module Toolbox def self.record_validations(*model_classes) -- cgit v1.2.3 From 22c5667c2ef46d6723c1805d3adc52dc8e92429b Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 11 May 2009 19:49:11 -0700 Subject: Defer rake/contrib/sshpublisher require so we can use the stdlib rake instead of the full gem --- actionpack/Rakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 18610ed773..ef76eedfd7 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -4,7 +4,6 @@ require 'rake/testtask' require 'rake/rdoctask' require 'rake/packagetask' require 'rake/gempackagetask' -require 'rake/contrib/sshpublisher' require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version') PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' @@ -143,12 +142,14 @@ task :update_js => [ :update_scriptaculous ] desc "Publish the API documentation" task :pgem => [:package] do + require 'rake/contrib/sshpublisher' Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload `ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'` end desc "Publish the API documentation" task :pdoc => [:rdoc] do + require 'rake/contrib/sshpublisher' Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ap", "doc").upload end -- cgit v1.2.3