Permalink
Browse files

Merge commit 'rails/master'

Conflicts:
	activerecord/lib/active_record/associations.rb
  • Loading branch information...
miloops committed Jul 31, 2009
2 parents c1cbf02 + 62fd1d3 commit 3de59e916d6a3d4eab202cf0c99b1f88905a3b43
Showing 410 changed files with 11,767 additions and 5,713 deletions.
View
@@ -13,6 +13,8 @@ actionmailer/pkg
activesupport/pkg
railties/pkg
railties/test/500.html
+railties/test/fixtures/tmp
+railties/test/initializer/root/log
railties/doc/guides/html/images
railties/doc/guides/html/stylesheets
benches
View
@@ -38,7 +38,8 @@ Rake::RDocTask.new do |rdoc|
rdoc.rdoc_files.include('railties/CHANGELOG')
rdoc.rdoc_files.include('railties/MIT-LICENSE')
rdoc.rdoc_files.include('railties/README')
- rdoc.rdoc_files.include('railties/lib/{*.rb,commands/*.rb,rails/*.rb,rails_generator/*.rb}')
+ rdoc.rdoc_files.include('railties/lib/{*.rb,commands/*.rb,rails/*.rb,generators/*.rb}')
+ rdoc.rdoc_files.exclude('railties/lib/vendor/*')
rdoc.rdoc_files.include('activerecord/README')
rdoc.rdoc_files.include('activerecord/CHANGELOG')
@@ -1,6 +1,6 @@
=begin rdoc
-= Obsolete methods that are depriciated
+= Obsolete methods that are deprecated
If you really want to see them, go to lib/tmail/obsolete.rb and view to your
heart's content.
@@ -276,7 +276,7 @@ def authentication_request(controller, realm, message = nil)
#
# The nonce is opaque to the client. Composed of Time, and hash of Time with secret
# key from the Rails session secret generated upon creation of project. Ensures
- # the time cannot be modifed by client.
+ # the time cannot be modified by client.
def nonce(time = Time.now)
t = time.to_i
hashed = [t, secret_key]
@@ -1,5 +1,55 @@
module ActionController #:nodoc:
module MimeResponds #:nodoc:
+ extend ActiveSupport::Concern
+
+ included do
+ class_inheritable_reader :mimes_for_respond_to
+ clear_respond_to
+ end
+
+ module ClassMethods
+ # Defines mimes that are rendered by default when invoking respond_with.
+ #
+ # Examples:
+ #
+ # respond_to :html, :xml, :json
+ #
+ # All actions on your controller will respond to :html, :xml and :json.
+ #
+ # But if you want to specify it based on your actions, you can use only and
+ # except:
+ #
+ # respond_to :html
+ # respond_to :xml, :json, :except => [ :edit ]
+ #
+ # The definition above explicits that all actions respond to :html. And all
+ # actions except :edit respond to :xml and :json.
+ #
+ # You can specify also only parameters:
+ #
+ # respond_to :rjs, :only => :create
+ #
+ def respond_to(*mimes)
+ options = mimes.extract_options!
+
+ only_actions = Array(options.delete(:only))
+ except_actions = Array(options.delete(:except))
+
+ mimes.each do |mime|
+ mime = mime.to_sym
+ mimes_for_respond_to[mime] = {}
+ mimes_for_respond_to[mime][:only] = only_actions unless only_actions.empty?
+ mimes_for_respond_to[mime][:except] = except_actions unless except_actions.empty?
+ end
+ end
+
+ # Clear all mimes in respond_to.
+ #
+ def clear_respond_to
+ write_inheritable_attribute(:mimes_for_respond_to, ActiveSupport::OrderedHash.new)
+ end
+ end
+
# Without web-service support, an action which collects the data for displaying a list of people
# might look something like this:
#
@@ -92,50 +142,187 @@ module MimeResponds #:nodoc:
# environment.rb as follows.
#
# Mime::Type.register "image/jpg", :jpg
- def respond_to(*types, &block)
- raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
- block ||= lambda { |responder| types.each { |type| responder.send(type) } }
- responder = Responder.new(self)
- block.call(responder)
- responder.respond
- end
+ #
+ # Respond to also allows you to specify a common block for different formats by using any:
+ #
+ # def index
+ # @people = Person.find(:all)
+ #
+ # respond_to do |format|
+ # format.html
+ # format.any(:xml, :json) { render request.format.to_sym => @people }
+ # end
+ # end
+ #
+ # In the example above, if the format is xml, it will render:
+ #
+ # render :xml => @people
+ #
+ # Or if the format is json:
+ #
+ # render :json => @people
+ #
+ # Since this is a common pattern, you can use the class method respond_to
+ # with the respond_with method to have the same results:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :html, :xml, :json
+ #
+ # def index
+ # @people = Person.find(:all)
+ # respond_with(@person)
+ # end
+ # end
+ #
+ # Be sure to check respond_with and respond_to documentation for more examples.
+ #
+ def respond_to(*mimes, &block)
+ options = mimes.extract_options!
+ raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
- class Responder #:nodoc:
-
- def initialize(controller)
- @controller = controller
- @request = controller.request
- @response = controller.response
+ resource = options.delete(:with)
+ responder = Responder.new
- @mime_type_priority = @request.formats
+ mimes = collect_mimes_from_class_level if mimes.empty?
+ mimes.each { |mime| responder.send(mime) }
+ block.call(responder) if block_given?
- @order = []
- @responses = {}
+ if format = request.negotiate_mime(responder.order)
+ respond_to_block_or_template_or_resource(format, resource,
+ options, &responder.response_for(format))
+ else
+ head :not_acceptable
end
+ end
- def custom(mime_type, &block)
- mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
+ # respond_with allows you to respond an action with a given resource. It
+ # requires that you set your class with a :respond_to method with the
+ # formats allowed:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :html, :xml, :json
+ #
+ # def index
+ # @people = Person.find(:all)
+ # respond_with(@person)
+ # end
+ # end
+ #
+ # When a request comes with format :xml, the respond_with will first search
+ # for a template as person/index.xml, if the template is not available, it
+ # will see if the given resource responds to :to_xml.
+ #
+ # If neither are available, it will raise an error.
+ #
+ # Extra parameters given to respond_with are used when :to_format is invoked.
+ # This allows you to set status and location for several formats at the same
+ # time. Consider this restful controller response on create for both xml
+ # and json formats:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :xml, :json
+ #
+ # def create
+ # @person = Person.new(params[:person])
+ #
+ # if @person.save
+ # respond_with(@person, :status => :ok, :location => person_url(@person))
+ # else
+ # respond_with(@person.errors, :status => :unprocessable_entity)
+ # end
+ # end
+ # end
+ #
+ # Finally, respond_with also accepts blocks, as in respond_to. Let's take
+ # the same controller and create action above and add common html behavior:
+ #
+ # class PeopleController < ApplicationController
+ # respond_to :html, :xml, :json
+ #
+ # def create
+ # @person = Person.new(params[:person])
+ #
+ # if @person.save
+ # options = { :status => :ok, :location => person_url(@person) }
+ #
+ # respond_with(@person, options) do |format|
+ # format.html { redirect_to options[:location] }
+ # end
+ # else
+ # respond_with(@person.errors, :status => :unprocessable_entity) do
+ # format.html { render :action => :new }
+ # end
+ # end
+ # end
+ # end
+ #
+ def respond_with(resource, options={}, &block)
+ respond_to(options.merge!(:with => resource), &block)
+ end
- @order << mime_type
+ protected
- @responses[mime_type] ||= Proc.new do
- # TODO: Remove this when new base is merged in
- @controller.formats = [mime_type.to_sym]
- @controller.content_type = mime_type
- @controller.template.formats = [mime_type.to_sym]
+ def respond_to_block_or_template_or_resource(format, resource, options)
+ self.formats = [format.to_sym]
+ return yield if block_given?
- block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
+ begin
+ default_render
+ rescue ActionView::MissingTemplate => e
+ if resource && resource.respond_to?(:"to_#{format.to_sym}")
+ render options.merge(format.to_sym => resource)
+ else
+ raise e
end
end
+ end
+
+ # Collect mimes declared in the class method respond_to valid for the
+ # current action.
+ #
+ def collect_mimes_from_class_level #:nodoc:
+ action = action_name.to_sym
+
+ mimes_for_respond_to.keys.select do |mime|
+ config = mimes_for_respond_to[mime]
+
+ if config[:except]
+ !config[:except].include?(action)
+ elsif config[:only]
+ config[:only].include?(action)
+ else
+ true
+ end
+ end
+ end
+
+ class Responder #:nodoc:
+ attr_accessor :order
+
+ def initialize
+ @order, @responses = [], {}
+ end
def any(*args, &block)
if args.any?
args.each { |type| send(type, &block) }
else
- custom(@mime_type_priority.first, &block)
+ custom(Mime::ALL, &block)
end
end
-
+ alias :all :any
+
+ def custom(mime_type, &block)
+ mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
+
+ @order << mime_type
+ @responses[mime_type] ||= block
+ end
+
+ def response_for(mime)
+ @responses[mime] || @responses[Mime::ALL]
+ end
+
def self.generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
const = sym.to_s.upcase
@@ -152,7 +339,7 @@ def #{sym}(&block) # def html(&block)
def method_missing(symbol, &block)
mime_constant = Mime.const_get(symbol.to_s.upcase)
-
+
if Mime::SET.include?(mime_constant)
self.class.generate_method_for_mime(mime_constant)
send(symbol, &block)
@@ -161,25 +348,6 @@ def method_missing(symbol, &block)
end
end
- def respond
- for priority in @mime_type_priority
- if priority == Mime::ALL
- @responses[@order.first].call
- return
- else
- if @responses[priority]
- @responses[priority].call
- return # mime type match found, be happy and return
- end
- end
- end
-
- if @order.include?(Mime::ALL)
- @responses[Mime::ALL].call
- else
- @controller.send :head, :not_acceptable
- end
- end
end
end
end
@@ -11,11 +11,10 @@ def process_action(*)
def render(options)
super
- options[:_template] ||= _action_view._partial
self.content_type ||= begin
mime = options[:_template].mime_type
formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first)
- end
+ end.to_s
response_body
end
@@ -106,8 +106,7 @@ def verifiable_request_format?
!request.content_type.nil? && request.content_type.verify_request?
end
- # Sets the token value for the current session. Pass a <tt>:secret</tt> option
- # in +protect_from_forgery+ to add a custom salt to the hash.
+ # Sets the token value for the current session.
def form_authenticity_token
session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end
@@ -139,7 +139,7 @@ module ActionController
# # In routes.rb
# map.with_options :controller => 'blog' do |blog|
# blog.show '', :action => 'list'
- # blog.delete 'delete/:id', :action => 'delete',
+ # blog.delete 'delete/:id', :action => 'delete'
# blog.edit 'edit/:id', :action => 'edit'
# end
#
@@ -93,7 +93,7 @@ def self.included(base) #:nodoc:
#
# * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
- # * <tt>:host</tt> - Specifies the host the link should be targetted at.
+ # * <tt>:host</tt> - Specifies the host the link should be targeted at.
# If <tt>:only_path</tt> is false, this option must be
# provided either explicitly, or via +default_url_options+.
# * <tt>:port</tt> - Optionally specify the port to connect to.
@@ -155,7 +155,7 @@ def #{selector}(options = nil) # def hash_f
def define_url_helper(route, name, kind, options)
selector = url_helper_name(name, kind)
- # The segment keys used for positional paramters
+ # The segment keys used for positional parameters
hash_access_method = hash_access_name(name, kind)
Oops, something went wrong.

0 comments on commit 3de59e9

Please sign in to comment.