Permalink
Browse files

Merge commit 'rails/master'

  • Loading branch information...
2 parents 4996d1a + 467d251 commit 11161e6c96fb6686a33e05ead106b96089ff9790 @fxn fxn committed Apr 3, 2010
Showing with 653 additions and 592 deletions.
  1. +1 −1 Gemfile
  2. +1 −0 actionpack/lib/action_dispatch/railtie.rb
  3. +28 −25 actionpack/lib/action_dispatch/routing/mapper.rb
  4. +1 −3 actionpack/lib/action_dispatch/testing/integration.rb
  5. +6 −1 actionpack/lib/action_view/base.rb
  6. +3 −6 actionpack/lib/action_view/helpers.rb
  7. +1 −0 actionpack/lib/action_view/helpers/form_helper.rb
  8. +37 −15 actionpack/lib/action_view/helpers/url_helper.rb
  9. +2 −2 actionpack/lib/action_view/render/partials.rb
  10. +9 −0 actionpack/lib/action_view/template.rb
  11. +6 −1 actionpack/lib/action_view/test_case.rb
  12. +20 −0 actionpack/test/abstract_unit.rb
  13. +43 −8 actionpack/test/dispatch/routing_test.rb
  14. +4 −5 actionpack/test/template/active_model_helper_test.rb
  15. +11 −15 actionpack/test/template/asset_tag_helper_test.rb
  16. +2 −9 actionpack/test/template/erb/helper.rb
  17. +9 −9 actionpack/test/template/form_helper_test.rb
  18. +9 −5 actionpack/test/template/form_tag_helper_test.rb
  19. +12 −13 actionpack/test/template/prototype_helper_test.rb
  20. +8 −0 actionpack/test/template/render_test.rb
  21. +14 −19 actionpack/test/template/scriptaculous_helper_test.rb
  22. +204 −215 actionpack/test/template/url_helper_test.rb
  23. +2 −0 activemodel/lib/active_model/errors.rb
  24. +10 −0 activemodel/test/cases/validations/i18n_validation_test.rb
  25. +10 −0 activerecord/CHANGELOG
  26. +22 −51 activerecord/lib/active_record/associations.rb
  27. +1 −1 activerecord/lib/active_record/associations/through_association_scope.rb
  28. +25 −108 activerecord/lib/active_record/named_scope.rb
  29. +11 −0 activerecord/lib/active_record/reflection.rb
  30. +20 −1 activerecord/lib/active_record/relation.rb
  31. +18 −2 activerecord/lib/active_record/relation/finder_methods.rb
  32. +4 −2 activerecord/lib/active_record/relation/predicate_builder.rb
  33. +21 −4 activerecord/lib/active_record/relation/query_methods.rb
  34. +9 −6 activerecord/lib/active_record/relation/spawn_methods.rb
  35. +16 −0 activerecord/test/cases/relations_test.rb
  36. +6 −0 activerecord/test/models/post.rb
  37. +27 −63 activesupport/lib/active_support/values/time_zone.rb
  38. +8 −0 activesupport/test/time_zone_test.rb
  39. +1 −1 railties/lib/rails/application/configuration.rb
  40. +3 −0 railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
  41. +2 −1 railties/lib/rails/generators/rails/app/templates/public/index.html
  42. +6 −0 railties/test/application/middleware_test.rb
View
@@ -11,7 +11,7 @@ group :mri do
if RUBY_VERSION < '1.9'
gem "system_timer"
gem "ruby-debug", ">= 0.10.3"
- elsif RUBY_VERSION < '1.9.2'
+ elsif RUBY_VERSION < '1.9.2' && !ENV['CI']
gem "ruby-debug19"
end
end
@@ -6,6 +6,7 @@ class Railtie < Rails::Railtie
config.action_dispatch = ActiveSupport::OrderedOptions.new
config.action_dispatch.x_sendfile_header = ""
config.action_dispatch.ip_spoofing_check = true
+ config.action_dispatch.show_exceptions = true
# Prepare dispatcher callbacks and run 'prepare' callbacks
initializer "action_dispatch.prepare_dispatcher" do |app|
@@ -194,6 +194,21 @@ def match(*args)
self
end
+ def mount(app, options = nil)
+ if options
+ path = options.delete(:at)
+ else
+ options = app
+ app, path = options.find { |k, v| k.respond_to?(:call) }
+ options.delete(app) if app
+ end
+
+ raise "A rack application must be specified" unless path
+
+ match(path, options.merge(:to => app, :anchor => false))
+ self
+ end
+
def default_url_options=(options)
@set.default_url_options = options
end
@@ -380,14 +395,13 @@ def self.default_actions
[:index, :create, :new, :show, :update, :destroy, :edit]
end
- attr_reader :plural, :singular, :options
+ attr_reader :controller, :path, :options
def initialize(entities, options = {})
- @name = entities.to_s
- @options = options
-
- @plural = @name.pluralize
- @singular = @name.singularize
+ @name = entities.to_s
+ @path = options.delete(:path) || @name
+ @controller = options.delete(:controller) || @name.to_s.pluralize
+ @options = options
end
def default_actions
@@ -417,8 +431,12 @@ def name
options[:as] || @name
end
- def controller
- options[:controller] || plural
+ def plural
+ name.to_s.pluralize
+ end
+
+ def singular
+ name.to_s.singularize
end
def member_name
@@ -509,7 +527,7 @@ def resource(*resources, &block)
resource = SingletonResource.new(resources.pop, options)
- scope(:path => resource.name.to_s, :controller => resource.controller) do
+ scope(:path => resource.path, :controller => resource.controller) do
with_scope_level(:resource, resource) do
scope(:name_prefix => resource.name.to_s, :as => "") do
@@ -539,7 +557,7 @@ def resources(*resources, &block)
resource = Resource.new(resources.pop, options)
- scope(:path => resource.name.to_s, :controller => resource.controller) do
+ scope(:path => resource.path, :controller => resource.controller) do
with_scope_level(:resources, resource) do
yield if block_given?
@@ -603,21 +621,6 @@ def nested
end
end
- def mount(app, options = nil)
- if options
- path = options.delete(:at)
- else
- options = app
- app, path = options.find { |k, v| k.respond_to?(:call) }
- options.delete(app) if app
- end
-
- raise "A rack application must be specified" unless path
-
- match(path, options.merge(:to => app, :anchor => false))
- self
- end
-
def match(*args)
options = args.extract_options!
@@ -263,9 +263,7 @@ def process(method, path, parameters = nil, rack_environment = nil)
"HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
- "HTTP_ACCEPT" => accept,
-
- "action_dispatch.show_exceptions" => false
+ "HTTP_ACCEPT" => accept
}
(rack_environment || {}).each do |key, value|
@@ -168,6 +168,8 @@ module Subclasses
remove_method :helpers
attr_reader :helpers
+ class_attribute :_router
+
class << self
delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
@@ -204,7 +206,10 @@ def initialize(lookup_context = nil, assigns_for_first_render = {}, controller =
@assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
@helpers = self.class.helpers || Module.new
- @_controller = controller
+ if @_controller = controller
+ @_request = controller.request if controller.respond_to?(:request)
+ end
+
@_config = ActiveSupport::InheritableOptions.new(controller.config) if controller && controller.respond_to?(:config)
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
@_virtual_path = nil
@@ -29,16 +29,13 @@ module Helpers #:nodoc:
autoload :TranslationHelper
autoload :UrlHelper
- def self.included(base)
- base.extend(ClassMethods)
- end
+ extend ActiveSupport::Concern
- module ClassMethods
- include SanitizeHelper::ClassMethods
+ included do
+ extend SanitizeHelper::ClassMethods
end
include ActiveSupport::Benchmarkable
-
include ActiveModelHelper
include AssetTagHelper
include AtomFeedHelper
@@ -96,6 +96,7 @@ module FormHelper
extend ActiveSupport::Concern
include FormTagHelper
+ include UrlHelper
# Creates a form and a scope around a specific model object that is used
# as a base for questioning about values for the fields.
@@ -13,14 +13,15 @@ module UrlHelper
extend ActiveSupport::Concern
include ActionDispatch::Routing::UrlFor
- include JavaScriptHelper
+ include TagHelper
# Need to map default url options to controller one.
- def default_url_options(*args) #:nodoc:
- controller.send(:default_url_options, *args)
- end
-
+ # def default_url_options(*args) #:nodoc:
+ # controller.send(:default_url_options, *args)
+ # end
+ #
def url_options
+ return super unless controller.respond_to?(:url_options)
controller.url_options
end
@@ -97,7 +98,7 @@ def url_for(options = {})
when Hash
options = { :only_path => options[:host].nil? }.update(options.symbolize_keys)
escape = options.key?(:escape) ? options.delete(:escape) : false
- controller.send(:url_for, options)
+ super
when :back
escape = false
controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
@@ -119,13 +120,24 @@ def url_for(options = {})
#
# ==== Signatures
#
- # link_to(name, options = {}, html_options = nil)
- # link_to(options = {}, html_options = nil) do
+ # link_to(body, url, html_options = {})
+ # # url is a String; you can use URL helpers like
+ # # posts_path
+ #
+ # link_to(body, url_options = {}, html_options = {})
+ # # url_options, except :confirm or :method,
+ # # is passed to url_for
+ #
+ # link_to(options = {}, html_options = {}) do
+ # # name
+ # end
+ #
+ # link_to(url, html_options = {}) do
# # name
# end
#
# ==== Options
- # * <tt>:confirm => 'question?'</tt> - This will allow the unobtrusive JavaScript
+ # * <tt>:confirm => 'question?'</tt> - This will allow the unobtrusive JavaScript
# driver to prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
# * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically
@@ -138,7 +150,11 @@ def url_for(options = {})
# disabled clicking the link will have no effect. If you are relying on the
# POST behavior, you should check for it in your controller's action by using
# the request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
- # * The +html_options+ will accept a hash of html attributes for the link tag.
+ # * <tt>:remote => true</tt> - This will allow the unobtrusive JavaScript
+ # driver to make an Ajax request to the URL in question instead of following
+ # the link. The drivers each provide mechanisms for listening for the
+ # completion of the Ajax request and performing JavaScript operations once
+ # they're complete
#
# ==== Examples
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
@@ -220,8 +236,8 @@ def link_to(*args, &block)
options = args[1] || {}
html_options = args[2]
- url = url_for(options)
html_options = convert_options_to_data_attributes(options, html_options)
+ url = url_for(options)
if html_options
html_options = html_options.stringify_keys
@@ -259,10 +275,10 @@ def link_to(*args, &block)
# There are a few special +html_options+:
# * <tt>:method</tt> - Specifies the anchor name to be appended to the path.
# * <tt>:disabled</tt> - Specifies the anchor name to be appended to the path.
- # * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
+ # * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
# prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
- # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
+ # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
# submit behaviour. By default this behaviour is an ajax submit.
#
# ==== Examples
@@ -282,7 +298,7 @@ def link_to(*args, &block)
# # </form>"
#
#
- # <%= button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
+ # <%= button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
# :method => "delete", :remote => true, :disable_with => 'loading...') %>
# # => "<form class='button-to' method='post' action='http://www.example.com' data-remote='true'>
# # <div>
@@ -546,8 +562,14 @@ def mail_to(email_address, name = nil, html_options = {})
# current_page?(:controller => 'library', :action => 'checkout')
# # => false
def current_page?(options)
+ unless request
+ raise "You cannot use helpers that need to determine the current " \
+ "page unless your view context provides a Request object " \
+ "in a #request method"
+ end
+
url_string = CGI.unescapeHTML(url_for(options))
- request = controller.request
+
# We ignore any extra parameters in the request_uri if the
# submitted url doesn't have any either. This lets the function
# work with things like ?order=asc
@@ -179,7 +179,7 @@ class PartialRenderer
def initialize(view_context, options, block)
@view = view_context
- @partial_names = PARTIAL_NAMES[@view.controller.class]
+ @partial_names = PARTIAL_NAMES[@view.controller.class.name]
setup(options, block)
end
@@ -300,7 +300,7 @@ def find_template(path=@path)
end
def partial_path(object = @object)
- @partial_names[object.class] ||= begin
+ @partial_names[object.class.name] ||= begin
object = object.to_model if object.respond_to?(:to_model)
object.class.model_name.partial_path.dup.tap do |partial|
@@ -18,6 +18,14 @@ class Template
attr_reader :source, :identifier, :handler, :virtual_path, :formats
+ def self.finalizer_for(method_name)
+ proc do
+ ActionView::CompiledTemplates.module_eval do
+ remove_possible_method method_name
+ end
+ end
+ end
+
def initialize(source, identifier, handler, details)
@source = source
@identifier = identifier
@@ -98,6 +106,7 @@ def #{method_name}(local_assigns)
begin
ActionView::CompiledTemplates.module_eval(source, identifier, line)
+ ObjectSpace.define_finalizer(self, self.class.finalizer_for(method_name))
method_name
rescue Exception => e # errors from template code
if logger = (view && view.logger)
@@ -142,8 +142,13 @@ def _assigns
end
end
+ def _router
+ @controller._router if @controller.respond_to?(:_router)
+ end
+
def method_missing(selector, *args)
- if @controller._router.named_routes.helpers.include?(selector)
+ if @controller.respond_to?(:_router) &&
+ @controller._router.named_routes.helpers.include?(selector)
@controller.__send__(selector, *args)
else
super
@@ -57,6 +57,18 @@ def body_to_string(body)
extend self
end
+module RenderERBUtils
+ def render_erb(string)
+ template = ActionView::Template.new(
+ string.strip,
+ "test template",
+ ActionView::Template::Handlers::ERB,
+ {})
+
+ template.render(self, {}).strip
+ end
+end
+
module SetupOnce
extend ActiveSupport::Concern
@@ -225,6 +237,14 @@ def assert_header(name, value)
end
end
+class ActionController::Base
+ def self.test_routes(&block)
+ router = ActionDispatch::Routing::RouteSet.new
+ router.draw(&block)
+ include router.url_helpers
+ end
+end
+
class ::ApplicationController < ActionController::Base
end
Oops, something went wrong.

0 comments on commit 11161e6

Please sign in to comment.