diff options
author | wycats <wycats@gmail.com> | 2010-04-10 17:22:52 -0400 |
---|---|---|
committer | wycats <wycats@gmail.com> | 2010-04-10 17:22:52 -0400 |
commit | 87f7093ee3306f417e1136d947eba200d40ff8e7 (patch) | |
tree | ba70dbdaf67e12fc067bb5d8343d7681932452ef /actionpack/lib | |
parent | ee8e9d548472fb8cb8792a569e579c6513be77d6 (diff) | |
parent | 381f877bbbbf81d679f5be3b7ac7e961d41502bd (diff) | |
download | rails-87f7093ee3306f417e1136d947eba200d40ff8e7.tar.gz rails-87f7093ee3306f417e1136d947eba200d40ff8e7.tar.bz2 rails-87f7093ee3306f417e1136d947eba200d40ff8e7.zip |
Merge branch 'master' into docrails_master
Diffstat (limited to 'actionpack/lib')
23 files changed, 139 insertions, 480 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 536154fc6b..c14393dda7 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -33,7 +33,6 @@ module ActionController autoload :Streaming autoload :Testing autoload :UrlFor - autoload :Verification end autoload :Dispatcher, 'action_controller/deprecated/dispatcher' diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 1dfc240029..2e94a20d9d 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -30,7 +30,6 @@ module ActionController Cookies, Flash, - Verification, RequestForgeryProtection, Streaming, RecordIdentifier, diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index fe95f0e0d7..2a0a1107eb 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -38,22 +38,22 @@ module ActionController #:nodoc: extend ActiveSupport::Concern included do - @@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" ## # :singleton-method: # The cache directory should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>. # For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>RAILS_ROOT + "/public"</tt>). Changing # this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your # web server to look in the new location for cached files. + @@page_cache_directory = '' cattr_accessor :page_cache_directory - @@page_cache_extension = '.html' ## # :singleton-method: # Most Rails requests do not have an extension, such as <tt>/weblog/new</tt>. In these cases, the page caching mechanism will add one in # order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>. # If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an # extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps. + @@page_cache_extension = '.html' cattr_accessor :page_cache_extension end diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 05551ffee4..5d9cfb153a 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -6,15 +6,6 @@ module ActionController deprecated_config_writer(option, message) end - # This method has been moved to ActionDispatch::Request.filter_parameters - def filter_parameter_logging(*args, &block) - ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller) - filter = Rails.application.config.filter_parameters - filter.concat(args) - filter << block if block - filter - end - def deprecated_config_reader(option, message = nil) message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ "Please read it from config.#{option}" @@ -136,6 +127,25 @@ module ActionController end end + module DeprecatedBehavior + # This method has been moved to ActionDispatch::Request.filter_parameters + def filter_parameter_logging(*args, &block) + ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller) + filter = Rails.application.config.filter_parameters + filter.concat(args) + filter << block if block + filter + end + + # This was moved to a plugin + def verify(*args) + ActiveSupport::Deprecation.warn "verify was removed from Rails and is now available as a plugin. " << + "Please install it with `rails plugin install git://github.com/rails/verification.git`.", caller + end + end + + extend DeprecatedBehavior + deprecated_config_writer :session_store deprecated_config_writer :session_options deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index e6cea483bb..02722360f1 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -32,8 +32,6 @@ module ActionController def rescue_action(env) raise env["action_dispatch.rescue.exception"] end - - self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" end # For old tests diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb index d97c10a293..6ad9a23542 100644 --- a/actionpack/lib/action_controller/metal/responder.rb +++ b/actionpack/lib/action_controller/metal/responder.rb @@ -135,7 +135,6 @@ module ActionController #:nodoc: def to_format default_render rescue ActionView::MissingTemplate => e - raise unless resourceful? api_behavior(e) end @@ -154,6 +153,8 @@ module ActionController #:nodoc: # This is the common behavior for "API" requests, like :xml and :json. def api_behavior(error) + raise error unless resourceful? + if get? display resource elsif has_errors? diff --git a/actionpack/lib/action_controller/metal/verification.rb b/actionpack/lib/action_controller/metal/verification.rb deleted file mode 100644 index b7fc2b7421..0000000000 --- a/actionpack/lib/action_controller/metal/verification.rb +++ /dev/null @@ -1,130 +0,0 @@ -module ActionController #:nodoc: - module Verification #:nodoc: - extend ActiveSupport::Concern - - include AbstractController::Callbacks, Flash, Rendering - - # This module provides a class-level method for specifying that certain - # actions are guarded against being called without certain prerequisites - # being met. This is essentially a special kind of before_filter. - # - # An action may be guarded against being invoked without certain request - # parameters being set, or without certain session values existing. - # - # When a verification is violated, values may be inserted into the flash, and - # a specified redirection is triggered. If no specific action is configured, - # verification failures will by default result in a 400 Bad Request response. - # - # Usage: - # - # class GlobalController < ActionController::Base - # # Prevent the #update_settings action from being invoked unless - # # the 'admin_privileges' request parameter exists. The - # # settings action will be redirected to in current controller - # # if verification fails. - # verify :params => "admin_privileges", :only => :update_post, - # :redirect_to => { :action => "settings" } - # - # # Disallow a post from being updated if there was no information - # # submitted with the post, and if there is no active post in the - # # session, and if there is no "note" key in the flash. The route - # # named category_url will be redirected to if verification fails. - # - # verify :params => "post", :session => "post", "flash" => "note", - # :only => :update_post, - # :add_flash => { "alert" => "Failed to create your message" }, - # :redirect_to => :category_url - # - # Note that these prerequisites are not business rules. They do not examine - # the content of the session or the parameters. That level of validation should - # be encapsulated by your domain model or helper methods in the controller. - module ClassMethods - # Verify the given actions so that if certain prerequisites are not met, - # the user is redirected to a different action. The +options+ parameter - # is a hash consisting of the following key/value pairs: - # - # <tt>:params</tt>:: - # a single key or an array of keys that must be in the <tt>params</tt> - # hash in order for the action(s) to be safely called. - # <tt>:session</tt>:: - # a single key or an array of keys that must be in the <tt>session</tt> - # in order for the action(s) to be safely called. - # <tt>:flash</tt>:: - # a single key or an array of keys that must be in the flash in order - # for the action(s) to be safely called. - # <tt>:method</tt>:: - # a single key or an array of keys--any one of which must match the - # current request method in order for the action(s) to be safely called. - # (The key should be a symbol: <tt>:get</tt> or <tt>:post</tt>, for - # example.) - # <tt>:xhr</tt>:: - # true/false option to ensure that the request is coming from an Ajax - # call or not. - # <tt>:add_flash</tt>:: - # a hash of name/value pairs that should be merged into the session's - # flash if the prerequisites cannot be satisfied. - # <tt>:add_headers</tt>:: - # a hash of name/value pairs that should be merged into the response's - # headers hash if the prerequisites cannot be satisfied. - # <tt>:redirect_to</tt>:: - # the redirection parameters to be used when redirecting if the - # prerequisites cannot be satisfied. You can redirect either to named - # route or to the action in some controller. - # <tt>:render</tt>:: - # the render parameters to be used when the prerequisites cannot be satisfied. - # <tt>:only</tt>:: - # only apply this verification to the actions specified in the associated - # array (may also be a single value). - # <tt>:except</tt>:: - # do not apply this verification to the actions specified in the associated - # array (may also be a single value). - def verify(options={}) - before_filter :only => options[:only], :except => options[:except] do - verify_action options - end - end - end - - private - - def verify_action(options) #:nodoc: - if prereqs_invalid?(options) - flash.update(options[:add_flash]) if options[:add_flash] - response.headers.merge!(options[:add_headers]) if options[:add_headers] - apply_remaining_actions(options) unless performed? - end - end - - def prereqs_invalid?(options) # :nodoc: - verify_presence_of_keys_in_hash_flash_or_params(options) || - verify_method(options) || - verify_request_xhr_status(options) - end - - def verify_presence_of_keys_in_hash_flash_or_params(options) # :nodoc: - [*options[:params] ].find { |v| v && params[v.to_sym].nil? } || - [*options[:session]].find { |v| session[v].nil? } || - [*options[:flash] ].find { |v| flash[v].nil? } - end - - def verify_method(options) # :nodoc: - [*options[:method]].all? { |v| request.method_symbol != v.to_sym } if options[:method] - end - - def verify_request_xhr_status(options) # :nodoc: - request.xhr? != options[:xhr] unless options[:xhr].nil? - end - - def apply_redirect_to(redirect_to_option) # :nodoc: - (redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? self.__send__(redirect_to_option) : redirect_to_option - end - - def apply_remaining_actions(options) # :nodoc: - case - when options[:render] ; render(options[:render]) - when options[:redirect_to] ; redirect_to(apply_redirect_to(options[:redirect_to])) - else head(:bad_request) - end - end - end -end diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index ae363e300c..7f2eb4306b 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -120,7 +120,7 @@ module ActionController end %w(edit new).each do |action| - module_eval <<-EOT, __FILE__, __LINE__ + module_eval <<-EOT, __FILE__, __LINE__ + 1 def #{action}_polymorphic_url(record_or_hash, options = {}) # def edit_polymorphic_url(record_or_hash, options = {}) polymorphic_url( # polymorphic_url( record_or_hash, # record_or_hash, diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 030ba4ec48..b029434004 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -44,6 +44,12 @@ module ActionController ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger } end + initializer "action_controller.page_cache_directory" do + ActiveSupport.on_load(:action_controller) do + self.page_cache_directory = Rails.public_path + end + end + initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 2d4cf2fafb..dfd8e75bcc 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -284,6 +284,8 @@ module ActionController include ActionDispatch::TestProcess include ActionController::TemplateAssertions + attr_reader :response, :request + # Executes a request simulating GET HTTP method and set/volley the response def get(action, parameters = nil, session = nil, flash = nil) process(action, parameters, session, flash, "GET") diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 18a3688bb0..1524b00d5b 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -36,17 +36,16 @@ module ActionDispatch when Proc strategy.call(request.raw_post) when :xml_simple, :xml_node - request.body.size == 0 ? {} : Hash.from_xml(request.raw_post).with_indifferent_access + data = Hash.from_xml(request.body) || {} + request.body.rewind if request.body.respond_to?(:rewind) + data.with_indifferent_access when :yaml YAML.load(request.raw_post) when :json - if request.body.size == 0 - {} - else - data = ActiveSupport::JSON.decode(request.raw_post) - data = {:_json => data} unless data.is_a?(Hash) - data.with_indifferent_access - end + data = ActiveSupport::JSON.decode(request.body) + request.body.rewind if request.body.respond_to?(:rewind) + data = {:_json => data} unless data.is_a?(Hash) + data.with_indifferent_access else false end @@ -76,4 +75,4 @@ module ActionDispatch defined?(Rails.logger) ? Rails.logger : Logger.new($stderr) end end -end
\ No newline at end of file +end diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb index 839df50999..09ff052fd0 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb @@ -6,7 +6,7 @@ <% end %> <% - clean_params = @request.parameters.clone + clean_params = @request.filtered_parameters.clone clean_params.delete("action") clean_params.delete("controller") diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 925e91f081..7035e360ec 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -324,7 +324,8 @@ module ActionDispatch end def namespace(path) - scope(path.to_s, :name_prefix => path.to_s, :controller_namespace => path.to_s) { yield } + path = path.to_s + scope(:path => path, :name_prefix => path, :module => path) { yield } end def constraints(constraints = {}) @@ -363,15 +364,15 @@ module ActionDispatch parent ? "#{parent}_#{child}" : child end - def merge_controller_namespace_scope(parent, child) + def merge_module_scope(parent, child) parent ? "#{parent}/#{child}" : child end def merge_controller_scope(parent, child) - @scope[:controller_namespace] ? "#{@scope[:controller_namespace]}/#{child}" : child + @scope[:module] ? "#{@scope[:module]}/#{child}" : child end - def merge_resources_path_names_scope(parent, child) + def merge_path_names_scope(parent, child) merge_options_scope(parent, child) end @@ -520,7 +521,7 @@ module ActionDispatch def initialize(*args) #:nodoc: super - @scope[:resources_path_names] = @set.resources_path_names + @scope[:path_names] = @set.resources_path_names end def resource(*resources, &block) @@ -636,7 +637,7 @@ module ActionDispatch return self end - resources_path_names = options.delete(:path_names) + path_names = options.delete(:path_names) if args.first.is_a?(Symbol) action = args.first @@ -653,7 +654,7 @@ module ActionDispatch end else with_exclusive_name_prefix(action) do - return match("#{action_path(action, resources_path_names)}(.:format)", options.reverse_merge(:to => action)) + return match("#{action_path(action, path_names)}(.:format)", options.reverse_merge(:to => action)) end end end @@ -681,7 +682,7 @@ module ActionDispatch private def action_path(name, path_names = nil) - path_names ||= @scope[:resources_path_names] + path_names ||= @scope[:path_names] path_names[name.to_sym] || name.to_s end @@ -692,7 +693,7 @@ module ActionDispatch end if path_names = options.delete(:path_names) - scope(:resources_path_names => path_names) do + scope(:path_names => path_names) do send(method, resources.pop, options, &block) end return true diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index 0b40465a79..8f0c5d939f 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -3,7 +3,7 @@ module ActionPack MAJOR = 3 MINOR = 0 TINY = 0 - BUILD = "beta2" + BUILD = "beta3" STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 44e193f18e..a7650c0050 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -1,8 +1,6 @@ -require 'cgi' require 'action_view/helpers/form_helper' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/enumerable' -require 'active_support/core_ext/kernel/reporting' require 'active_support/core_ext/object/blank' module ActionView @@ -14,252 +12,29 @@ module ActionView end module Helpers - # The Active Record Helper makes it easier to create forms for records kept in instance variables. The most far-reaching is the +form+ - # method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This - # is a great way of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. - # In that case, it's better to use the +input+ method and the specialized +form+ methods in link:classes/ActionView/Helpers/FormHelper.html module ActiveModelHelper - # Returns a default input tag for the type of object returned by the method. For example, if <tt>@post</tt> - # has an attribute +title+ mapped to a +VARCHAR+ column that holds "Hello World": - # - # input("post", "title") - # # => <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> - def input(record_name, method, options = {}) - InstanceTag.new(record_name, method, self).to_tag(options) - end - - # Returns an entire form with all needed input tags for a specified Active Record object. For example, if <tt>@post</tt> - # has attributes named +title+ of type +VARCHAR+ and +body+ of type +TEXT+ then - # - # form("post") - # - # would yield a form like the following (modulus formatting): - # - # <form action='/posts/create' method='post'> - # <p> - # <label for="post_title">Title</label><br /> - # <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> - # </p> - # <p> - # <label for="post_body">Body</label><br /> - # <textarea cols="40" id="post_body" name="post[body]" rows="20"></textarea> - # </p> - # <input name="commit" type="submit" value="Create" /> - # </form> - # - # It's possible to specialize the form builder by using a different action name and by supplying another - # block renderer. For example, if <tt>@entry</tt> has an attribute +message+ of type +VARCHAR+ then - # - # form("entry", - # :action => "sign", - # :input_block => Proc.new { |record, column| - # "#{column.human_name}: #{input(record, column.name)}<br />" - # }) - # - # would yield a form like the following (modulus formatting): - # - # <form action="/entries/sign" method="post"> - # Message: - # <input id="entry_message" name="entry[message]" size="30" type="text" /><br /> - # <input name="commit" type="submit" value="Sign" /> - # </form> - # - # It's also possible to add additional content to the form by giving it a block, such as: - # - # form("entry", :action => "sign") do |form| - # form << content_tag("b", "Department") - # form << collection_select("department", "id", @departments, "id", "name") - # end - # - # The following options are available: - # - # * <tt>:action</tt> - The action used when submitting the form (default: +create+ if a new record, otherwise +update+). - # * <tt>:input_block</tt> - Specialize the output using a different block, see above. - # * <tt>:method</tt> - The method used when submitting the form (default: +post+). - # * <tt>:multipart</tt> - Whether to change the enctype of the form to "multipart/form-data", used when uploading a file (default: +false+). - # * <tt>:submit_value</tt> - The text of the submit button (default: "Create" if a new record, otherwise "Update"). - def form(record_name, options = {}) - record = instance_variable_get("@#{record_name}") - record = convert_to_model(record) - - options = options.symbolize_keys - options[:action] ||= record.persisted? ? "update" : "create" - action = url_for(:action => options[:action], :id => record) - - submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize - - contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil) - contents.safe_concat hidden_field(record_name, :id) if record.persisted? - contents.safe_concat all_input_tags(record, record_name, options) - yield contents if block_given? - contents.safe_concat submit_tag(submit_value) - contents.safe_concat('</form>') - end - - # Returns a string containing the error message attached to the +method+ on the +object+ if one exists. - # This error message is wrapped in a <tt>DIV</tt> tag by default or with <tt>:html_tag</tt> if specified, - # which can be extended to include a <tt>:prepend_text</tt> and/or <tt>:append_text</tt> (to properly explain - # the error), and a <tt>:css_class</tt> to style it accordingly. +object+ should either be the name of an - # instance variable or the actual object. The method can be passed in either as a string or a symbol. - # As an example, let's say you have a model <tt>@post</tt> that has an error message on the +title+ attribute: - # - # <%= error_message_on "post", "title" %> - # # => <div class="formError">can't be empty</div> - # - # <%= error_message_on @post, :title %> - # # => <div class="formError">can't be empty</div> - # - # <%= error_message_on "post", "title", - # :prepend_text => "Title simply ", - # :append_text => " (or it won't work).", - # :html_tag => "span", - # :css_class => "inputError" %> - # # => <span class="inputError">Title simply can't be empty (or it won't work).</span> - def error_message_on(object, method, *args) - options = args.extract_options! - unless args.empty? - ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate ' + - 'prepend_text, append_text, html_tag, and css_class arguments', caller) - - options[:prepend_text] = args[0] || '' - options[:append_text] = args[1] || '' - options[:html_tag] = args[2] || 'div' - options[:css_class] = args[3] || 'formError' - end - options.reverse_merge!(:prepend_text => '', :append_text => '', :html_tag => 'div', :css_class => 'formError') - - object = convert_to_model(object) - - if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && - (errors = obj.errors[method]).presence - content_tag(options[:html_tag], - (options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]), - :class => options[:css_class] - ) - else - '' - end - end - - # Returns a string with a <tt>DIV</tt> containing all of the error messages for the objects located as instance variables by the names - # given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are - # provided. - # - # This <tt>DIV</tt> can be tailored by the following options: - # - # * <tt>:header_tag</tt> - Used for the header of the error div (default: "h2"). - # * <tt>:id</tt> - The id of the error div (default: "errorExplanation"). - # * <tt>:class</tt> - The class of the error div (default: "errorExplanation"). - # * <tt>:object</tt> - The object (or array of objects) for which to display errors, - # if you need to escape the instance variable convention. - # * <tt>:object_name</tt> - The object name to use in the header, or any text that you prefer. - # If <tt>:object_name</tt> is not set, the name of the first object will be used. - # * <tt>:header_message</tt> - The message in the header of the error div. Pass +nil+ - # or an empty string to avoid the header message altogether. (Default: "X errors - # prohibited this object from being saved"). - # * <tt>:message</tt> - The explanation message after the header message and before - # the error list. Pass +nil+ or an empty string to avoid the explanation message - # altogether. (Default: "There were problems with the following fields:"). - # - # To specify the display for one object, you simply provide its name as a parameter. - # For example, for the <tt>@user</tt> model: - # - # error_messages_for 'user' - # - # You can also supply an object: - # - # error_messages_for @user - # - # This will use the last part of the model name in the presentation. For instance, if - # this is a MyKlass::User object, this will use "user" as the name in the String. This - # is taken from MyKlass::User.model_name.human, which can be overridden. - # - # To specify more than one object, you simply list them; optionally, you can add an extra <tt>:object_name</tt> parameter, which - # will be the name used in the header message: - # - # error_messages_for 'user_common', 'user', :object_name => 'user' - # - # You can also use a number of objects, which will have the same naming semantics - # as a single object. - # - # error_messages_for @user, @post - # - # If the objects cannot be located as instance variables, you can add an extra <tt>:object</tt> parameter which gives the actual - # object (or array of objects to use): - # - # error_messages_for 'user', :object => @question.user - # - # NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what - # you need is significantly different from the default presentation, it makes plenty of sense to access the <tt>object.errors</tt> - # instance yourself and set it up. View the source of this method to see how easy it is. - def error_messages_for(*params) - options = params.extract_options!.symbolize_keys - - objects = Array.wrap(options.delete(:object) || params).map do |object| - object = instance_variable_get("@#{object}") unless object.respond_to?(:to_model) - object = convert_to_model(object) - - if object.class.respond_to?(:model_name) - options[:object_name] ||= object.class.model_name.human.downcase + %w(input form error_messages_for error_message_on).each do |method| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + ActiveSupport::Deprecation.warn "#{method} was removed from Rails and is now available as a plugin. " << + "Please install it with `rails plugin install git://github.com/rails/dynamic_form.git`.", caller end + RUBY + end + end - object - end - - objects.compact! - count = objects.inject(0) {|sum, object| sum + object.errors.count } - - unless count.zero? - html = {} - [:id, :class].each do |key| - if options.include?(key) - value = options[key] - html[key] = value unless value.blank? - else - html[key] = 'errorExplanation' - end - end - options[:object_name] ||= params.first - - I18n.with_options :locale => options[:locale], :scope => [:errors, :template] do |locale| - header_message = if options.include?(:header_message) - options[:header_message] - else - locale.t :header, :count => count, :model => options[:object_name].to_s.gsub('_', ' ') - end - - message = options.include?(:message) ? options[:message] : locale.t(:body) - - error_messages = objects.sum do |object| - object.errors.full_messages.map do |msg| - content_tag(:li, msg) - end - end.join.html_safe - - contents = '' - contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? - contents << content_tag(:p, message) unless message.blank? - contents << content_tag(:ul, error_messages) - - content_tag(:div, contents.html_safe, html) + module ActiveModelFormBuilder + %w(error_messages error_message_on).each do |method| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + ActiveSupport::Deprecation.warn "f.#{method} was removed from Rails and is now available as a plugin. " << + "Please install it with `rails plugin install git://github.com/rails/dynamic_form.git`.", caller end - else - '' - end + RUBY end - - private - def all_input_tags(record, record_name, options) - input_block = options[:input_block] || default_input_block - record.class.content_columns.collect{ |column| input_block.call(record_name, column) }.join("\n") - end - - def default_input_block - Proc.new { |record, column| %(<p><label for="#{record}_#{column.name}">#{column.human_name}</label><br />#{input(record, column.name)}</p>) } - end end - module ActiveRecordInstanceTag + module ActiveModelInstanceTag def object @active_model_object ||= begin object = super @@ -267,26 +42,6 @@ module ActionView end end - def to_tag(options = {}) - case column_type - when :string - field_type = @method_name.include?("password") ? "password" : "text" - to_input_field_tag(field_type, options) - when :text - to_text_area_tag(options) - when :integer, :float, :decimal - to_input_field_tag("text", options) - when :date - to_date_select_tag(options) - when :datetime, :timestamp - to_datetime_select_tag(options) - when :time - to_time_select_tag(options) - when :boolean - to_boolean_select_tag(options) - end - end - %w(tag content_tag to_date_select_tag to_datetime_select_tag to_time_select_tag).each do |meth| module_eval "def #{meth}(*) error_wrapping(super) end" end @@ -302,14 +57,14 @@ module ActionView def error_message object.errors[@method_name] end + end - def column_type - object.send(:column_for_attribute, @method_name).type - end + class FormBuilder + include ActiveModelFormBuilder end class InstanceTag - include ActiveRecordInstanceTag + include ActiveModelInstanceTag end end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index e4ec17467e..563d9ec319 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -501,16 +501,53 @@ module ActionView end end + # Web browsers cache favicons. If you just throw a <tt>favicon.ico</tt> into the document + # root of your application and it changes later, clients that have it in their cache + # won't see the update. Using this helper prevents that because it appends an asset ID: + # + # <%= favicon_link_tag %> + # + # generates + # + # <link href="/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" /> + # + # You may specify a different file in the first argument: + # + # <%= favicon_link_tag 'favicon.ico' %> + # + # That's passed to +path_to_image+ as is, so it gives + # + # <link href="/images/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" /> + # + # The helper accepts an additional options hash where you can override "rel" and "type". + # + # For example, Mobile Safari looks for a different LINK tag, pointing to an image that + # will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad. + # The following call would generate such a tag: + # + # <%= favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png' %> + # + def favicon_link_tag(source='/favicon.ico', options={}) + tag('link', { + :rel => 'shortcut icon', + :type => 'image/vnd.microsoft.icon', + :href => path_to_image(source) + }.merge(options.symbolize_keys)) + end + # Computes the path to an image asset in the public images directory. # Full paths from the document root will be passed through. - # Used internally by +image_tag+ to build the image path. + # Used internally by +image_tag+ to build the image path: # - # ==== Examples - # image_path("edit") # => /images/edit - # image_path("edit.png") # => /images/edit.png - # image_path("icons/edit.png") # => /images/icons/edit.png - # image_path("/icons/edit.png") # => /icons/edit.png - # image_path("http://www.railsapplication.com/img/edit.png") # => http://www.railsapplication.com/img/edit.png + # image_path("edit") # => "/images/edit" + # image_path("edit.png") # => "/images/edit.png" + # image_path("icons/edit.png") # => "/images/icons/edit.png" + # image_path("/icons/edit.png") # => "/icons/edit.png" + # image_path("http://www.railsapplication.com/img/edit.png") # => "http://www.railsapplication.com/img/edit.png" + # + # If you have images as application resources this method may conflict with their named routes. + # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and + # plugin authors are encouraged to do so. def image_path(source) compute_public_path(source, 'images') end @@ -590,7 +627,7 @@ module ActionView end if mouseover = options.delete(:mouseover) - options[:onmouseover] = "this.src='#{image_path(mouseover)}'" + options[:onmouseover] = "this.src='#{path_to_image(mouseover)}'" options[:onmouseout] = "this.src='#{src}'" end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index fc02d959d4..a3453cc47a 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1105,7 +1105,7 @@ module ActionView end (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector| - src, file, line = <<-end_src, __FILE__, __LINE__ + 1 + src, line = <<-end_src, __LINE__ + 1 def #{selector}(method, options = {}) # def text_field(method, options = {}) @template.send( # @template.send( #{selector.inspect}, # "text_field", @@ -1114,7 +1114,7 @@ module ActionView objectify_options(options)) # objectify_options(options)) end # end end_src - class_eval src, file, line + class_eval src, __FILE__, line end def fields_for(record_or_name_or_array, *args, &block) @@ -1169,14 +1169,6 @@ module ActionView @template.hidden_field(@object_name, method, objectify_options(options)) end - def error_message_on(method, *args) - @template.error_message_on(@object, method, *args) - end - - def error_messages(options = {}) - @template.error_messages_for(@object_name, objectify_options(options)) - end - # Add the submit button for the given form. When no value is given, it checks # if the object is a new resource or not to create the proper label: # diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 11c6351bd3..105f4565e6 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -217,8 +217,6 @@ module ActionView InstanceTag.new(object, method, self, options.delete(:object)).to_grouped_collection_select_tag(collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) end - - # Return select and option tags for the given object and method, using # #time_zone_options_for_select to generate the list of option tags. # diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 081c317e0c..b840f77fb5 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -199,8 +199,8 @@ module ActionView # file_field_tag 'attachment' # # => <input id="attachment" name="attachment" type="file" /> # - # file_field_tag 'avatar', :class => 'profile-input' - # # => <input class="profile-input" id="avatar" name="avatar" type="file" /> + # file_field_tag 'avatar', :class => 'profile_input' + # # => <input class="profile_input" id="avatar" name="avatar" type="file" /> # # file_field_tag 'picture', :disabled => true # # => <input disabled="disabled" id="picture" name="picture" type="file" /> @@ -244,8 +244,8 @@ module ActionView # password_field_tag 'confirm_pass', nil, :disabled => true # # => <input disabled="disabled" id="confirm_pass" name="confirm_pass" type="password" /> # - # password_field_tag 'pin', '1234', :maxlength => 4, :size => 6, :class => "pin-input" - # # => <input class="pin-input" id="pin" maxlength="4" name="pin" size="6" type="password" value="1234" /> + # password_field_tag 'pin', '1234', :maxlength => 4, :size => 6, :class => "pin_input" + # # => <input class="pin_input" id="pin" maxlength="4" name="pin" size="6" type="password" value="1234" /> def password_field_tag(name = "password", value = nil, options = {}) text_field_tag(name, value, options.update("type" => "password")) end @@ -374,8 +374,8 @@ module ActionView # submit_tag nil, :class => "form_submit" # # => <input class="form_submit" name="commit" type="submit" /> # - # submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button" - # # => <input class="edit-button" data-disable_with="Editing..." + # submit_tag "Edit", :disable_with => "Editing...", :class => "edit_button" + # # => <input class="edit_button" data-disable_with="Editing..." # # name="commit" type="submit" value="Edit" /> # # submit_tag "Save", :confirm => "Are you sure?" @@ -386,7 +386,7 @@ module ActionView options.stringify_keys! if disable_with = options.delete("disable_with") - options["data-disable-with"] = disable_with if disable_with + options["data-disable-with"] = disable_with end if confirm = options.delete("confirm") @@ -398,7 +398,7 @@ module ActionView # Displays an image which when clicked will submit the form. # - # <tt>source</tt> is passed to AssetTagHelper#image_path + # <tt>source</tt> is passed to AssetTagHelper#path_to_image # # ==== Options # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm @@ -414,11 +414,11 @@ module ActionView # image_submit_tag("purchase.png", :disabled => true) # # => <input disabled="disabled" src="/images/purchase.png" type="image" /> # - # image_submit_tag("search.png", :class => 'search-button') - # # => <input class="search-button" src="/images/search.png" type="image" /> + # image_submit_tag("search.png", :class => 'search_button') + # # => <input class="search_button" src="/images/search.png" type="image" /> # - # image_submit_tag("agree.png", :disabled => true, :class => "agree-disagree-button") - # # => <input class="agree-disagree-button" disabled="disabled" src="/images/agree.png" type="image" /> + # image_submit_tag("agree.png", :disabled => true, :class => "agree_disagree_button") + # # => <input class="agree_disagree_button" disabled="disabled" src="/images/agree.png" type="image" /> def image_submit_tag(source, options = {}) options.stringify_keys! diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 5925faf810..0b748d700b 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -265,7 +265,7 @@ module ActionView # using the +link_to+ method with the <tt>:method</tt> modifier as described in # the +link_to+ documentation. # - # The generated form element has a class name of <tt>button-to</tt> + # The generated form element has a class name of <tt>button_to</tt> # to allow styling of the form itself and its children. You can control # the form submission and input element behavior using +html_options+. # This method accepts the <tt>:method</tt> and <tt>:confirm</tt> modifiers @@ -289,14 +289,14 @@ module ActionView # # ==== Examples # <%= button_to "New", :action => "new" %> - # # => "<form method="post" action="/controller/new" class="button-to"> + # # => "<form method="post" action="/controller/new" class="button_to"> # # <div><input value="New" type="submit" /></div> # # </form>" # # # <%= button_to "Delete Image", { :action => "delete", :id => @image.id }, # :confirm => "Are you sure?", :method => :delete %> - # # => "<form method="post" action="/images/delete/1" class="button-to"> + # # => "<form method="post" action="/images/delete/1" class="button_to"> # # <div> # # <input type="hidden" name="_method" value="delete" /> # # <input data-confirm='Are you sure?' value="Delete" type="submit" /> @@ -306,7 +306,7 @@ module ActionView # # <%= 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'> + # # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'> # # <div> # # <input name='_method' value='delete' type='hidden' /> # # <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' /> @@ -338,7 +338,7 @@ module ActionView html_options.merge!("type" => "submit", "value" => name) - ("<form method=\"#{form_method}\" action=\"#{escape_once url}\" #{"data-remote=\"true\"" if remote} class=\"button-to\"><div>" + + ("<form method=\"#{form_method}\" action=\"#{escape_once url}\" #{"data-remote=\"true\"" if remote} class=\"button_to\"><div>" + method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe end diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml index a3e2230f6f..187e010e30 100644 --- a/actionpack/lib/action_view/locale/en.yml +++ b/actionpack/lib/action_view/locale/en.yml @@ -141,14 +141,6 @@ minute: "Minute" second: "Seconds" - errors: - template: - header: - one: "1 error prohibited this {{model}} from being saved" - other: "{{count}} errors prohibited this {{model}} from being saved" - # The variable :count is also available - body: "There were problems with the following fields:" - helpers: select: # Default value for :prompt => true in FormOptionsHelper diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 9b59aac0eb..6e61d85dcc 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -38,7 +38,7 @@ module ActionView end register_detail(:formats) { Mime::SET.symbols } - register_detail(:locale) { [I18n.locale] } + register_detail(:locale) { [I18n.locale, I18n.default_locale] } class DetailsKey #:nodoc: alias :eql? :equal? @@ -160,7 +160,7 @@ module ActionView config = I18n.config.respond_to?(:i18n_config) ? I18n.config.i18n_config : I18n.config config.locale = value end - super(I18n.locale) + super(_locale_defaults) end # Update the details keys by merging the given hash into the current diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index 7311730a19..31b09d9f0a 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -48,7 +48,7 @@ module ActionView # def _layout_for(name = nil, &block) #:nodoc: if !block || name - @_content_for[name || :layout] + @_content_for[name || :layout].html_safe else capture(&block) end |