aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-06-23 18:13:46 -0300
committerEmilio Tagua <miloops@gmail.com>2009-06-23 18:13:46 -0300
commitb9088dce07f8525cdb84a1312a77b81db79067d6 (patch)
tree72ace069842b074981ba814ef1c335271176ce27
parent4864f92ee34e840307d968fa8b04972b6d786fe8 (diff)
parent4417a19b035d73eb46a5e06e296a4b1c8091bef1 (diff)
downloadrails-b9088dce07f8525cdb84a1312a77b81db79067d6.tar.gz
rails-b9088dce07f8525cdb84a1312a77b81db79067d6.tar.bz2
rails-b9088dce07f8525cdb84a1312a77b81db79067d6.zip
Merge commit 'rails/master'
-rw-r--r--actionpack/lib/action_controller/base/compatibility.rb8
-rw-r--r--actionpack/lib/action_controller/base/filter_parameter_logging.rb5
-rw-r--r--actionpack/lib/action_controller/base/flash.rb74
-rw-r--r--actionpack/lib/action_controller/base/http.rb2
-rw-r--r--actionpack/lib/action_controller/base/layouts.rb7
-rw-r--r--actionpack/lib/action_controller/base/mime_responds.rb7
-rw-r--r--actionpack/lib/action_controller/base/request_forgery_protection.rb18
-rw-r--r--actionpack/lib/action_controller/base/streaming.rb5
-rw-r--r--actionpack/lib/action_controller/base/verification.rb5
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb26
-rw-r--r--actionpack/lib/action_controller/legacy/layout.rb3
-rw-r--r--actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb3
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb14
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb10
-rw-r--r--actionpack/lib/action_view.rb29
-rw-r--r--actionpack/lib/action_view/base.rb55
-rw-r--r--actionpack/lib/action_view/helpers/active_record_helper.rb59
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb31
-rw-r--r--actionpack/lib/action_view/paths.rb2
-rw-r--r--actionpack/lib/action_view/render/partials.rb7
-rw-r--r--actionpack/lib/action_view/render/rendering.rb70
-rw-r--r--actionpack/lib/action_view/template/handlers/builder.rb3
-rw-r--r--actionpack/lib/action_view/template/handlers/rjs.rb1
-rw-r--r--actionpack/lib/action_view/template/path.rb152
-rw-r--r--actionpack/lib/action_view/template/resolver.rb150
-rw-r--r--actionpack/lib/action_view/template/template.rb4
-rw-r--r--actionpack/lib/action_view/template/text.rb2
-rw-r--r--actionpack/test/abstract_controller/layouts_test.rb2
-rw-r--r--actionpack/test/abstract_unit.rb1
-rw-r--r--actionpack/test/activerecord/polymorphic_routes_test.rb9
-rw-r--r--actionpack/test/activerecord/render_partial_with_record_identification_test.rb1
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb24
-rw-r--r--actionpack/test/controller/base_test.rb6
-rw-r--r--actionpack/test/controller/filters_test.rb68
-rw-r--r--actionpack/test/controller/helper_test.rb19
-rw-r--r--actionpack/test/controller/layout_test.rb22
-rw-r--r--actionpack/test/controller/mime_responds_test.rb32
-rw-r--r--actionpack/test/controller/record_identifier_test.rb2
-rw-r--r--actionpack/test/controller/redirect_test.rb1
-rw-r--r--actionpack/test/controller/render_test.rb14
-rw-r--r--actionpack/test/controller/send_file_test.rb4
-rw-r--r--actionpack/test/dispatch/mime_type_test.rb4
-rw-r--r--actionpack/test/fixtures/layouts/builder.builder2
-rw-r--r--actionpack/test/fixtures/layouts/standard.html.erb2
-rw-r--r--actionpack/test/fixtures/layouts/talk_from_action.erb4
-rw-r--r--actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb1
-rw-r--r--actionpack/test/lib/controller/fake_models.rb6
-rw-r--r--actionpack/test/lib/fixture_template.rb41
-rw-r--r--actionpack/test/new_base/content_type_test.rb2
-rw-r--r--actionpack/test/new_base/etag_test.rb2
-rw-r--r--actionpack/test/new_base/render_action_test.rb8
-rw-r--r--actionpack/test/new_base/render_implicit_action_test.rb2
-rw-r--r--actionpack/test/new_base/render_layout_test.rb6
-rw-r--r--actionpack/test/new_base/render_partial_test.rb2
-rw-r--r--actionpack/test/new_base/render_rjs_test.rb46
-rw-r--r--actionpack/test/new_base/render_template_test.rb6
-rw-r--r--actionpack/test/new_base/render_test.rb2
-rw-r--r--actionpack/test/new_base/render_text_test.rb4
-rw-r--r--actionpack/test/new_base/render_xml_test.rb2
-rw-r--r--actionpack/test/template/active_record_helper_test.rb14
-rw-r--r--actionpack/test/template/atom_feed_helper_test.rb1
-rw-r--r--actionpack/test/template/body_parts_test.rb13
-rw-r--r--actionpack/test/template/capture_helper_test.rb15
-rw-r--r--actionpack/test/template/compiled_templates_test.rb2
-rw-r--r--actionpack/test/template/form_helper_test.rb4
-rw-r--r--actionpack/test/template/prototype_helper_test.rb3
-rw-r--r--actionpack/test/template/record_tag_helper_test.rb1
-rw-r--r--actionpack/test/template/render_test.rb29
-rw-r--r--actionpack/test/template/test_test.rb1
-rw-r--r--actionpack/test/template/url_helper_test.rb2
-rw-r--r--activemodel/lib/active_model.rb7
-rw-r--r--activemodel/lib/active_model/attributes.rb17
-rw-r--r--activemodel/lib/active_model/errors.rb6
-rw-r--r--activemodel/lib/active_model/naming.rb (renamed from activesupport/lib/active_support/core_ext/module/model_naming.rb)16
-rw-r--r--activemodel/lib/active_model/serializers/json.rb38
-rw-r--r--activemodel/lib/active_model/validations.rb6
-rw-r--r--activemodel/test/cases/attributes_test.rb30
-rw-r--r--activemodel/test/cases/json_serialization_test.rb64
-rw-r--r--activemodel/test/cases/naming_test.rb (renamed from activesupport/test/core_ext/module/model_naming_test.rb)7
-rw-r--r--activemodel/test/cases/validations/presence_validation_test.rb18
-rw-r--r--activerecord/lib/active_record/associations/through_association_scope.rb7
-rwxr-xr-xactiverecord/lib/active_record/base.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb2
-rw-r--r--activerecord/lib/active_record/serializers/json_serializer.rb2
-rw-r--r--activerecord/lib/active_record/validations.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb6
-rw-r--r--activerecord/test/cases/migration_test.rb33
-rw-r--r--activerecord/test/models/post.rb2
-rw-r--r--activerecord/test/schema/schema.rb1
-rw-r--r--activeresource/lib/active_resource/base.rb1
-rw-r--r--activesupport/lib/active_support/cache.rb12
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb14
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module.rb1
-rw-r--r--activesupport/lib/active_support/json/decoding.rb1
-rw-r--r--activesupport/lib/active_support/json/encoding.rb5
-rw-r--r--activesupport/test/caching_test.rb16
-rw-r--r--railties/lib/initializer.rb2
-rw-r--r--railties/test/rails_info_controller_test.rb2
100 files changed, 813 insertions, 698 deletions
diff --git a/actionpack/lib/action_controller/base/compatibility.rb b/actionpack/lib/action_controller/base/compatibility.rb
index 29ba43a879..cd4b72b1c6 100644
--- a/actionpack/lib/action_controller/base/compatibility.rb
+++ b/actionpack/lib/action_controller/base/compatibility.rb
@@ -118,6 +118,14 @@ module ActionController
details[:prefix] = nil if name =~ /\blayouts/
super
end
+
+ # Move this into a "don't run in production" module
+ def _default_layout(details, require_layout = false)
+ super
+ rescue ActionView::MissingTemplate
+ _find_by_parts(_layout({}), {})
+ nil
+ end
def performed?
response_body
diff --git a/actionpack/lib/action_controller/base/filter_parameter_logging.rb b/actionpack/lib/action_controller/base/filter_parameter_logging.rb
index 8370ba6fc0..26cd03f277 100644
--- a/actionpack/lib/action_controller/base/filter_parameter_logging.rb
+++ b/actionpack/lib/action_controller/base/filter_parameter_logging.rb
@@ -2,10 +2,7 @@ module ActionController
module FilterParameterLogging
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include AbstractController::Logger
- end
+ include AbstractController::Logger
included do
include InstanceMethodsForNewBase
diff --git a/actionpack/lib/action_controller/base/flash.rb b/actionpack/lib/action_controller/base/flash.rb
index 42c6e430ca..590f9be3ac 100644
--- a/actionpack/lib/action_controller/base/flash.rb
+++ b/actionpack/lib/action_controller/base/flash.rb
@@ -28,20 +28,7 @@ module ActionController #:nodoc:
module Flash
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- include Session if defined?(ActionController::Http)
-
- included do
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include InstanceMethodsForNewBase
- else
- include InstanceMethodsForBase
-
- alias_method_chain :perform_action, :flash
- alias_method_chain :reset_session, :flash
- end
- end
+ include Session
class FlashNow #:nodoc:
def initialize(flash)
@@ -148,49 +135,30 @@ module ActionController #:nodoc:
end
end
- module InstanceMethodsForBase #:nodoc:
- protected
- def perform_action_with_flash
- perform_action_without_flash
- if defined? @_flash
- @_flash.store(session)
- remove_instance_variable(:@_flash)
- end
- end
-
- def reset_session_with_flash
- reset_session_without_flash
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
+ protected
+ def process_action(method_name)
+ super
+ if defined? @_flash
+ @_flash.store(session)
+ remove_instance_variable(:@_flash)
+ end
end
- module InstanceMethodsForNewBase #:nodoc:
- protected
- def process_action(method_name)
- super
- if defined? @_flash
- @_flash.store(session)
- remove_instance_variable(:@_flash)
- end
- end
-
- def reset_session
- super
- remove_instance_variable(:@_flash) if defined?(@_flash)
- end
+ def reset_session
+ super
+ remove_instance_variable(:@_flash) if defined?(@_flash)
end
- protected
- # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
- # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
- # to put a new one.
- def flash #:doc:
- if !defined?(@_flash)
- @_flash = session["flash"] || FlashHash.new
- @_flash.sweep
- end
-
- @_flash
+ # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
+ # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
+ # to put a new one.
+ def flash #:doc:
+ if !defined?(@_flash)
+ @_flash = session["flash"] || FlashHash.new
+ @_flash.sweep
end
+
+ @_flash
+ end
end
end
diff --git a/actionpack/lib/action_controller/base/http.rb b/actionpack/lib/action_controller/base/http.rb
index 2e73561f93..ec78bc15a8 100644
--- a/actionpack/lib/action_controller/base/http.rb
+++ b/actionpack/lib/action_controller/base/http.rb
@@ -36,7 +36,7 @@ module ActionController
# ==== Returns
# String
def self.controller_path
- @controller_path ||= self.name.sub(/Controller$/, '').underscore
+ @controller_path ||= name && name.sub(/Controller$/, '').underscore
end
# Delegates to the class' #controller_path
diff --git a/actionpack/lib/action_controller/base/layouts.rb b/actionpack/lib/action_controller/base/layouts.rb
index ace4b148c9..365351b421 100644
--- a/actionpack/lib/action_controller/base/layouts.rb
+++ b/actionpack/lib/action_controller/base/layouts.rb
@@ -26,9 +26,6 @@ module ActionController
# hello world
# // The footer part of this layout
#
- # NOTE: The old notation for rendering the view from a layout was to expose the magic <tt>@content_for_layout</tt> instance
- # variable. The preferred notation now is to use <tt>yield</tt>, as documented above.
- #
# == Accessing shared variables
#
# Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
@@ -176,7 +173,7 @@ module ActionController
super
return if (options.key?(:text) || options.key?(:inline) || options.key?(:partial)) && !options.key?(:layout)
- layout = options.key?(:layout) ? options[:layout] : :none
+ layout = options.key?(:layout) ? options[:layout] : :default
options[:_layout] = _layout_for_option(layout, options[:_template].details)
end
@@ -184,7 +181,7 @@ module ActionController
case name
when String then _layout_for_name(name, details)
when true then _default_layout(details, true)
- when :none then _default_layout(details, false)
+ when :default then _default_layout(details, false)
when false, nil then nil
else
raise ArgumentError,
diff --git a/actionpack/lib/action_controller/base/mime_responds.rb b/actionpack/lib/action_controller/base/mime_responds.rb
index 5c7218691e..ed0d58dba1 100644
--- a/actionpack/lib/action_controller/base/mime_responds.rb
+++ b/actionpack/lib/action_controller/base/mime_responds.rb
@@ -120,12 +120,9 @@ module ActionController #:nodoc:
@responses[mime_type] ||= Proc.new do
# TODO: Remove this when new base is merged in
- if defined?(Http)
- @controller.formats = [mime_type.to_sym]
- end
-
+ @controller.formats = [mime_type.to_sym]
+ @controller.content_type = mime_type
@controller.template.formats = [mime_type.to_sym]
- @response.content_type = mime_type
block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
end
diff --git a/actionpack/lib/action_controller/base/request_forgery_protection.rb b/actionpack/lib/action_controller/base/request_forgery_protection.rb
index a470c8eec1..6ba86cd0be 100644
--- a/actionpack/lib/action_controller/base/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/base/request_forgery_protection.rb
@@ -6,20 +6,16 @@ module ActionController #:nodoc:
extend ActiveSupport::Concern
# TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include AbstractController::Helpers, Session
- end
+ include AbstractController::Helpers, Session
included do
- if defined?(ActionController::Http)
- # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
- # sets it to <tt>:authenticity_token</tt> by default.
- cattr_accessor :request_forgery_protection_token
+ # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
+ # sets it to <tt>:authenticity_token</tt> by default.
+ cattr_accessor :request_forgery_protection_token
- # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
- class_inheritable_accessor :allow_forgery_protection
- self.allow_forgery_protection = true
- end
+ # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
+ class_inheritable_accessor :allow_forgery_protection
+ self.allow_forgery_protection = true
helper_method :form_authenticity_token
helper_method :protect_against_forgery?
diff --git a/actionpack/lib/action_controller/base/streaming.rb b/actionpack/lib/action_controller/base/streaming.rb
index 5c72fc9ad9..70a97ccfec 100644
--- a/actionpack/lib/action_controller/base/streaming.rb
+++ b/actionpack/lib/action_controller/base/streaming.rb
@@ -4,10 +4,7 @@ module ActionController #:nodoc:
module Streaming
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include ActionController::Renderer
- end
+ include ActionController::Renderer
DEFAULT_SEND_FILE_OPTIONS = {
:type => 'application/octet-stream'.freeze,
diff --git a/actionpack/lib/action_controller/base/verification.rb b/actionpack/lib/action_controller/base/verification.rb
index d87b348ed4..951ae1bee1 100644
--- a/actionpack/lib/action_controller/base/verification.rb
+++ b/actionpack/lib/action_controller/base/verification.rb
@@ -2,10 +2,7 @@ module ActionController #:nodoc:
module Verification #:nodoc:
extend ActiveSupport::Concern
- # TODO : Remove the defined? check when new base is the main base
- if defined?(ActionController::Http)
- include AbstractController::Callbacks, Session, Flash, Renderer
- end
+ include AbstractController::Callbacks, Session, Flash, Renderer
# This module provides a class-level method for specifying that certain
# actions are guarded against being called without certain prerequisites
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 54148b55d8..d8a1662acc 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -62,14 +62,7 @@ module ActionController #:nodoc:
cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options)
- # TODO: Remove this once new base is swapped in.
- if defined?(ActionController::Http)
- around_filter cache_filter, filter_options
- else
- around_filter(filter_options) do |controller, action|
- cache_filter.filter(controller, action)
- end
- end
+ around_filter cache_filter, filter_options
end
end
@@ -91,19 +84,10 @@ module ActionController #:nodoc:
@options = options
end
- # TODO: Remove once New Base is merged
- if defined?(ActionController::Http)
- def filter(controller)
- should_continue = before(controller)
- yield if should_continue
- after(controller)
- end
- else
- def filter(controller, action)
- should_continue = before(controller)
- action.call if should_continue
- after(controller)
- end
+ def filter(controller)
+ should_continue = before(controller)
+ yield if should_continue
+ after(controller)
end
def before(controller)
diff --git a/actionpack/lib/action_controller/legacy/layout.rb b/actionpack/lib/action_controller/legacy/layout.rb
index 3046e082d9..3f3d20b95f 100644
--- a/actionpack/lib/action_controller/legacy/layout.rb
+++ b/actionpack/lib/action_controller/legacy/layout.rb
@@ -44,9 +44,6 @@ module ActionController #:nodoc:
# hello world
# // The footer part of this layout
#
- # NOTE: The old notation for rendering the view from a layout was to expose the magic <tt>@content_for_layout</tt> instance
- # variable. The preferred notation now is to use <tt>yield</tt>, as documented above.
- #
# == Accessing shared variables
#
# Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
diff --git a/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb b/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
index d9b614c237..c6f7de17bd 100644
--- a/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
+++ b/actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
@@ -112,8 +112,7 @@ module ActionController
# Returns the path component of a URL for the given record. It uses
# <tt>polymorphic_url</tt> with <tt>:routing_type => :path</tt>.
def polymorphic_path(record_or_hash_or_array, options = {})
- options[:routing_type] = :path
- polymorphic_url(record_or_hash_or_array, options)
+ polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
end
%w(edit new).each do |action|
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 25156a4c75..27f27e27fe 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -2,7 +2,19 @@ require 'set'
require 'active_support/core_ext/class/attribute_accessors'
module Mime
- SET = []
+ class Mimes < Array
+ def symbols
+ @symbols ||= map {|m| m.to_sym }
+ end
+
+ %w(<< concat shift unshift push pop []= clear compact! collect!
+ delete delete_at delete_if flatten! map! insert reject! reverse!
+ replace slice! sort! uniq!).each do |method|
+ define_method(method) {|*args| @symbols = nil; super(*args) }
+ end
+ end
+
+ SET = Mimes.new
EXTENSION_LOOKUP = {}
LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 140feb9a68..3f23a5af7a 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -180,12 +180,10 @@ module ActionDispatch
else
accepts.dup
end.tap do |ret|
- if defined?(ActionController::Http)
- if ret == ONLY_ALL
- ret.replace Mime::SET
- elsif all = ret.index(Mime::ALL)
- ret.delete_at(all) && ret.insert(all, *Mime::SET)
- end
+ if ret == ONLY_ALL
+ ret.replace Mime::SET
+ elsif all = ret.index(Mime::ALL)
+ ret.delete_at(all) && ret.insert(all, *Mime::SET)
end
end
else
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 94138097e3..27a06db5bb 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -33,21 +33,22 @@ module ActionView
[Base, InlineTemplate, TemplateError]
end
- autoload :Base, 'action_view/base'
- autoload :Helpers, 'action_view/helpers'
- autoload :InlineTemplate, 'action_view/template/inline'
- autoload :Partials, 'action_view/render/partials'
- autoload :Path, 'action_view/template/path'
- autoload :PathSet, 'action_view/paths'
- autoload :Rendering, 'action_view/render/rendering'
- autoload :Renderable, 'action_view/template/renderable'
+ autoload :Base, 'action_view/base'
+ autoload :Helpers, 'action_view/helpers'
+ autoload :InlineTemplate, 'action_view/template/inline'
+ autoload :Partials, 'action_view/render/partials'
+ autoload :Resolver, 'action_view/template/resolver'
+ autoload :PathSet, 'action_view/paths'
+ autoload :Rendering, 'action_view/render/rendering'
+ autoload :Renderable, 'action_view/template/renderable'
autoload :RenderablePartial, 'action_view/template/partial'
- autoload :Template, 'action_view/template/template'
- autoload :TemplateError, 'action_view/template/error'
- autoload :TemplateHandler, 'action_view/template/handler'
- autoload :TemplateHandlers, 'action_view/template/handlers'
- autoload :TextTemplate, 'action_view/template/text'
- autoload :Helpers, 'action_view/helpers'
+ autoload :Template, 'action_view/template/template'
+ autoload :TemplateError, 'action_view/template/error'
+ autoload :TemplateHandler, 'action_view/template/handler'
+ autoload :TemplateHandlers, 'action_view/template/handlers'
+ autoload :TextTemplate, 'action_view/template/text'
+ autoload :Helpers, 'action_view/helpers'
+ autoload :FileSystemResolverWithFallback, 'action_view/template/resolver'
end
class ERB
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 4ab568b44c..45184f58fb 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -170,12 +170,13 @@ module ActionView #:nodoc:
attr_accessor :base_path, :assigns, :template_extension, :formats
attr_accessor :controller
+ attr_internal :captures
attr_accessor :output_buffer
class << self
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
- delegate :logger, :to => 'ActionController::Base'
+ delegate :logger, :to => 'ActionController::Base', :allow_nil => true
end
@@debug_rjs = false
@@ -229,38 +230,27 @@ module ActionView #:nodoc:
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc:
@formats = formats || [:html]
- @assigns = assigns_for_first_render
- @assigns_added = nil
+ @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
@controller = controller
@helpers = ProxyModule.new(self)
+ @_content_for = Hash.new {|h,k| h[k] = "" }
self.view_paths = view_paths
-
- @_first_render = nil
- @_current_render = nil
end
+ attr_internal :template
attr_reader :view_paths
def view_paths=(paths)
@view_paths = self.class.process_view_paths(paths)
end
- # Access the current template being rendered.
- # Returns a ActionView::Template object.
- def template
- @_current_render
- end
-
- def template=(template) #:nodoc:
- @_first_render ||= template
- @_current_render = template
- end
-
def with_template(current_template)
+ _evaluate_assigns_and_ivars
last_template, self.template = template, current_template
+ last_formats, self.formats = formats, [current_template.mime_type.to_sym] + Mime::SET.symbols
yield
ensure
- self.template = last_template
+ self.template, self.formats = last_template, last_formats
end
def punctuate_body!(part)
@@ -271,30 +261,19 @@ module ActionView #:nodoc:
# Evaluates the local assigns and controller ivars, pushes them to the view.
def _evaluate_assigns_and_ivars #:nodoc:
- unless @assigns_added
- @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
- _copy_ivars_from_controller
- @assigns_added = true
- end
+ @assigns_added ||= _copy_ivars_from_controller
end
- private
+ private
- def _copy_ivars_from_controller #:nodoc:
- if @controller
- variables = @controller.instance_variable_names
- variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
- variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
- end
+ def _copy_ivars_from_controller #:nodoc:
+ if @controller
+ variables = @controller.instance_variable_names
+ variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
+ variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
end
+ true
+ end
- def _set_controller_content_type(content_type) #:nodoc:
- # TODO: Remove this method when new base is switched
- unless defined?(ActionController::Http)
- if controller.respond_to?(:response)
- controller.response.content_type ||= content_type
- end
- end
- end
end
end
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb
index 8b70200654..75cc651968 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -122,9 +122,9 @@ module ActionView
options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
- (errors = obj.errors.on(method))
+ (errors = obj.errors[method])
content_tag("div",
- "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.is_a?(Array) ? errors.first : errors)}#{options[:append_text]}",
+ "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}",
:class => options[:css_class]
)
else
@@ -247,59 +247,22 @@ module ActionView
end
end
- alias_method :tag_without_error_wrapping, :tag
- def tag(name, options)
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
- else
- tag_without_error_wrapping(name, options)
- end
- end
-
- alias_method :content_tag_without_error_wrapping, :content_tag
- def content_tag(name, value, options)
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name))
- else
- content_tag_without_error_wrapping(name, value, options)
- end
- end
-
- alias_method :to_date_select_tag_without_error_wrapping, :to_date_select_tag
- def to_date_select_tag(options = {}, html_options = {})
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(to_date_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
- else
- to_date_select_tag_without_error_wrapping(options, html_options)
- end
- end
-
- alias_method :to_datetime_select_tag_without_error_wrapping, :to_datetime_select_tag
- def to_datetime_select_tag(options = {}, html_options = {})
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(to_datetime_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
- else
- to_datetime_select_tag_without_error_wrapping(options, html_options)
+ %w(tag content_tag to_date_select_tag to_datetime_select_tag to_time_select_tag).each do |meth|
+ without = "#{meth}_without_error_wrapping"
+ define_method "#{meth}_with_error_wrapping" do |*args|
+ error_wrapping(send(without, *args))
end
+ alias_method_chain meth, :error_wrapping
end
- alias_method :to_time_select_tag_without_error_wrapping, :to_time_select_tag
- def to_time_select_tag(options = {}, html_options = {})
- if object.respond_to?(:errors) && object.errors.respond_to?(:on)
- error_wrapping(to_time_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
+ def error_wrapping(html_tag)
+ if object.respond_to?(:errors) && object.errors.respond_to?(:full_messages) && object.errors[@method_name].any?
+ Base.field_error_proc.call(html_tag, self)
else
- to_time_select_tag_without_error_wrapping(options, html_options)
+ html_tag
end
end
- def error_wrapping(html_tag, has_error)
- has_error ? Base.field_error_proc.call(html_tag, self) : html_tag
- end
-
- def error_message
- object.errors.on(@method_name)
- end
-
def column_type
object.send(:column_for_attribute, @method_name).type
end
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index b4197479a0..c90acc5ac2 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -111,15 +111,32 @@ module ActionView
#
# WARNING: content_for is ignored in caches. So you shouldn't use it
# for elements that will be fragment cached.
- #
- # The deprecated way of accessing a content_for block is to use an instance variable
- # named <tt>@content_for_#{name_of_the_content_block}</tt>. The preferred usage is now
- # <tt><%= yield :footer %></tt>.
def content_for(name, content = nil, &block)
- ivar = "@content_for_#{name}"
content = capture(&block) if block_given?
- instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
- nil
+ return @_content_for[name] << content if content
+ @_content_for[name]
+ end
+
+ # content_for? simply checks whether any content has been captured yet using content_for
+ # Useful to render parts of your layout differently based on what is in your views.
+ #
+ # ==== Examples
+ #
+ # Perhaps you will use different css in you layout if no content_for :right_column
+ #
+ # <%# This is the layout %>
+ # <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ # <head>
+ # <title>My Website</title>
+ # <%= yield :script %>
+ # </head>
+ # <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
+ # <%= yield %>
+ # <%= yield :right_col %>
+ # </body>
+ # </html>
+ def content_for?(name)
+ @_content_for[name].present?
end
# Use an alternate output buffer for the duration of the block.
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index 95c56faf9c..074b475819 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -3,7 +3,7 @@ module ActionView #:nodoc:
def self.type_cast(obj)
if obj.is_a?(String)
cache = !defined?(Rails) || !Rails.respond_to?(:configuration) || Rails.configuration.cache_classes
- Template::FileSystemPathWithFallback.new(obj, :cache => cache)
+ FileSystemResolverWithFallback.new(obj, :cache => cache)
else
obj
end
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index eacf117bea..87314fff67 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -245,13 +245,6 @@ module ActionView
end
end
- def _render_partial_with_block(layout, block, options)
- @_proc_for_layout = block
- concat(_render_partial(options.merge(:partial => layout)))
- ensure
- @_proc_for_layout = nil
- end
-
def _render_partial_with_layout(layout, options)
if layout
prefix = controller && !layout.include?("/") ? controller.controller_path : nil
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index fe785e7b20..162e38c484 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -51,32 +51,60 @@ module ActionView
end
begin
- original_content_for_layout = @content_for_layout if defined?(@content_for_layout)
- @content_for_layout = content
+ old_content, @_content_for[:layout] = @_content_for[:layout], content
- @cached_content_for_layout = @content_for_layout
+ @cached_content_for_layout = @_content_for[:layout]
_render_template(layout, locals)
ensure
- @content_for_layout = original_content_for_layout
+ @_content_for[:layout] = old_content
end
end
+ # You can think of a layout as a method that is called with a block. This method
+ # returns the block that the layout is called with. If the user calls yield :some_name,
+ # the block, by default, returns content_for(:some_name). If the user calls yield,
+ # the default block returns content_for(:layout).
+ #
+ # The user can override this default by passing a block to the layout.
+ #
+ # ==== Example
+ #
+ # # The template
+ # <% render :layout => "my_layout" do %>Content<% end %>
+ #
+ # # The layout
+ # <html><% yield %></html>
+ #
+ # In this case, instead of the default block, which would return content_for(:layout),
+ # this method returns the block that was passed in to render layout, and the response
+ # would be <html>Content</html>.
+ #
+ # Finally, the block can take block arguments, which can be passed in by yield.
+ #
+ # ==== Example
+ #
+ # # The template
+ # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %>
+ #
+ # # The layout
+ # <html><% yield Struct.new(:name).new("David") %></html>
+ #
+ # In this case, the layout would receive the block passed into <tt>render :layout</tt>,
+ # and the Struct specified in the layout would be passed into the block. The result
+ # would be <html>Hello David</html>.
+ def layout_proc(name)
+ @_default_layout ||= proc { |*names| @_content_for[names.first || :layout] }
+ !@_content_for.key?(name) && @_proc_for_layout || @_default_layout
+ end
+
def _render_template(template, local_assigns = {})
with_template(template) do
- _evaluate_assigns_and_ivars
- _set_controller_content_type(template.mime_type) if template.respond_to?(:mime_type)
-
template.render(self, local_assigns) do |*names|
- if !instance_variable_defined?(:"@content_for_#{names.first}") &&
- instance_variable_defined?(:@_proc_for_layout) && (proc = @_proc_for_layout)
- capture(*names, &proc)
- elsif instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
- instance_variable_get(ivar)
- end
+ capture(*names, &layout_proc(names.first))
end
end
rescue Exception => e
- if TemplateError === e
+ if e.is_a?(TemplateError)
e.sub_template_of(template)
raise e
else
@@ -101,20 +129,18 @@ module ActionView
end
def _render_template_with_layout(template, layout = nil, options = {}, partial = false)
- if controller && logger
- logger.info("Rendering #{template.identifier}" +
- (options[:status] ? " (#{options[:status]})" : ''))
- end
-
+ logger && logger.info("Rendering #{template.identifier}#{' (#{options[:status]})' if options[:status]}")
+
+ locals = options[:locals] || {}
+
content = if partial
object = partial unless partial == true
_render_partial_object(template, options, object)
else
- _render_template(template, options[:locals] || {})
+ _render_template(template, locals)
end
- return content unless layout
- _render_content_with_layout(content, layout, options[:locals] || {})
+ layout ? _render_content_with_layout(content, layout, locals) : content
end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb
index f412228752..abe140af0b 100644
--- a/actionpack/lib/action_view/template/handlers/builder.rb
+++ b/actionpack/lib/action_view/template/handlers/builder.rb
@@ -8,8 +8,7 @@ module ActionView
self.default_format = Mime::XML
def compile(template)
- "_set_controller_content_type(Mime::XML);" +
- "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
+ "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
";xml.target!;"
diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb
index a36744c2b7..b1d15dc209 100644
--- a/actionpack/lib/action_view/template/handlers/rjs.rb
+++ b/actionpack/lib/action_view/template/handlers/rjs.rb
@@ -6,7 +6,6 @@ module ActionView
self.default_format = Mime::JS
def compile(template)
- "@formats = [:html];" +
"controller.response.content_type ||= Mime::JS;" +
"update_page do |page|;#{template.source}\nend"
end
diff --git a/actionpack/lib/action_view/template/path.rb b/actionpack/lib/action_view/template/path.rb
deleted file mode 100644
index 478bf96c9a..0000000000
--- a/actionpack/lib/action_view/template/path.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-require "pathname"
-
-module ActionView
- class Template
- # Abstract super class
- class Path
- def initialize(options)
- @cache = options[:cache]
- @cached = {}
- end
-
- # Normalizes the arguments and passes it on to find_template
- def find_by_parts(*args)
- find_all_by_parts(*args).first
- end
-
- def find_all_by_parts(name, details = {}, prefix = nil, partial = nil)
- details[:locales] = [I18n.locale]
- name = name.to_s.gsub(handler_matcher, '').split("/")
- find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial)
- end
-
- private
-
- # This is what child classes implement. No defaults are needed
- # because Path guarentees that the arguments are present and
- # normalized.
- def find_templates(name, details, prefix, partial)
- raise NotImplementedError
- end
-
- def valid_handlers
- @valid_handlers ||= TemplateHandlers.extensions
- end
-
- def handler_matcher
- @handler_matcher ||= begin
- e = valid_handlers.join('|')
- /\.(?:#{e})$/
- end
- end
-
- def handler_glob
- e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join
- "{#{e}}"
- end
-
- def formats_glob
- @formats_glob ||= begin
- formats = Mime::SET.map { |m| m.symbol }
- '{' + formats.map { |l| ".#{l}," }.join + '}'
- end
- end
-
- def cached(key)
- return yield unless @cache
- return @cached[key] if @cached.key?(key)
- @cached[key] = yield
- end
- end
-
- class FileSystemPath < Path
-
- def initialize(path, options = {})
- raise ArgumentError, "path already is a Path class" if path.is_a?(Path)
- super(options)
- @path = Pathname.new(path).expand_path
- end
-
- # TODO: This is the currently needed API. Make this suck less
- # ==== <suck>
- attr_reader :path
-
- def to_s
- path.to_s
- end
-
- def to_str
- path.to_s
- end
-
- def ==(path)
- to_str == path.to_str
- end
-
- def eql?(path)
- to_str == path.to_str
- end
- # ==== </suck>
-
- def find_templates(name, details, prefix, partial, root = "#{@path}/")
- if glob = details_to_glob(name, details, prefix, partial, root)
- cached(glob) do
- Dir[glob].map do |path|
- next if File.directory?(path)
- source = File.read(path)
- identifier = Pathname.new(path).expand_path.to_s
-
- Template.new(source, identifier, *path_to_details(path))
- end.compact
- end
- end
- end
-
- private
-
- # :api: plugin
- def details_to_glob(name, details, prefix, partial, root)
- path = ""
- path << "#{prefix}/" unless prefix.empty?
- path << (partial ? "_#{name}" : name)
-
- extensions = ""
- [:locales, :formats].each do |k|
- extensions << if exts = details[k]
- '{' + exts.map {|e| ".#{e},"}.join + '}'
- else
- k == :formats ? formats_glob : ''
- end
- end
-
- "#{root}#{path}#{extensions}#{handler_glob}"
- 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 FileSystemPathWithFallback < FileSystemPath
-
- def find_templates(name, details, prefix, partial)
- templates = super
- return super(name, details, prefix, partial, '') if templates.empty?
- templates
- end
-
- end
- end
-end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
new file mode 100644
index 0000000000..d15f53a11b
--- /dev/null
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -0,0 +1,150 @@
+require "pathname"
+require "action_view/template/template"
+
+module ActionView
+ # Abstract superclass
+ class Resolver
+ def initialize(options)
+ @cache = options[:cache]
+ @cached = {}
+ end
+
+ # Normalizes the arguments and passes it on to find_template
+ def find_by_parts(*args)
+ find_all_by_parts(*args).first
+ end
+
+ def find_all_by_parts(name, details = {}, prefix = nil, partial = nil)
+ details[:locales] = [I18n.locale]
+ name = name.to_s.gsub(handler_matcher, '').split("/")
+ find_templates(name.pop, details, [prefix, *name].compact.join("/"), partial)
+ end
+
+ private
+
+ # This is what child classes implement. No defaults are needed
+ # because Resolver guarantees that the arguments are present and
+ # normalized.
+ def find_templates(name, details, prefix, partial)
+ raise NotImplementedError
+ end
+
+ def valid_handlers
+ @valid_handlers ||= TemplateHandlers.extensions
+ end
+
+ def handler_matcher
+ @handler_matcher ||= begin
+ e = valid_handlers.join('|')
+ /\.(?:#{e})$/
+ end
+ end
+
+ def handler_glob
+ e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join
+ "{#{e}}"
+ end
+
+ def formats_glob
+ @formats_glob ||= begin
+ '{' + Mime::SET.symbols.map { |l| ".#{l}," }.join + '}'
+ end
+ end
+
+ def cached(key)
+ return yield unless @cache
+ return @cached[key] if @cached.key?(key)
+ @cached[key] = yield
+ end
+ end
+
+ class FileSystemResolver < Resolver
+
+ def initialize(path, options = {})
+ raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
+ super(options)
+ @path = Pathname.new(path).expand_path
+ end
+
+ # TODO: This is the currently needed API. Make this suck less
+ # ==== <suck>
+ attr_reader :path
+
+ def to_s
+ path.to_s
+ end
+
+ def to_str
+ path.to_s
+ end
+
+ def ==(path)
+ to_str == path.to_str
+ end
+
+ def eql?(path)
+ to_str == path.to_str
+ end
+ # ==== </suck>
+
+ def find_templates(name, details, prefix, partial, root = "#{@path}/")
+ if glob = details_to_glob(name, details, prefix, partial, root)
+ cached(glob) do
+ Dir[glob].map do |path|
+ next if File.directory?(path)
+ source = File.read(path)
+ identifier = Pathname.new(path).expand_path.to_s
+
+ Template.new(source, identifier, *path_to_details(path))
+ end.compact
+ end
+ end
+ end
+
+ private
+
+ # :api: plugin
+ def details_to_glob(name, details, prefix, partial, root)
+ path = ""
+ path << "#{prefix}/" unless prefix.empty?
+ path << (partial ? "_#{name}" : name)
+
+ extensions = ""
+ [:locales, :formats].each do |k|
+ extensions << if exts = details[k]
+ '{' + exts.map {|e| ".#{e},"}.join + '}'
+ else
+ k == :formats ? formats_glob : ''
+ end
+ end
+
+ "#{root}#{path}#{extensions}#{handler_glob}"
+ 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 FileSystemResolverWithFallback < FileSystemResolver
+
+ def find_templates(name, details, prefix, partial)
+ templates = super
+ return super(name, details, prefix, partial, '') if templates.empty?
+ templates
+ end
+
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb
index e7ea42c2eb..fac50cd692 100644
--- a/actionpack/lib/action_view/template/template.rb
+++ b/actionpack/lib/action_view/template/template.rb
@@ -2,7 +2,7 @@
# This is so that templates compiled in this file are UTF-8
require 'set'
-require "action_view/template/path"
+require "action_view/template/resolver"
module ActionView
class Template
@@ -20,7 +20,7 @@ module ActionView
handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html"
end
@mime_type = Mime::Type.lookup_by_extension(format.to_s)
- @details[:formats] = Array.wrap(format && format.to_sym)
+ @details[:formats] = Array.wrap(format.to_sym)
end
def render(view, locals, &blk)
diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb
index fd57b1677e..81944ff546 100644
--- a/actionpack/lib/action_view/template/text.rb
+++ b/actionpack/lib/action_view/template/text.rb
@@ -3,7 +3,7 @@ module ActionView #:nodoc:
def initialize(string, content_type = Mime[:html])
super(string.to_s)
- @content_type = Mime[content_type]
+ @content_type = Mime[content_type] || content_type
end
def details
diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb
index 37eb55ec98..b28df7743f 100644
--- a/actionpack/test/abstract_controller/layouts_test.rb
+++ b/actionpack/test/abstract_controller/layouts_test.rb
@@ -9,7 +9,7 @@ module AbstractControllerTests
include AbstractController::Renderer
include AbstractController::Layouts
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.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/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 1333a9d71a..30e795a7a2 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -1,5 +1,6 @@
$:.unshift(File.dirname(__FILE__) + '/../lib')
$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
+$:.unshift(File.dirname(__FILE__) + '/../../activemodel/lib')
$:.unshift(File.dirname(__FILE__) + '/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb
index b9f5be2361..2036d1eeb5 100644
--- a/actionpack/test/activerecord/polymorphic_routes_test.rb
+++ b/actionpack/test/activerecord/polymorphic_routes_test.rb
@@ -234,10 +234,13 @@ class PolymorphicRoutesTest < ActionController::TestCase
with_admin_test_routes do
@project.save
@task.save
+
+ options = {}
object_array = [:admin, @project, @task]
- assert_no_difference 'object_array.size' do
- polymorphic_url(object_array)
- end
+ original_args = [object_array.dup, options.dup]
+
+ assert_no_difference('object_array.size') { polymorphic_path(object_array, options) }
+ assert_equal original_args, [object_array, options]
end
end
diff --git a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb
index 0a596c7ae0..2a31f3be44 100644
--- a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb
+++ b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb
@@ -126,6 +126,7 @@ class RenderPartialWithRecordIdentificationController < ActionController::Base
end
class Game < Struct.new(:name, :id)
+ extend ActiveModel::Naming
def to_param
id.to_s
end
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index 24686ab4b6..ecbaba39d1 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -13,6 +13,18 @@ class ActionPackAssertionsController < ActionController::Base
# a standard template
def hello_xml_world() render :template => "test/hello_xml_world"; end
+ # a standard template rendering PDF
+ def hello_xml_world_pdf
+ self.content_type = "application/pdf"
+ render :template => "test/hello_xml_world"
+ end
+
+ # a standard template rendering PDF
+ def hello_xml_world_pdf_header
+ response.headers["Content-Type"] = "application/pdf; charset=utf-8"
+ render :template => "test/hello_xml_world"
+ end
+
# a standard partial
def partial() render :partial => 'test/partial'; end
@@ -537,11 +549,13 @@ class ActionPackHeaderTest < ActionController::TestCase
end
def test_rendering_xml_respects_content_type
- pending do
- @response.headers['type'] = 'application/pdf'
- process :hello_xml_world
- assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
- end
+ process :hello_xml_world_pdf
+ assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
+ end
+
+ def test_rendering_xml_respects_content_type_when_set_in_the_header
+ process :hello_xml_world_pdf_header
+ assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
end
def test_render_text_with_custom_content_type
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index 03fd98a85c..8877057070 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -146,11 +146,7 @@ class PerformActionTest < ActionController::TestCase
def test_method_missing_is_not_an_action_name
use_controller MethodMissingController
- if defined?(ActionController::Http)
- assert ! @controller.__send__(:action_method?, 'method_missing')
- else
- assert ! @controller.__send__(:action_methods).include?('method_missing')
- end
+ assert ! @controller.__send__(:action_method?, 'method_missing')
get :method_missing
assert_response :success
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index b930ff4997..2da97a9d86 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -9,24 +9,20 @@ class ActionController::Base
end unless method_defined?(pending)
end
- if defined?(ActionController::Http)
- def before_filters
- filters = _process_action_callbacks.select { |c| c.kind == :before }
- filters.map! { |c| c.instance_variable_get(:@raw_filter) }
- end
+ def before_filters
+ filters = _process_action_callbacks.select { |c| c.kind == :before }
+ filters.map! { |c| c.instance_variable_get(:@raw_filter) }
end
end
- if defined?(ActionController::Http)
- def assigns(key = nil)
- assigns = {}
- instance_variable_names.each do |ivar|
- next if ActionController::Base.protected_instance_variables.include?(ivar)
- assigns[ivar[1..-1]] = instance_variable_get(ivar)
- end
-
- key.nil? ? assigns : assigns[key.to_s]
+ def assigns(key = nil)
+ assigns = {}
+ instance_variable_names.each do |ivar|
+ next if ActionController::Base.protected_instance_variables.include?(ivar)
+ assigns[ivar[1..-1]] = instance_variable_get(ivar)
end
+
+ key.nil? ? assigns : assigns[key.to_s]
end
end
@@ -598,22 +594,11 @@ class FilterTest < ActionController::TestCase
assert_equal "before and after", assigns["execution_log"]
end
- for_tag(:old_base) do
- def test_prepending_and_appending_around_filter
- controller = test_process(MixedFilterController)
- assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
- " after appended aroundfilter after aroundfilter after procfilter ",
- MixedFilterController.execution_log
- end
- end
-
- for_tag(:new_base) do
- def test_prepending_and_appending_around_filter
- controller = test_process(MixedFilterController)
- assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
- " after appended aroundfilter after procfilter after aroundfilter ",
- MixedFilterController.execution_log
- end
+ def test_prepending_and_appending_around_filter
+ controller = test_process(MixedFilterController)
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
+ " after appended aroundfilter after procfilter after aroundfilter ",
+ MixedFilterController.execution_log
end
def test_rendering_breaks_filtering_chain
@@ -876,14 +861,6 @@ class YieldingAroundFiltersTest < ActionController::TestCase
assert_raise(After) { test_process(controller,'raises_after') }
end
- for_tag(:old_base) do
- def test_with_method
- controller = ControllerWithFilterMethod
- assert_nothing_raised { test_process(controller,'no_raise') }
- assert_raise(After) { test_process(controller,'raises_after') }
- end
- end
-
def test_with_proc
test_process(ControllerWithProcFilter,'no_raise')
assert assigns['before']
@@ -906,18 +883,9 @@ class YieldingAroundFiltersTest < ActionController::TestCase
end
end
- for_tag(:old_base) do
- def test_filter_order_with_all_filter_types
- test_process(ControllerWithAllTypesOfFilters,'no_raise')
- assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after', assigns['ran_filter'].join(' ')
- end
- end
-
- for_tag(:new_base) do
- def test_filter_order_with_all_filter_types
- test_process(ControllerWithAllTypesOfFilters,'no_raise')
- assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)', assigns['ran_filter'].join(' ')
- end
+ def test_filter_order_with_all_filter_types
+ test_process(ControllerWithAllTypesOfFilters,'no_raise')
+ assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)', assigns['ran_filter'].join(' ')
end
def test_filter_order_with_skip_filter_method
diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb
index 515c4c9f52..23149fee27 100644
--- a/actionpack/test/controller/helper_test.rb
+++ b/actionpack/test/controller/helper_test.rb
@@ -127,11 +127,7 @@ class HelperTest < Test::Unit::TestCase
end
def test_all_helpers
- methods = if defined?(ActionController::Http)
- AllHelpersController._helpers.instance_methods.map {|m| m.to_s}
- else
- AllHelpersController.master_helper_module.instance_methods.map {|m| m.to_s}
- end
+ methods = AllHelpersController._helpers.instance_methods.map {|m| m.to_s}
# abc_helper.rb
assert methods.include?('bare_a')
@@ -147,12 +143,7 @@ class HelperTest < Test::Unit::TestCase
@controller_class.helpers_dir = File.dirname(__FILE__) + '/../fixtures/alternate_helpers'
# Reload helpers
- if defined?(ActionController::Http)
- @controller_class._helpers = Module.new
- else
- @controller_class.master_helper_module = Module.new
- end
-
+ @controller_class._helpers = Module.new
@controller_class.helper :all
# helpers/abc_helper.rb should not be included
@@ -184,11 +175,7 @@ class HelperTest < Test::Unit::TestCase
end
def master_helper_methods
- if defined?(ActionController::Http)
- @controller_class._helpers.instance_methods.map {|m| m.to_s }
- else
- @controller_class.master_helper_module.instance_methods.map {|m| m.to_s }
- end
+ @controller_class._helpers.instance_methods.map {|m| m.to_s }
end
def missing_methods
diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb
index c3d7b0778d..feb2f81cc1 100644
--- a/actionpack/test/controller/layout_test.rb
+++ b/actionpack/test/controller/layout_test.rb
@@ -165,26 +165,10 @@ class LayoutSetInResponseTest < ActionController::TestCase
assert_nil @controller.template.layout
end
- for_tag(:old_base) do
- # exempt_from_layout is deprecated
- def test_exempt_from_layout_honored_by_render_template
- ActionController::Base.exempt_from_layout :erb
- @controller = RenderWithTemplateOptionController.new
-
- get :hello
- assert_equal "alt/hello.rhtml", @response.body.strip
-
- ensure
- ActionController::Base.exempt_from_layout.delete(ERB)
- end
- end
-
def test_layout_is_picked_from_the_controller_instances_view_path
- pending do
- @controller = PrependsViewPathController.new
- get :hello
- assert_equal 'layouts/alt', @controller.template.layout
- end
+ @controller = PrependsViewPathController.new
+ get :hello
+ assert @controller.template.layout =~ /layouts\/alt\.\w+/
end
def test_absolute_pathed_layout
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index 0c6822a5b1..93ca34c41c 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -375,11 +375,9 @@ class MimeControllerTest < ActionController::TestCase
end
def test_rjs_type_skips_layout
- pending(:new_base) do
- @request.accept = "text/javascript"
- get :all_types_with_layout
- assert_equal 'RJS for all_types_with_layout', @response.body
- end
+ @request.accept = "text/javascript"
+ get :all_types_with_layout
+ assert_equal 'RJS for all_types_with_layout', @response.body
end
def test_html_type_with_layout
@@ -467,14 +465,6 @@ class MimeControllerTest < ActionController::TestCase
assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
assert_equal "text/html", @response.content_type
end
-
- def test_format_with_custom_response_type_and_request_headers_with_only_one_layout_present
- get :iphone_with_html_response_type_without_layout
- assert_equal '<html><div id="html_missing">Hello future from Firefox!</div></html>', @response.body
-
- @request.accept = "text/iphone"
- assert_raise(ActionView::MissingTemplate) { get :iphone_with_html_response_type_without_layout }
- end
end
class AbstractPostController < ActionController::Base
@@ -529,16 +519,14 @@ class MimeControllerLayoutsTest < ActionController::TestCase
assert_equal 'Hello iPhone', @response.body
end
- for_tag(:old_base) do
- def test_format_with_inherited_layouts
- @controller = SuperPostController.new
+ def test_format_with_inherited_layouts
+ @controller = SuperPostController.new
- get :index
- assert_equal 'Super Firefox', @response.body
+ get :index
+ assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body
- @request.accept = "text/iphone"
- get :index
- assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
- end
+ @request.accept = "text/iphone"
+ get :index
+ assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
end
end
diff --git a/actionpack/test/controller/record_identifier_test.rb b/actionpack/test/controller/record_identifier_test.rb
index 12c1eaea69..28bc608d47 100644
--- a/actionpack/test/controller/record_identifier_test.rb
+++ b/actionpack/test/controller/record_identifier_test.rb
@@ -1,6 +1,8 @@
require 'abstract_unit'
class Comment
+ extend ActiveModel::Naming
+
attr_reader :id
def save; @id = 1 end
def new_record?; @id.nil? end
diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb
index 13247f2d08..453a77e7bc 100644
--- a/actionpack/test/controller/redirect_test.rb
+++ b/actionpack/test/controller/redirect_test.rb
@@ -4,6 +4,7 @@ class WorkshopsController < ActionController::Base
end
class Workshop
+ extend ActiveModel::Naming
attr_accessor :id, :new_record
def initialize(id, new_record)
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 9e42d1738a..9934639d21 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -301,6 +301,9 @@ class TestController < ActionController::Base
def render_implicit_html_template_from_xhr_request
end
+ def render_implicit_js_template_without_layout
+ end
+
def formatted_html_erb
end
@@ -928,16 +931,13 @@ class RenderTest < ActionController::TestCase
end
def test_should_implicitly_render_html_template_from_xhr_request
- pending
- # xhr :get, :render_implicit_html_template_from_xhr_request
- # assert_equal "XHR!\nHello HTML!", @response.body
+ xhr :get, :render_implicit_html_template_from_xhr_request
+ assert_equal "XHR!\nHello HTML!", @response.body
end
def test_should_implicitly_render_js_template_without_layout
- pending do
- get :render_implicit_js_template_without_layout, :format => :js
- assert_no_match %r{<html>}, @response.body
- end
+ get :render_implicit_js_template_without_layout, :format => :js
+ assert_no_match %r{<html>}, @response.body
end
def test_should_render_formatted_template
diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb
index 4134da3b9e..d88d5c5dac 100644
--- a/actionpack/test/controller/send_file_test.rb
+++ b/actionpack/test/controller/send_file_test.rb
@@ -45,8 +45,8 @@ class SendFileTest < ActionController::TestCase
assert_equal file_data, response.body
end
- for_tag(:old_base) do
- def test_file_stream
+ def test_file_stream
+ pending do
response = nil
assert_nothing_raised { response = process('file') }
assert_not_nil response
diff --git a/actionpack/test/dispatch/mime_type_test.rb b/actionpack/test/dispatch/mime_type_test.rb
index 27bdd10ee5..4ea0fedb8f 100644
--- a/actionpack/test/dispatch/mime_type_test.rb
+++ b/actionpack/test/dispatch/mime_type_test.rb
@@ -56,7 +56,7 @@ class MimeTypeTest < ActiveSupport::TestCase
test "type convenience methods" do
# Don't test Mime::ALL, since it Mime::ALL#html? == true
- types = Mime::SET.to_a.map{|m| m.to_sym }.uniq - [:all]
+ types = Mime::SET.symbols.uniq - [:all]
# Remove custom Mime::Type instances set in other tests, like Mime::GIF and Mime::IPHONE
types.delete_if { |type| !Mime.const_defined?(type.to_s.upcase) }
@@ -76,7 +76,7 @@ class MimeTypeTest < ActiveSupport::TestCase
end
test "verifiable mime types" do
- all_types = Mime::SET.to_a.map{|m| m.to_sym}
+ all_types = Mime::SET.symbols
all_types.uniq!
# Remove custom Mime::Type instances set in other tests, like Mime::GIF and Mime::IPHONE
all_types.delete_if { |type| !Mime.const_defined?(type.to_s.upcase) }
diff --git a/actionpack/test/fixtures/layouts/builder.builder b/actionpack/test/fixtures/layouts/builder.builder
index 729af4b8bc..7c7d4b2dd1 100644
--- a/actionpack/test/fixtures/layouts/builder.builder
+++ b/actionpack/test/fixtures/layouts/builder.builder
@@ -1,3 +1,3 @@
xml.wrapper do
- xml << @content_for_layout
+ xml << yield
end \ No newline at end of file
diff --git a/actionpack/test/fixtures/layouts/standard.html.erb b/actionpack/test/fixtures/layouts/standard.html.erb
index 368764e6f4..5e6c24fe39 100644
--- a/actionpack/test/fixtures/layouts/standard.html.erb
+++ b/actionpack/test/fixtures/layouts/standard.html.erb
@@ -1 +1 @@
-<html><%= @content_for_layout %><%= @variable_for_layout %></html> \ No newline at end of file
+<html><%= yield %><%= @variable_for_layout %></html> \ No newline at end of file
diff --git a/actionpack/test/fixtures/layouts/talk_from_action.erb b/actionpack/test/fixtures/layouts/talk_from_action.erb
index 187aab07a2..bf53fdb785 100644
--- a/actionpack/test/fixtures/layouts/talk_from_action.erb
+++ b/actionpack/test/fixtures/layouts/talk_from_action.erb
@@ -1,2 +1,2 @@
-<title><%= @title || @content_for_title %></title>
-<%= @content_for_layout -%> \ No newline at end of file
+<title><%= @title || yield(:title) %></title>
+<%= yield -%> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb b/actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb
new file mode 100644
index 0000000000..892ae5eca2
--- /dev/null
+++ b/actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb
@@ -0,0 +1 @@
+alert('hello'); \ No newline at end of file
diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb
index 0b30c79b10..9e6f14d373 100644
--- a/actionpack/test/lib/controller/fake_models.rb
+++ b/actionpack/test/lib/controller/fake_models.rb
@@ -1,4 +1,8 @@
+require "active_model"
+
class Customer < Struct.new(:name, :id)
+ extend ActiveModel::Naming
+
def to_param
id.to_s
end
@@ -12,6 +16,8 @@ end
module Quiz
class Question < Struct.new(:name, :id)
+ extend ActiveModel::Naming
+
def to_param
id.to_s
end
diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb
index 59fb6819ed..5cf414a1c6 100644
--- a/actionpack/test/lib/fixture_template.rb
+++ b/actionpack/test/lib/fixture_template.rb
@@ -1,6 +1,5 @@
module ActionView #:nodoc:
-class Template
- class FixturePath < Path
+ class FixtureResolver < Resolver
def initialize(hash = {}, options = {})
super(options)
@hash = hash
@@ -22,7 +21,7 @@ class Template
def formats_regexp
@formats_regexp ||= begin
- formats = Mime::SET.map { |m| m.symbol }
+ formats = Mime::SET.symbols
'(?:' + formats.map { |l| "\\.#{Regexp.escape(l.to_s)}" }.join('|') + ')?'
end
end
@@ -65,40 +64,4 @@ class Template
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/content_type_test.rb b/actionpack/test/new_base/content_type_test.rb
index 82b817a5a3..cfc03a3024 100644
--- a/actionpack/test/new_base/content_type_test.rb
+++ b/actionpack/test/new_base/content_type_test.rb
@@ -19,7 +19,7 @@ module ContentType
class ImpliedController < ActionController::Base
# Template's mime type is used if no content_type is specified
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"content_type/implied/i_am_html_erb.html.erb" => "Hello world!",
"content_type/implied/i_am_xml_erb.xml.erb" => "<xml>Hello world!</xml>",
"content_type/implied/i_am_html_builder.html.builder" => "xml.p 'Hello'",
diff --git a/actionpack/test/new_base/etag_test.rb b/actionpack/test/new_base/etag_test.rb
index a40d3c936a..3a69e7dac4 100644
--- a/actionpack/test/new_base/etag_test.rb
+++ b/actionpack/test/new_base/etag_test.rb
@@ -2,7 +2,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module Etags
class BasicController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"etags/basic/base.html.erb" => "Hello from without_layout.html.erb",
"layouts/etags.html.erb" => "teh <%= yield %> tagz"
)]
diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb
index 4402eadf42..dfa7cc2141 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::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"render_action/basic/hello_world.html.erb" => "Hello world!"
)]
@@ -117,7 +117,7 @@ module RenderActionWithApplicationLayout
# # ==== Render actions with layouts ====
class BasicController < ::ApplicationController
# Set the view path to an application view structure with layouts
- self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = self.view_paths = [ActionView::FixtureResolver.new(
"render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!",
"render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Omg'",
"layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI",
@@ -202,7 +202,7 @@ end
module RenderActionWithControllerLayout
class BasicController < ActionController::Base
- self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = self.view_paths = [ActionView::FixtureResolver.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"
)]
@@ -263,7 +263,7 @@ end
module RenderActionWithBothLayouts
class BasicController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new({
+ self.view_paths = [ActionView::FixtureResolver.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 2846df48da..fd96e1955f 100644
--- a/actionpack/test/new_base/render_implicit_action_test.rb
+++ b/actionpack/test/new_base/render_implicit_action_test.rb
@@ -2,7 +2,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module RenderImplicitAction
class SimpleController < ::ApplicationController
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"render_implicit_action/simple/hello_world.html.erb" => "Hello world!",
"render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!"
)]
diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb
index f32c60d683..279b807a5f 100644
--- a/actionpack/test/new_base/render_layout_test.rb
+++ b/actionpack/test/new_base/render_layout_test.rb
@@ -2,7 +2,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module ControllerLayouts
class ImplicitController < ::ApplicationController
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI",
"layouts/override.html.erb" => "Override! <%= yield %>",
"basic.html.erb" => "Hello world!",
@@ -26,7 +26,7 @@ module ControllerLayouts
end
class ImplicitNameController < ::ApplicationController
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI",
"basic.html.erb" => "Hello world!"
)]
@@ -68,7 +68,7 @@ module ControllerLayouts
end
class MismatchFormatController < ::ApplicationController
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"layouts/application.html.erb" => "<html><%= yield %></html>",
"controller_layouts/mismatch_format/index.js.rjs" => "page[:test].omg",
"controller_layouts/mismatch_format/implicit.rjs" => "page[:test].omg"
diff --git a/actionpack/test/new_base/render_partial_test.rb b/actionpack/test/new_base/render_partial_test.rb
index 3a300afe5c..bbb98a0c01 100644
--- a/actionpack/test/new_base/render_partial_test.rb
+++ b/actionpack/test/new_base/render_partial_test.rb
@@ -4,7 +4,7 @@ module RenderPartial
class BasicController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"render_partial/basic/_basic.html.erb" => "OMG!",
"render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>"
)]
diff --git a/actionpack/test/new_base/render_rjs_test.rb b/actionpack/test/new_base/render_rjs_test.rb
new file mode 100644
index 0000000000..bd4c87b3bf
--- /dev/null
+++ b/actionpack/test/new_base/render_rjs_test.rb
@@ -0,0 +1,46 @@
+require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+
+module RenderRjs
+
+ class BasicController < ActionController::Base
+
+ self.view_paths = [ActionView::FixtureResolver.new(
+ "render_rjs/basic/index.js.rjs" => "page[:customer].replace_html render(:partial => 'customer')",
+ "render_rjs/basic/index_html.js.rjs" => "page[:customer].replace_html :partial => 'customer'",
+ "render_rjs/basic/_customer.js.erb" => "JS Partial",
+ "render_rjs/basic/_customer.html.erb" => "HTML Partial",
+ "render_rjs/basic/index_locale.js.rjs" => "page[:customer].replace_html :partial => 'customer'",
+ "render_rjs/basic/_customer.da.html.erb" => "Danish HTML Partial",
+ "render_rjs/basic/_customer.da.js.erb" => "Danish JS Partial"
+ )]
+
+ def index
+ render
+ end
+
+ def index_locale
+ old_locale, I18n.locale = I18n.locale, :da
+ end
+
+ end
+
+ class TestBasic < SimpleRouteCase
+ testing BasicController
+
+ test "rendering a partial in an RJS template should pick the JS template over the HTML one" do
+ get :index
+ assert_response("$(\"customer\").update(\"JS Partial\");")
+ end
+
+ test "replacing an element with a partial in an RJS template should pick the HTML template over the JS one" do
+ get :index_html
+ assert_response("$(\"customer\").update(\"HTML Partial\");")
+ end
+
+ test "replacing an element with a partial in an RJS template with a locale should pick the localed HTML template" do
+ get :index_locale, :format => :js
+ assert_response("$(\"customer\").update(\"Danish HTML Partial\");")
+ end
+
+ 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 face5b7571..94ea38fc7b 100644
--- a/actionpack/test/new_base/render_template_test.rb
+++ b/actionpack/test/new_base/render_template_test.rb
@@ -3,7 +3,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module RenderTemplate
class WithoutLayoutController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"test/basic.html.erb" => "Hello from basic.html.erb",
"shared.html.erb" => "Elastica",
"locals.html.erb" => "The secret is <%= secret %>",
@@ -79,7 +79,7 @@ module RenderTemplate
end
class WithLayoutController < ::ApplicationController
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"test/basic.html.erb" => "Hello from basic.html.erb",
"shared.html.erb" => "Elastica",
"layouts/application.html.erb" => "<%= yield %>, I'm here!",
@@ -148,7 +148,7 @@ module RenderTemplate
module Compatibility
class WithoutLayoutController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.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 ed3d50fa0b..5783b4766a 100644
--- a/actionpack/test/new_base/render_test.rb
+++ b/actionpack/test/new_base/render_test.rb
@@ -2,7 +2,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module Render
class BlankRenderController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"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 %>",
diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb
index 4a90eaac40..84f77432c9 100644
--- a/actionpack/test/new_base/render_text_test.rb
+++ b/actionpack/test/new_base/render_text_test.rb
@@ -2,7 +2,7 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module RenderText
class SimpleController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new]
+ self.view_paths = [ActionView::FixtureResolver.new]
def index
render :text => "hello david"
@@ -10,7 +10,7 @@ module RenderText
end
class WithLayoutController < ::ApplicationController
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"layouts/application.html.erb" => "<%= yield %>, I'm here!",
"layouts/greetings.html.erb" => "<%= yield %>, I wish thee well.",
"layouts/ivar.html.erb" => "<%= yield %>, <%= @ivar %>"
diff --git a/actionpack/test/new_base/render_xml_test.rb b/actionpack/test/new_base/render_xml_test.rb
index e6c40b1533..a3890ddfb2 100644
--- a/actionpack/test/new_base/render_xml_test.rb
+++ b/actionpack/test/new_base/render_xml_test.rb
@@ -4,7 +4,7 @@ module RenderXml
# This has no layout and it works
class BasicController < ActionController::Base
- self.view_paths = [ActionView::Template::FixturePath.new(
+ self.view_paths = [ActionView::FixtureResolver.new(
"render_xml/basic/with_render_erb" => "Hello world!"
)]
end
diff --git a/actionpack/test/template/active_record_helper_test.rb b/actionpack/test/template/active_record_helper_test.rb
index b4b8cbe074..4691049a41 100644
--- a/actionpack/test/template/active_record_helper_test.rb
+++ b/actionpack/test/template/active_record_helper_test.rb
@@ -33,8 +33,8 @@ class ActiveRecordHelperTest < ActionView::TestCase
["Author name can't be <em>empty</em>"]
end
- def on(field)
- "can't be <em>empty</em>"
+ def [](field)
+ ["can't be <em>empty</em>"]
end
end
@@ -47,14 +47,14 @@ class ActiveRecordHelperTest < ActionView::TestCase
@post = Post.new
def @post.errors
Class.new {
- def on(field)
+ def [](field)
case field.to_s
when "author_name"
- "can't be empty"
+ ["can't be empty"]
when "body"
- true
+ ['foo']
else
- false
+ []
end
end
def empty?() false end
@@ -85,7 +85,7 @@ class ActiveRecordHelperTest < ActionView::TestCase
@user = User.new
def @user.errors
Class.new {
- def on(field) field == "email" end
+ def [](field) field == "email" ? ['nonempty'] : [] end
def empty?() false end
def count() 1 end
def full_messages() [ "User email can't be empty" ] end
diff --git a/actionpack/test/template/atom_feed_helper_test.rb b/actionpack/test/template/atom_feed_helper_test.rb
index bd97caf5d7..6f1179f359 100644
--- a/actionpack/test/template/atom_feed_helper_test.rb
+++ b/actionpack/test/template/atom_feed_helper_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
Scroll = Struct.new(:id, :to_param, :title, :body, :updated_at, :created_at)
+Scroll.extend ActiveModel::Naming
class ScrollsController < ActionController::Base
FEEDS = {}
diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb
index 4e7aa63f96..bac67c1a7d 100644
--- a/actionpack/test/template/body_parts_test.rb
+++ b/actionpack/test/template/body_parts_test.rb
@@ -4,9 +4,8 @@ class BodyPartsTest < ActionController::TestCase
RENDERINGS = [Object.new, Object.new, Object.new]
class TestController < ActionController::Base
- def performed?
- defined?(ActionController::Http) ? true : super
- end
+ def performed?() true end
+
def index
RENDERINGS.each do |rendering|
@template.punctuate_body! rendering
@@ -19,11 +18,9 @@ class BodyPartsTest < ActionController::TestCase
def test_body_parts
get :index
- pending(:old_base) do
- # TestProcess buffers body_parts into body
- # TODO: Rewrite test w/o going through process
- assert_equal RENDERINGS, @response.body_parts
- end
+ # TestProcess buffers body_parts into body
+ # TODO: Rewrite test w/o going through process
+ assert_equal RENDERINGS, @response.body_parts
assert_equal RENDERINGS.join, @response.body
end
end
diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb
new file mode 100644
index 0000000000..2017a18806
--- /dev/null
+++ b/actionpack/test/template/capture_helper_test.rb
@@ -0,0 +1,15 @@
+require 'abstract_unit'
+
+class CaptureHelperTest < ActionView::TestCase
+ def setup
+ super
+ @_content_for = Hash.new {|h,k| h[k] = "" }
+ end
+
+ def test_content_for
+ assert ! content_for?(:title)
+ content_for :title, 'title'
+ assert content_for?(:title)
+ assert ! content_for?(:something_else)
+ end
+end
diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb
index b29b03f99d..9c268aef27 100644
--- a/actionpack/test/template/compiled_templates_test.rb
+++ b/actionpack/test/template/compiled_templates_test.rb
@@ -41,7 +41,7 @@ class CompiledTemplatesTest < Test::Unit::TestCase
end
def render_without_cache(*args)
- path = ActionView::Template::FileSystemPathWithFallback.new(FIXTURE_LOAD_PATH)
+ path = ActionView::FileSystemResolverWithFallback.new(FIXTURE_LOAD_PATH)
view_paths = ActionView::Base.process_view_paths(path)
ActionView::Base.new(view_paths, {}).render(*args)
end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 947668ccc6..f8215132e3 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -50,7 +50,7 @@ class FormHelperTest < ActionView::TestCase
@comment = Comment.new
def @post.errors()
Class.new{
- def on(field); "can't be empty" if field == "author_name"; end
+ def [](field); field == "author_name" ? ["can't be empty"] : [] end
def empty?() false end
def count() 1 end
def full_messages() [ "Author name can't be empty" ] end
@@ -1193,4 +1193,4 @@ class FormHelperTest < ActionView::TestCase
def protect_against_forgery?
false
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb
index f9f418aec9..02b1d137f5 100644
--- a/actionpack/test/template/prototype_helper_test.rb
+++ b/actionpack/test/template/prototype_helper_test.rb
@@ -1,8 +1,10 @@
require 'abstract_unit'
Bunny = Struct.new(:Bunny, :id)
+Bunny.extend ActiveModel::Naming
class Author
+ extend ActiveModel::Naming
attr_reader :id
def save; @id = 1 end
def new_record?; @id.nil? end
@@ -12,6 +14,7 @@ class Author
end
class Article
+ extend ActiveModel::Naming
attr_reader :id
attr_reader :author_id
def save; @id = 1; @author_id = 1 end
diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb
index 809ed6d6af..5b840d123b 100644
--- a/actionpack/test/template/record_tag_helper_test.rb
+++ b/actionpack/test/template/record_tag_helper_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
class Post
+ extend ActiveModel::Naming
def id
45
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 2ed11aa3c0..7f30ae88a1 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -46,29 +46,6 @@ module RenderTestCases
I18n.locale = old_locale
end
- def test_render_implicit_html_template_from_xhr_request
- old_format = @view.formats
- pending do
- @view.formats = [:js]
- assert_equal "Hello HTML!", @view.render(:file => "test/render_implicit_html_template_from_xhr_request")
- end
- ensure
- @view.formats = old_format
- end
-
- def test_render_implicit_html_template_from_xhr_request_with_localization
- old_locale = I18n.locale
- old_format = @view.formats
- pending do
- I18n.locale = :da
- @view.formats = [:js]
- assert_equal "Hey HTML!\n", @view.render(:file => "test/render_implicit_html_template_from_xhr_request")
- end
- ensure
- I18n.locale = old_locale
- @view.formats = old_format
- end
-
def test_render_file_at_top_level
assert_equal 'Elastica', @view.render(:file => '/shared')
end
@@ -278,7 +255,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase
# Ensure view path cache is primed
def setup
view_paths = ActionController::Base.view_paths
- assert_equal ActionView::Template::FileSystemPathWithFallback, view_paths.first.class
+ assert_equal ActionView::FileSystemResolverWithFallback, view_paths.first.class
setup_view(view_paths)
end
end
@@ -289,9 +266,9 @@ class LazyViewRenderTest < ActiveSupport::TestCase
# Test the same thing as above, but make sure the view path
# is not eager loaded
def setup
- path = ActionView::Template::FileSystemPathWithFallback.new(FIXTURE_LOAD_PATH)
+ path = ActionView::FileSystemResolverWithFallback.new(FIXTURE_LOAD_PATH)
view_paths = ActionView::Base.process_view_paths(path)
- assert_equal ActionView::Template::FileSystemPathWithFallback, view_paths.first.class
+ assert_equal ActionView::FileSystemResolverWithFallback, view_paths.first.class
setup_view(view_paths)
end
end
diff --git a/actionpack/test/template/test_test.rb b/actionpack/test/template/test_test.rb
index dd07a6d438..f32d0b3d42 100644
--- a/actionpack/test/template/test_test.rb
+++ b/actionpack/test/template/test_test.rb
@@ -41,6 +41,7 @@ class PeopleHelperTest < ActionView::TestCase
def test_link_to_person
person = mock(:name => "David")
+ person.class.extend ActiveModel::Naming
expects(:mocha_mock_path).with(person).returns("/people/1")
assert_equal '<a href="/people/1">David</a>', link_to_person(person)
end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index f3d2f87b4a..f0364fd660 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -494,6 +494,7 @@ class LinkToUnlessCurrentWithControllerTest < ActionView::TestCase
end
class Workshop
+ extend ActiveModel::Naming
attr_accessor :id, :new_record
def initialize(id, new_record)
@@ -510,6 +511,7 @@ class Workshop
end
class Session
+ extend ActiveModel::Naming
attr_accessor :id, :workshop_id, :new_record
def initialize(id, new_record)
diff --git a/activemodel/lib/active_model.rb b/activemodel/lib/active_model.rb
index 73cee9b88f..544121c593 100644
--- a/activemodel/lib/active_model.rb
+++ b/activemodel/lib/active_model.rb
@@ -26,15 +26,22 @@ $:.unshift(activesupport_path) if File.directory?(activesupport_path)
require 'active_support'
module ActiveModel
+ autoload :Attributes, 'active_model/attributes'
autoload :Base, 'active_model/base'
autoload :DeprecatedErrorMethods, 'active_model/deprecated_error_methods'
autoload :Errors, 'active_model/errors'
+ autoload :Name, 'active_model/naming'
+ autoload :Naming, 'active_model/naming'
autoload :Observer, 'active_model/observing'
autoload :Observing, 'active_model/observing'
autoload :StateMachine, 'active_model/state_machine'
autoload :TestCase, 'active_model/test_case'
autoload :Validations, 'active_model/validations'
autoload :ValidationsRepairHelper, 'active_model/validations_repair_helper'
+
+ module Serializers
+ autoload :JSON, 'active_model/serializers/json'
+ end
end
I18n.load_path << File.dirname(__FILE__) + '/active_model/locale/en.yml'
diff --git a/activemodel/lib/active_model/attributes.rb b/activemodel/lib/active_model/attributes.rb
new file mode 100644
index 0000000000..4665525281
--- /dev/null
+++ b/activemodel/lib/active_model/attributes.rb
@@ -0,0 +1,17 @@
+require 'active_support/core_ext/object/instance_variables'
+
+module ActiveModel
+ module Attributes
+ def attributes
+ instance_values
+ end
+
+ def read_attribute(attr_name)
+ instance_variable_get(:"@#{attr_name}")
+ end
+
+ def write_attribute(attr_name, value)
+ instance_variable_set(:"@#{attr_name}", value)
+ end
+ end
+end
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 2e643f108f..a4cf700231 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -68,7 +68,7 @@ module ActiveModel
# Will add an error message to each of the attributes in +attributes+ that is empty.
def add_on_empty(attributes, custom_message = nil)
[attributes].flatten.each do |attribute|
- value = @base.get_attribute_value(attribute)
+ value = @base.send(attribute)
is_empty = value.respond_to?(:empty?) ? value.empty? : false
add(attribute, :empty, :default => custom_message) unless !value.nil? && !is_empty
end
@@ -77,7 +77,7 @@ module ActiveModel
# Will add an error message to each of the attributes in +attributes+ that is blank (using Object#blank?).
def add_on_blank(attributes, custom_message = nil)
[attributes].flatten.each do |attribute|
- value = @base.get_attribute_value(attribute)
+ value = @base.send(attribute)
add(attribute, :blank, :default => custom_message) if value.blank?
end
end
@@ -146,7 +146,7 @@ module ActiveModel
defaults = defaults.compact.flatten << :"messages.#{message}"
key = defaults.shift
- value = @base.get_attribute_value(attribute)
+ value = @base.send(attribute)
options = { :default => defaults,
:model => @base.class.name.humanize,
diff --git a/activesupport/lib/active_support/core_ext/module/model_naming.rb b/activemodel/lib/active_model/naming.rb
index 13420bab07..ffb44e3824 100644
--- a/activesupport/lib/active_support/core_ext/module/model_naming.rb
+++ b/activemodel/lib/active_model/naming.rb
@@ -1,7 +1,7 @@
require 'active_support/inflector'
-module ActiveSupport
- class ModelName < String
+module ActiveModel
+ class Name < String
attr_reader :singular, :plural, :element, :collection, :partial_path
alias_method :cache_key, :collection
@@ -14,12 +14,12 @@ module ActiveSupport
@partial_path = "#{@collection}/#{@element}".freeze
end
end
-end
-class Module
- # Returns an ActiveSupport::ModelName object for module. It can be
- # used to retrieve all kinds of naming-related information.
- def model_name
- @model_name ||= ActiveSupport::ModelName.new(name)
+ module Naming
+ # Returns an ActiveModel::Name object for module. It can be
+ # used to retrieve all kinds of naming-related information.
+ def model_name
+ @_model_name ||= ActiveModel::Name.new(name)
+ end
end
end
diff --git a/activemodel/lib/active_model/serializers/json.rb b/activemodel/lib/active_model/serializers/json.rb
new file mode 100644
index 0000000000..60b5cbe948
--- /dev/null
+++ b/activemodel/lib/active_model/serializers/json.rb
@@ -0,0 +1,38 @@
+require 'active_support/json'
+require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/hash/slice'
+
+module ActiveModel
+ module Serializers
+ module JSON
+ extend ActiveSupport::Concern
+ include ActiveModel::Attributes
+
+ included do
+ cattr_accessor :include_root_in_json, :instance_writer => false
+ end
+
+ def encode_json(encoder)
+ options = encoder.options || {}
+
+ hash = if options[:only]
+ only = Array.wrap(options[:only]).map { |attr| attr.to_s }
+ attributes.slice(*only)
+ elsif options[:except]
+ except = Array.wrap(options[:except]).map { |attr| attr.to_s }
+ attributes.except(*except)
+ else
+ attributes
+ end
+
+ hash = { self.class.model_name.element => hash } if include_root_in_json
+ ActiveSupport::JSON.encode(hash)
+ end
+
+ def as_json(options = nil)
+ self
+ end
+ end
+ end
+end
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 6b6f51d942..5223cea135 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -64,7 +64,7 @@ module ActiveModel
# Declare the validation.
send(validation_method(options[:on]), options) do |record|
attrs.each do |attr|
- value = record.get_attribute_value(attr)
+ value = record.send(attr)
next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
yield record, attr, value
end
@@ -93,10 +93,6 @@ module ActiveModel
def invalid?
!valid?
end
-
- def get_attribute_value(attribute)
- respond_to?(attribute.to_sym) ? send(attribute.to_sym) : instance_variable_get(:"@#{attribute}")
- end
end
end
diff --git a/activemodel/test/cases/attributes_test.rb b/activemodel/test/cases/attributes_test.rb
new file mode 100644
index 0000000000..5f3ea839a4
--- /dev/null
+++ b/activemodel/test/cases/attributes_test.rb
@@ -0,0 +1,30 @@
+require 'cases/helper'
+
+class AttributesTest < ActiveModel::TestCase
+ class Person
+ include ActiveModel::Attributes
+ attr_accessor :name
+ end
+
+ test "reads attribute" do
+ p = Person.new
+ assert_equal nil, p.read_attribute(:name)
+
+ p.name = "Josh"
+ assert_equal "Josh", p.read_attribute(:name)
+ end
+
+ test "writes attribute" do
+ p = Person.new
+ assert_equal nil, p.name
+
+ p.write_attribute(:name, "Josh")
+ assert_equal "Josh", p.name
+ end
+
+ test "returns all attributes" do
+ p = Person.new
+ p.name = "Josh"
+ assert_equal({"name" => "Josh"}, p.attributes)
+ end
+end
diff --git a/activemodel/test/cases/json_serialization_test.rb b/activemodel/test/cases/json_serialization_test.rb
new file mode 100644
index 0000000000..abcec67a85
--- /dev/null
+++ b/activemodel/test/cases/json_serialization_test.rb
@@ -0,0 +1,64 @@
+require 'cases/helper'
+
+class JsonSerializationTest < ActiveModel::TestCase
+ class Contact
+ extend ActiveModel::Naming
+ include ActiveModel::Serializers::JSON
+ attr_accessor :name, :age, :created_at, :awesome, :preferences
+ end
+
+ def setup
+ @contact = Contact.new
+ @contact.name = 'Konata Izumi'
+ @contact.age = 16
+ @contact.created_at = Time.utc(2006, 8, 1)
+ @contact.awesome = true
+ @contact.preferences = { 'shows' => 'anime' }
+ end
+
+ test "should include root in json" do
+ begin
+ Contact.include_root_in_json = true
+ json = @contact.to_json
+
+ assert_match %r{^\{"contact":\{}, json
+ assert_match %r{"name":"Konata Izumi"}, json
+ assert_match %r{"age":16}, json
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_match %r{"awesome":true}, json
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
+ ensure
+ Contact.include_root_in_json = false
+ end
+ end
+
+ test "should encode all encodable attributes" do
+ json = @contact.to_json
+
+ assert_match %r{"name":"Konata Izumi"}, json
+ assert_match %r{"age":16}, json
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_match %r{"awesome":true}, json
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
+ end
+
+ test "should allow attribute filtering with only" do
+ json = @contact.to_json(:only => [:name, :age])
+
+ assert_match %r{"name":"Konata Izumi"}, json
+ assert_match %r{"age":16}, json
+ assert_no_match %r{"awesome":true}, json
+ assert !json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_no_match %r{"preferences":\{"shows":"anime"\}}, json
+ end
+
+ test "should allow attribute filtering with except" do
+ json = @contact.to_json(:except => [:name, :age])
+
+ assert_no_match %r{"name":"Konata Izumi"}, json
+ assert_no_match %r{"age":16}, json
+ assert_match %r{"awesome":true}, json
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
+ end
+end
diff --git a/activesupport/test/core_ext/module/model_naming_test.rb b/activemodel/test/cases/naming_test.rb
index 37119f378a..e75d4541a3 100644
--- a/activesupport/test/core_ext/module/model_naming_test.rb
+++ b/activemodel/test/cases/naming_test.rb
@@ -1,9 +1,8 @@
-require 'abstract_unit'
-require 'active_support/core_ext/module/model_naming'
+require 'cases/helper'
-class ModelNamingTest < Test::Unit::TestCase
+class NamingTest < Test::Unit::TestCase
def setup
- @model_name = ActiveSupport::ModelName.new('Post::TrackBack')
+ @model_name = ActiveModel::Name.new('Post::TrackBack')
end
def test_singular
diff --git a/activemodel/test/cases/validations/presence_validation_test.rb b/activemodel/test/cases/validations/presence_validation_test.rb
index f6bed4903a..aa5bdf1e62 100644
--- a/activemodel/test/cases/validations/presence_validation_test.rb
+++ b/activemodel/test/cases/validations/presence_validation_test.rb
@@ -31,15 +31,15 @@ class PresenceValidationTest < ActiveModel::TestCase
assert t.save
end
- def test_validates_presence_of_with_custom_message_using_quotes
- repair_validations(Developer) do
- Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes"
- d = Developer.new
- d.name = "Joe"
- assert !d.valid?
- assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:non_existent]
- end
- end
+ # def test_validates_presence_of_with_custom_message_using_quotes
+ # repair_validations(Developer) do
+ # Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes"
+ # d = Developer.new
+ # d.name = "Joe"
+ # assert !d.valid?
+ # assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:non_existent]
+ # end
+ # end
def test_validates_presence_of_for_ruby_class
repair_validations(Person) do
diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb
index 137b491f28..c172e7b8f9 100644
--- a/activerecord/lib/active_record/associations/through_association_scope.rb
+++ b/activerecord/lib/active_record/associations/through_association_scope.rb
@@ -94,10 +94,17 @@ module ActiveRecord
def construct_join_attributes(associate)
# TODO: revist this to allow it for deletion, supposing dependent option is supported
raise ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection.new(@owner, @reflection) if @reflection.source_reflection.macro == :has_many
+
join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id)
+
if @reflection.options[:source_type]
join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s)
end
+
+ if @reflection.through_reflection.options[:conditions].is_a?(Hash)
+ join_attributes.merge!(@reflection.through_reflection.options[:conditions])
+ end
+
join_attributes
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index cc601b0d11..2453d38aca 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -3155,6 +3155,7 @@ module ActiveRecord #:nodoc:
end
Base.class_eval do
+ extend ActiveModel::Naming
extend QueryCache::ClassMethods
include Validations
include Locking::Optimistic, Locking::Pessimistic
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 2f01a303e5..8e33681772 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -101,7 +101,7 @@ module ActiveRecord
table_definition = TableDefinition.new(self)
table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name)) unless options[:id] == false
- yield table_definition
+ yield table_definition if block_given?
if options[:force] && table_exists?(table_name)
drop_table(table_name, options)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index cabb63bfaf..b33c460a93 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -246,7 +246,7 @@ module ActiveRecord
end
def rename_table(name, new_name)
- execute "ALTER TABLE #{name} RENAME TO #{new_name}"
+ execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
end
# See: http://www.sqlite.org/lang_altertable.html
diff --git a/activerecord/lib/active_record/serializers/json_serializer.rb b/activerecord/lib/active_record/serializers/json_serializer.rb
index e49cf59494..21afcd6e5c 100644
--- a/activerecord/lib/active_record/serializers/json_serializer.rb
+++ b/activerecord/lib/active_record/serializers/json_serializer.rb
@@ -1,5 +1,5 @@
require 'active_support/json'
-require 'active_support/core_ext/module/model_naming'
+require 'active_model/naming'
module ActiveRecord #:nodoc:
module Serialization
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index a150ba4acf..7ac6f6fe3b 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -194,10 +194,6 @@ module ActiveRecord
def errors
@errors ||= Errors.new(self)
end
-
- def get_attribute_value(attribute)
- respond_to?(attribute.to_sym) ? send(attribute.to_sym) : self[attribute.to_sym]
- end
end
end
end
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 4254badef2..7a4712d7c8 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -157,6 +157,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal peeps + 1, posts(:thinking).people.count
end
+ def test_associate_with_create_with_through_having_conditions
+ impatient_people = posts(:thinking).impatient_people.count
+ posts(:thinking).impatient_people.create!(:first_name => 'foo')
+ assert_equal impatient_people + 1, posts(:thinking).impatient_people.count
+ end
+
def test_associate_with_create_exclamation_and_no_options
peeps = posts(:thinking).people.count
posts(:thinking).people.create!(:first_name => 'foo')
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 16861f21b1..215b5a427a 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -293,6 +293,13 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.connection.drop_table table_name rescue nil
end
+ def test_create_table_without_a_block
+ table_name = :testings
+ Person.connection.create_table table_name
+ ensure
+ Person.connection.drop_table table_name rescue nil
+ end
+
# Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value.
unless current_adapter?(:SybaseAdapter, :SQLiteAdapter)
@@ -635,6 +642,32 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
+ if current_adapter?(:SQLiteAdapter)
+ def test_rename_table_for_sqlite_should_work_with_reserved_words
+ begin
+ assert_nothing_raised do
+ ActiveRecord::Base.connection.rename_table :references, :old_references
+ ActiveRecord::Base.connection.create_table :octopuses do |t|
+ t.column :url, :string
+ end
+ end
+
+ assert_nothing_raised { ActiveRecord::Base.connection.rename_table :octopuses, :references }
+
+ # Using explicit id in insert for compatibility across all databases
+ con = ActiveRecord::Base.connection
+ assert_nothing_raised do
+ con.execute "INSERT INTO 'references' (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://rubyonrails.com')"
+ end
+ assert_equal 'http://rubyonrails.com', ActiveRecord::Base.connection.select_value("SELECT url FROM 'references' WHERE id=1")
+
+ ensure
+ ActiveRecord::Base.connection.drop_table :references
+ ActiveRecord::Base.connection.rename_table :old_references, :references
+ end
+ end
+ end
+
def test_rename_table
begin
ActiveRecord::Base.connection.create_table :octopuses do |t|
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index 374e536a5b..7392515ec7 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -69,6 +69,8 @@ class Post < ActiveRecord::Base
:after_add => lambda {|owner, reader| log(:added, :after, reader.first_name) },
:before_remove => lambda {|owner, reader| log(:removed, :before, reader.first_name) },
:after_remove => lambda {|owner, reader| log(:removed, :after, reader.first_name) }
+ has_many :skimmers, :class_name => 'Reader', :conditions => { :skimmer => true }
+ has_many :impatient_people, :through => :skimmers, :source => :person
def self.top(limit)
ranked_by_comments.limit(limit)
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index b2aaccb352..d2d6d1f4b3 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -364,6 +364,7 @@ ActiveRecord::Schema.define do
create_table :readers, :force => true do |t|
t.integer :post_id, :null => false
t.integer :person_id, :null => false
+ t.boolean :skimmer, :default => false
end
create_table :shape_expressions, :force => true do |t|
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index a4f2a7e16a..f919f911e4 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -1086,6 +1086,7 @@ module ActiveResource
end
class Base
+ extend ActiveModel::Naming
include CustomMethods, Validations
end
end
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index feb6b1f2cf..192a82e74f 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -129,8 +129,8 @@ module ActiveSupport
#
# For example, MemCacheStore's #write method supports the +:expires_in+
# option, which tells the memcached server to automatically expire the
- # cache item after a certain period. We can use this option with #fetch
- # too:
+ # cache item after a certain period. This options is also supported by
+ # FileStore's #read method. We can use this option with #fetch too:
#
# cache = ActiveSupport::Cache::MemCacheStore.new
# cache.fetch("foo", :force => true, :expires_in => 5.seconds) do
@@ -169,6 +169,10 @@ module ActiveSupport
# You may also specify additional options via the +options+ argument.
# The specific cache store implementation will decide what to do with
# +options+.
+ #
+ # For example, FileStore supports the +:expires_in+ option, which
+ # makes the method return nil for cache items older than the specified
+ # period.
def read(key, options = nil)
log("read", key, options)
end
@@ -223,6 +227,10 @@ module ActiveSupport
end
private
+ def expires_in(options)
+ (options && options[:expires_in]) || 0
+ end
+
def log(operation, key, options)
logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off
end
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 3217350d58..75eed5ed94 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -10,11 +10,23 @@ module ActiveSupport
@cache_path = cache_path
end
+ # Reads a value from the cache.
+ #
+ # Possible options:
+ # - +:expires_in+ - the number of seconds that this value may stay in
+ # the cache.
def read(name, options = nil)
super
- File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil
+
+ file_name = real_file_path(name)
+ expires = expires_in(options)
+
+ if File.exist?(file_name) && (expires <= 0 || Time.now - File.mtime(file_name) < expires)
+ File.open(file_name, 'rb') { |f| Marshal.load(f) }
+ end
end
+ # Writes a value to the cache.
def write(name, value, options = nil)
super
ensure_cache_path(File.dirname(real_file_path(name)))
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index 38b3409ca6..954d0f5423 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -130,10 +130,6 @@ module ActiveSupport
end
private
- def expires_in(options)
- (options && options[:expires_in]) || 0
- end
-
def raw?(options)
options && options[:raw]
end
diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb
index 215c47b114..fbe89fe07c 100644
--- a/activesupport/lib/active_support/core_ext/module.rb
+++ b/activesupport/lib/active_support/core_ext/module.rb
@@ -7,5 +7,4 @@ require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/attr_accessor_with_default'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/loading'
-require 'active_support/core_ext/module/model_naming'
require 'active_support/core_ext/module/synchronization'
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
index b4e4177724..356b6cebeb 100644
--- a/activesupport/lib/active_support/json/decoding.rb
+++ b/activesupport/lib/active_support/json/decoding.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/core_ext/module/delegation'
module ActiveSupport
# Look for and parse json strings that look like ISO 8601 times.
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 907094a747..068b58b997 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -4,6 +4,11 @@ require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/object/instance_variables'
require 'active_support/deprecation'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/time_with_zone'
+require 'active_support/values/time_zone'
+
# Hack to load json gem first so we can overwrite its to_json.
begin
require 'json'
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 51d04d9388..c2a03818e1 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -146,6 +146,22 @@ class FileStoreTest < ActiveSupport::TestCase
end
include CacheStoreBehavior
+
+ def test_expires_in
+ time = Time.local(2008, 4, 24)
+ Time.stubs(:now).returns(time)
+ File.stubs(:mtime).returns(time)
+
+ @cache.write('foo', 'bar')
+ cache_read = lambda { @cache.read('foo', :expires_in => 1.minute) }
+ assert_equal 'bar', cache_read.call
+
+ Time.stubs(:now).returns(time + 30.seconds)
+ assert_equal 'bar', cache_read.call
+
+ Time.stubs(:now).returns(time + 2.minutes)
+ assert_nil cache_read.call
+ end
end
class MemoryStoreTest < ActiveSupport::TestCase
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index 9148bddaf2..1aa71c31b5 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -401,7 +401,7 @@ Run `rake gems:install` to install the missing gems.
def load_view_paths
if configuration.frameworks.include?(:action_view)
if configuration.cache_classes
- view_path = ActionView::Template::FileSystemPath.new(configuration.view_path)
+ view_path = ActionView::FileSystemResolverWithFallback.new(configuration.view_path)
ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller)
ActionMailer::Base.template_root = view_path if configuration.frameworks.include?(:action_mailer)
end
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index 3deb81965c..6a60908859 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
require 'action_controller'
-require 'action_controller/testing/process2'
+require 'action_controller/testing/process'
require 'rails/info'
require 'rails/info_controller'