mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge branch 'master' of github.com:rails/rails
This commit is contained in:
commit
8b9275340f
30 changed files with 576 additions and 557 deletions
|
@ -1,19 +1,24 @@
|
|||
module ActionController
|
||||
|
||||
def self.add_renderer(key, &block)
|
||||
RenderOptions.add(key, &block)
|
||||
end
|
||||
|
||||
module RenderOptions
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extlib_inheritable_accessor :_renderers
|
||||
self._renderers = []
|
||||
self._renderers = {}
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def _write_render_options
|
||||
renderers = _renderers.map do |r|
|
||||
renderers = _renderers.map do |name, value|
|
||||
<<-RUBY_EVAL
|
||||
if options.key?(:#{r})
|
||||
if options.key?(:#{name})
|
||||
_process_options(options)
|
||||
return render_#{r}(options[:#{r}], options)
|
||||
return _render_option_#{name}(options[:#{name}], options)
|
||||
end
|
||||
RUBY_EVAL
|
||||
end
|
||||
|
@ -25,79 +30,63 @@ module ActionController
|
|||
RUBY_EVAL
|
||||
end
|
||||
|
||||
def _add_render_option(name)
|
||||
_renderers << name
|
||||
def use_renderers(*args)
|
||||
args.each do |key|
|
||||
_renderers[key] = RENDERERS[key]
|
||||
end
|
||||
_write_render_options
|
||||
end
|
||||
alias use_renderer use_renderers
|
||||
end
|
||||
|
||||
def render_to_body(options)
|
||||
_handle_render_options(options) || super
|
||||
end
|
||||
end
|
||||
|
||||
module RenderOption #:nodoc:
|
||||
def self.extended(base)
|
||||
base.extend ActiveSupport::Concern
|
||||
base.send :include, ::ActionController::RenderOptions
|
||||
|
||||
def base.register_renderer(name)
|
||||
included { _add_render_option(name) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module RenderOptions
|
||||
module Json
|
||||
extend RenderOption
|
||||
register_renderer :json
|
||||
|
||||
def render_json(json, options)
|
||||
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
|
||||
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
|
||||
self.content_type ||= Mime::JSON
|
||||
self.response_body = json
|
||||
end
|
||||
end
|
||||
|
||||
module Js
|
||||
extend RenderOption
|
||||
register_renderer :js
|
||||
|
||||
def render_js(js, options)
|
||||
self.content_type ||= Mime::JS
|
||||
self.response_body = js.respond_to?(:to_js) ? js.to_js : js
|
||||
end
|
||||
end
|
||||
|
||||
module Xml
|
||||
extend RenderOption
|
||||
register_renderer :xml
|
||||
|
||||
def render_xml(xml, options)
|
||||
self.content_type ||= Mime::XML
|
||||
self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
|
||||
end
|
||||
end
|
||||
|
||||
module RJS
|
||||
extend RenderOption
|
||||
register_renderer :update
|
||||
|
||||
def render_update(proc, options)
|
||||
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
|
||||
self.content_type = Mime::JS
|
||||
self.response_body = generator.to_s
|
||||
end
|
||||
RENDERERS = {}
|
||||
def self.add(key, &block)
|
||||
define_method("_render_option_#{key}", &block)
|
||||
RENDERERS[key] = block
|
||||
All._write_render_options
|
||||
end
|
||||
|
||||
module All
|
||||
extend ActiveSupport::Concern
|
||||
include RenderOptions
|
||||
|
||||
include ActionController::RenderOptions::Json
|
||||
include ActionController::RenderOptions::Js
|
||||
include ActionController::RenderOptions::Xml
|
||||
include ActionController::RenderOptions::RJS
|
||||
INCLUDED = []
|
||||
included do
|
||||
self._renderers = RENDERERS
|
||||
_write_render_options
|
||||
INCLUDED << self
|
||||
end
|
||||
|
||||
def self._write_render_options
|
||||
INCLUDED.each(&:_write_render_options)
|
||||
end
|
||||
end
|
||||
|
||||
add :json do |json, options|
|
||||
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
|
||||
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
|
||||
self.content_type ||= Mime::JSON
|
||||
self.response_body = json
|
||||
end
|
||||
|
||||
add :js do |js, options|
|
||||
self.content_type ||= Mime::JS
|
||||
self.response_body = js.respond_to?(:to_js) ? js.to_js : js
|
||||
end
|
||||
|
||||
add :xml do |xml, options|
|
||||
self.content_type ||= Mime::XML
|
||||
self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
|
||||
end
|
||||
|
||||
add :update do |proc, options|
|
||||
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
|
||||
self.content_type = Mime::JS
|
||||
self.response_body = generator.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,272 +1,118 @@
|
|||
module ActionDispatch
|
||||
module Routing
|
||||
class Mapper
|
||||
module Resources
|
||||
class Resource #:nodoc:
|
||||
attr_reader :plural, :singular
|
||||
attr_reader :path_prefix, :name_prefix
|
||||
|
||||
def initialize(entities, options = {})
|
||||
entities = entities.to_s
|
||||
|
||||
@plural = entities.pluralize
|
||||
@singular = entities.singularize
|
||||
|
||||
@path_prefix = options[:path_prefix]
|
||||
@name_prefix = options[:name_prefix]
|
||||
end
|
||||
|
||||
def name
|
||||
plural
|
||||
end
|
||||
|
||||
def controller
|
||||
plural
|
||||
end
|
||||
|
||||
def member_name
|
||||
if name_prefix
|
||||
"#{name_prefix}_#{singular}"
|
||||
else
|
||||
singular
|
||||
end
|
||||
end
|
||||
|
||||
def collection_name
|
||||
if name_prefix
|
||||
"#{name_prefix}_#{plural}"
|
||||
else
|
||||
plural
|
||||
end
|
||||
end
|
||||
|
||||
def new_name
|
||||
if name_prefix
|
||||
"new_#{name_prefix}_#{singular}"
|
||||
else
|
||||
"new_#{singular}"
|
||||
end
|
||||
end
|
||||
|
||||
def edit_name
|
||||
if name_prefix
|
||||
"edit_#{name_prefix}_#{singular}"
|
||||
else
|
||||
"edit_#{singular}"
|
||||
end
|
||||
class Constraints
|
||||
def new(app, constraints = [])
|
||||
if constraints.any?
|
||||
super(app, constraints)
|
||||
else
|
||||
app
|
||||
end
|
||||
end
|
||||
|
||||
class SingletonResource < Resource #:nodoc:
|
||||
def initialize(entity, options = {})
|
||||
super(entity)
|
||||
end
|
||||
|
||||
def name
|
||||
singular
|
||||
end
|
||||
def initialize(app, constraints = [])
|
||||
@app, @constraints = app, constraints
|
||||
end
|
||||
|
||||
def resource(*resources, &block)
|
||||
options = resources.extract_options!
|
||||
def call(env)
|
||||
req = Rack::Request.new(env)
|
||||
|
||||
if resources.length > 1
|
||||
raise ArgumentError if block_given?
|
||||
resources.each { |r| resource(r, options) }
|
||||
return self
|
||||
end
|
||||
|
||||
name_prefix = @scope[:options][:name_prefix] if @scope[:options]
|
||||
resource = SingletonResource.new(resources.pop, :name_prefix => name_prefix)
|
||||
|
||||
if @scope[:scope_level] == :resources
|
||||
parent_resource = @scope[:scope_level_options][:name]
|
||||
parent_named_prefix = @scope[:scope_level_options][:name_prefix]
|
||||
with_scope_level(:member) do
|
||||
scope(":#{parent_resource}_id", :name_prefix => parent_named_prefix) do
|
||||
resource(resource.name, options, &block)
|
||||
end
|
||||
@constraints.each { |constraint|
|
||||
if constraint.respond_to?(:matches?) && !constraint.matches?(req)
|
||||
return [417, {}, []]
|
||||
elsif constraint.respond_to?(:call) && !constraint.call(req)
|
||||
return [417, {}, []]
|
||||
end
|
||||
return self
|
||||
end
|
||||
}
|
||||
|
||||
controller(resource.controller) do
|
||||
namespace(resource.name) do
|
||||
with_scope_level(:resource, :name => resource.singular, :name_prefix => resource.member_name) do
|
||||
yield if block_given?
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
get "", :to => :show, :as => resource.member_name
|
||||
post "", :to => :create
|
||||
put "", :to => :update
|
||||
delete "", :to => :destroy
|
||||
get "new", :to => :new, :as => resource.new_name
|
||||
get "edit", :to => :edit, :as => resource.edit_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self
|
||||
module Base
|
||||
def initialize(set)
|
||||
@set = set
|
||||
end
|
||||
|
||||
def resources(*resources, &block)
|
||||
options = resources.extract_options!
|
||||
|
||||
if resources.length > 1
|
||||
raise ArgumentError if block_given?
|
||||
resources.each { |r| resources(r, options) }
|
||||
return self
|
||||
end
|
||||
|
||||
name_prefix = @scope[:options][:name_prefix] if @scope[:options]
|
||||
resource = Resource.new(resources.pop, :name_prefix => name_prefix)
|
||||
|
||||
if @scope[:scope_level] == :resources
|
||||
parent_resource = @scope[:scope_level_options][:name]
|
||||
parent_named_prefix = @scope[:scope_level_options][:name_prefix]
|
||||
with_scope_level(:member) do
|
||||
scope(":#{parent_resource}_id", :name_prefix => parent_named_prefix) do
|
||||
resources(resource.name, options, &block)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
controller(resource.controller) do
|
||||
namespace(resource.name) do
|
||||
with_scope_level(:resources, :name => resource.singular, :name_prefix => resource.member_name) do
|
||||
yield if block_given?
|
||||
|
||||
collection do
|
||||
get "", :to => :index, :as => resource.collection_name
|
||||
post "", :to => :create
|
||||
get "new", :to => :new, :as => resource.new_name
|
||||
end
|
||||
|
||||
member do
|
||||
get "", :to => :show, :as => resource.member_name
|
||||
put "", :to => :update
|
||||
delete "", :to => :destroy
|
||||
get "edit", :to => :edit, :as => resource.edit_name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def collection
|
||||
unless @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't use collection outside resources scope"
|
||||
end
|
||||
|
||||
with_scope_level(:collection) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def member
|
||||
unless @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't use member outside resources scope"
|
||||
end
|
||||
|
||||
with_scope_level(:member) do
|
||||
scope(":id") do
|
||||
yield
|
||||
end
|
||||
end
|
||||
def root(options = {})
|
||||
match '/', options.merge(:as => :root)
|
||||
end
|
||||
|
||||
def match(*args)
|
||||
options = args.extract_options!
|
||||
args.push(options)
|
||||
|
||||
case options.delete(:on)
|
||||
when :collection
|
||||
return collection { match(*args) }
|
||||
when :member
|
||||
return member { match(*args) }
|
||||
end
|
||||
path = args.first
|
||||
|
||||
if @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't define route directly in resources scope"
|
||||
end
|
||||
conditions, defaults = {}, {}
|
||||
|
||||
super
|
||||
end
|
||||
path = nil if path == ""
|
||||
path = "#{@scope[:path]}#{path}" if @scope[:path]
|
||||
path = Rack::Mount::Utils.normalize_path(path) if path
|
||||
|
||||
private
|
||||
def with_scope_level(kind, options = {})
|
||||
old, @scope[:scope_level] = @scope[:scope_level], kind
|
||||
old_options, @scope[:scope_level_options] = @scope[:scope_level_options], options
|
||||
yield
|
||||
ensure
|
||||
@scope[:scope_level] = old
|
||||
@scope[:scope_level_options] = old_options
|
||||
end
|
||||
end
|
||||
raise ArgumentError, "path is required" unless path
|
||||
|
||||
module Scoping
|
||||
def self.extended(object)
|
||||
object.instance_eval do
|
||||
@scope = {}
|
||||
end
|
||||
end
|
||||
|
||||
def scope(*args)
|
||||
options = args.extract_options!
|
||||
|
||||
constraints = options.delete(:constraints) || {}
|
||||
constraints = options[:constraints] || {}
|
||||
unless constraints.is_a?(Hash)
|
||||
block, constraints = constraints, {}
|
||||
end
|
||||
constraints, @scope[:constraints] = @scope[:constraints], (@scope[:constraints] || {}).merge(constraints)
|
||||
blocks, @scope[:blocks] = @scope[:blocks], (@scope[:blocks] || []) + [block]
|
||||
blocks = ((@scope[:blocks] || []) + [block]).compact
|
||||
constraints = (@scope[:constraints] || {}).merge(constraints)
|
||||
options.each { |k, v| constraints[k] = v if v.is_a?(Regexp) }
|
||||
|
||||
options, @scope[:options] = @scope[:options], (@scope[:options] || {}).merge(options)
|
||||
conditions[:path_info] = path
|
||||
requirements = constraints.dup
|
||||
|
||||
path_set = controller_set = false
|
||||
path_regexp = Rack::Mount::Strexp.compile(path, constraints, SEPARATORS)
|
||||
segment_keys = Rack::Mount::RegexpWithNamedGroups.new(path_regexp).names
|
||||
constraints.reject! { |k, v| segment_keys.include?(k.to_s) }
|
||||
conditions.merge!(constraints)
|
||||
|
||||
case args.first
|
||||
when String
|
||||
path_set = true
|
||||
path = args.first
|
||||
path, @scope[:path] = @scope[:path], "#{@scope[:path]}#{Rack::Mount::Utils.normalize_path(path)}"
|
||||
when Symbol
|
||||
controller_set = true
|
||||
controller = args.first
|
||||
controller, @scope[:controller] = @scope[:controller], controller
|
||||
requirements[:controller] ||= @set.controller_constraints
|
||||
|
||||
if via = options[:via]
|
||||
via = Array(via).map { |m| m.to_s.upcase }
|
||||
conditions[:request_method] = Regexp.union(*via)
|
||||
end
|
||||
|
||||
yield
|
||||
defaults[:controller] ||= @scope[:controller].to_s if @scope[:controller]
|
||||
|
||||
app = initialize_app_endpoint(options, defaults)
|
||||
validate_defaults!(app, defaults, segment_keys)
|
||||
app = Constraints.new(app, blocks)
|
||||
|
||||
@set.add_route(app, conditions, requirements, defaults, options[:as])
|
||||
|
||||
self
|
||||
ensure
|
||||
@scope[:path] = path if path_set
|
||||
@scope[:controller] = controller if controller_set
|
||||
@scope[:options] = options
|
||||
@scope[:blocks] = blocks
|
||||
@scope[:constraints] = constraints
|
||||
end
|
||||
|
||||
def controller(controller)
|
||||
scope(controller.to_sym) { yield }
|
||||
end
|
||||
private
|
||||
def initialize_app_endpoint(options, defaults)
|
||||
app = nil
|
||||
|
||||
def namespace(path)
|
||||
scope(path.to_s) { yield }
|
||||
end
|
||||
if options[:to].respond_to?(:call)
|
||||
app = options[:to]
|
||||
defaults.delete(:controller)
|
||||
defaults.delete(:action)
|
||||
elsif options[:to].is_a?(String)
|
||||
defaults[:controller], defaults[:action] = options[:to].split('#')
|
||||
elsif options[:to].is_a?(Symbol)
|
||||
defaults[:action] = options[:to].to_s
|
||||
end
|
||||
|
||||
def constraints(constraints = {})
|
||||
scope(:constraints => constraints) { yield }
|
||||
end
|
||||
app || Routing::RouteSet::Dispatcher.new(:defaults => defaults)
|
||||
end
|
||||
|
||||
def match(*args)
|
||||
options = args.extract_options!
|
||||
options = (@scope[:options] || {}).merge(options)
|
||||
args.push(options)
|
||||
super(*args)
|
||||
end
|
||||
def validate_defaults!(app, defaults, segment_keys)
|
||||
return unless app.is_a?(Routing::RouteSet::Dispatcher)
|
||||
|
||||
unless defaults.include?(:controller) || segment_keys.include?("controller")
|
||||
raise ArgumentError, "missing :controller"
|
||||
end
|
||||
|
||||
unless defaults.include?(:action) || segment_keys.include?("action")
|
||||
raise ArgumentError, "missing :action"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module HttpHelpers
|
||||
|
@ -305,130 +151,299 @@ module ActionDispatch
|
|||
end
|
||||
end
|
||||
|
||||
class Constraints
|
||||
def new(app, constraints = [])
|
||||
if constraints.any?
|
||||
super(app, constraints)
|
||||
module Scoping
|
||||
def initialize(*args)
|
||||
@scope = {}
|
||||
super
|
||||
end
|
||||
|
||||
def scope(*args)
|
||||
options = args.extract_options!
|
||||
|
||||
case args.first
|
||||
when String
|
||||
options[:path] = args.first
|
||||
when Symbol
|
||||
options[:controller] = args.first
|
||||
end
|
||||
|
||||
if path = options.delete(:path)
|
||||
path_set = true
|
||||
path, @scope[:path] = @scope[:path], Rack::Mount::Utils.normalize_path(@scope[:path].to_s + path.to_s)
|
||||
else
|
||||
app
|
||||
path_set = false
|
||||
end
|
||||
|
||||
if name_prefix = options.delete(:name_prefix)
|
||||
name_prefix_set = true
|
||||
name_prefix, @scope[:name_prefix] = @scope[:name_prefix], (@scope[:name_prefix] ? "#{@scope[:name_prefix]}_#{name_prefix}" : name_prefix)
|
||||
else
|
||||
name_prefix_set = false
|
||||
end
|
||||
|
||||
if controller = options.delete(:controller)
|
||||
controller_set = true
|
||||
controller, @scope[:controller] = @scope[:controller], controller
|
||||
else
|
||||
controller_set = false
|
||||
end
|
||||
|
||||
constraints = options.delete(:constraints) || {}
|
||||
unless constraints.is_a?(Hash)
|
||||
block, constraints = constraints, {}
|
||||
end
|
||||
constraints, @scope[:constraints] = @scope[:constraints], (@scope[:constraints] || {}).merge(constraints)
|
||||
blocks, @scope[:blocks] = @scope[:blocks], (@scope[:blocks] || []) + [block]
|
||||
|
||||
options, @scope[:options] = @scope[:options], (@scope[:options] || {}).merge(options)
|
||||
|
||||
yield
|
||||
|
||||
self
|
||||
ensure
|
||||
@scope[:path] = path if path_set
|
||||
@scope[:name_prefix] = name_prefix if name_prefix_set
|
||||
@scope[:controller] = controller if controller_set
|
||||
@scope[:options] = options
|
||||
@scope[:blocks] = blocks
|
||||
@scope[:constraints] = constraints
|
||||
end
|
||||
|
||||
def controller(controller)
|
||||
scope(controller.to_sym) { yield }
|
||||
end
|
||||
|
||||
def namespace(path)
|
||||
scope("/#{path}") { yield }
|
||||
end
|
||||
|
||||
def constraints(constraints = {})
|
||||
scope(:constraints => constraints) { yield }
|
||||
end
|
||||
|
||||
def match(*args)
|
||||
options = args.extract_options!
|
||||
|
||||
options = (@scope[:options] || {}).merge(options)
|
||||
|
||||
if @scope[:name_prefix] && !options[:as].blank?
|
||||
options[:as] = "#{@scope[:name_prefix]}_#{options[:as]}"
|
||||
elsif @scope[:name_prefix] && options[:as] == ""
|
||||
options[:as] = @scope[:name_prefix].to_s
|
||||
end
|
||||
|
||||
args.push(options)
|
||||
super(*args)
|
||||
end
|
||||
end
|
||||
|
||||
module Resources
|
||||
class Resource #:nodoc:
|
||||
attr_reader :plural, :singular
|
||||
|
||||
def initialize(entities, options = {})
|
||||
entities = entities.to_s
|
||||
|
||||
@plural = entities.pluralize
|
||||
@singular = entities.singularize
|
||||
end
|
||||
|
||||
def name
|
||||
plural
|
||||
end
|
||||
|
||||
def controller
|
||||
plural
|
||||
end
|
||||
|
||||
def member_name
|
||||
singular
|
||||
end
|
||||
|
||||
def collection_name
|
||||
plural
|
||||
end
|
||||
|
||||
def id_segment
|
||||
":#{singular}_id"
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(app, constraints = [])
|
||||
@app, @constraints = app, constraints
|
||||
class SingletonResource < Resource #:nodoc:
|
||||
def initialize(entity, options = {})
|
||||
super
|
||||
end
|
||||
|
||||
def name
|
||||
singular
|
||||
end
|
||||
end
|
||||
|
||||
def call(env)
|
||||
req = Rack::Request.new(env)
|
||||
def resource(*resources, &block)
|
||||
options = resources.extract_options!
|
||||
|
||||
@constraints.each { |constraint|
|
||||
if constraint.respond_to?(:matches?) && !constraint.matches?(req)
|
||||
return [417, {}, []]
|
||||
elsif constraint.respond_to?(:call) && !constraint.call(req)
|
||||
return [417, {}, []]
|
||||
if resources.length > 1
|
||||
raise ArgumentError if block_given?
|
||||
resources.each { |r| resource(r, options) }
|
||||
return self
|
||||
end
|
||||
|
||||
resource = SingletonResource.new(resources.pop)
|
||||
|
||||
if @scope[:scope_level] == :resources
|
||||
nested do
|
||||
resource(resource.name, options, &block)
|
||||
end
|
||||
}
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(set)
|
||||
@set = set
|
||||
|
||||
extend HttpHelpers
|
||||
extend Scoping
|
||||
extend Resources
|
||||
end
|
||||
|
||||
def root(options = {})
|
||||
match '/', options.merge(:as => :root)
|
||||
end
|
||||
|
||||
def match(*args)
|
||||
options = args.extract_options!
|
||||
|
||||
if args.length > 1
|
||||
args.each { |path| match(path, options) }
|
||||
return self
|
||||
end
|
||||
|
||||
if args.first.is_a?(Symbol)
|
||||
return match(args.first.to_s, options.merge(:to => args.first.to_sym))
|
||||
end
|
||||
|
||||
path = args.first
|
||||
|
||||
conditions, defaults = {}, {}
|
||||
|
||||
path = nil if path == ""
|
||||
path = Rack::Mount::Utils.normalize_path(path) if path
|
||||
path = "#{@scope[:path]}#{path}" if @scope[:path]
|
||||
|
||||
raise ArgumentError, "path is required" unless path
|
||||
|
||||
constraints = options[:constraints] || {}
|
||||
unless constraints.is_a?(Hash)
|
||||
block, constraints = constraints, {}
|
||||
end
|
||||
blocks = ((@scope[:blocks] || []) + [block]).compact
|
||||
constraints = (@scope[:constraints] || {}).merge(constraints)
|
||||
options.each { |k, v| constraints[k] = v if v.is_a?(Regexp) }
|
||||
|
||||
conditions[:path_info] = path
|
||||
requirements = constraints.dup
|
||||
|
||||
path_regexp = Rack::Mount::Strexp.compile(path, constraints, SEPARATORS)
|
||||
segment_keys = Rack::Mount::RegexpWithNamedGroups.new(path_regexp).names
|
||||
constraints.reject! { |k, v| segment_keys.include?(k.to_s) }
|
||||
conditions.merge!(constraints)
|
||||
|
||||
requirements[:controller] ||= @set.controller_constraints
|
||||
|
||||
if via = options[:via]
|
||||
via = Array(via).map { |m| m.to_s.upcase }
|
||||
conditions[:request_method] = Regexp.union(*via)
|
||||
end
|
||||
|
||||
defaults[:controller] ||= @scope[:controller].to_s if @scope[:controller]
|
||||
|
||||
app = initialize_app_endpoint(options, defaults)
|
||||
validate_defaults!(app, defaults, segment_keys)
|
||||
app = Constraints.new(app, blocks)
|
||||
|
||||
@set.add_route(app, conditions, requirements, defaults, options[:as])
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
def initialize_app_endpoint(options, defaults)
|
||||
app = nil
|
||||
|
||||
if options[:to].respond_to?(:call)
|
||||
app = options[:to]
|
||||
defaults.delete(:controller)
|
||||
defaults.delete(:action)
|
||||
elsif options[:to].is_a?(String)
|
||||
defaults[:controller], defaults[:action] = options[:to].split('#')
|
||||
elsif options[:to].is_a?(Symbol)
|
||||
defaults[:action] = options[:to].to_s
|
||||
return self
|
||||
end
|
||||
|
||||
app || Routing::RouteSet::Dispatcher.new(:defaults => defaults)
|
||||
end
|
||||
scope(:path => "/#{resource.name}", :controller => resource.controller) do
|
||||
with_scope_level(:resource, resource) do
|
||||
yield if block_given?
|
||||
|
||||
def validate_defaults!(app, defaults, segment_keys)
|
||||
return unless app.is_a?(Routing::RouteSet::Dispatcher)
|
||||
|
||||
unless defaults.include?(:controller) || segment_keys.include?("controller")
|
||||
raise ArgumentError, "missing :controller"
|
||||
get "(.:format)", :to => :show, :as => resource.member_name
|
||||
post "(.:format)", :to => :create
|
||||
put "(.:format)", :to => :update
|
||||
delete "(.:format)", :to => :destroy
|
||||
get "/new(.:format)", :to => :new, :as => "new_#{resource.singular}"
|
||||
get "/edit(.:format)", :to => :edit, :as => "edit_#{resource.singular}"
|
||||
end
|
||||
end
|
||||
|
||||
unless defaults.include?(:action) || segment_keys.include?("action")
|
||||
raise ArgumentError, "missing :action"
|
||||
self
|
||||
end
|
||||
|
||||
def resources(*resources, &block)
|
||||
options = resources.extract_options!
|
||||
|
||||
if resources.length > 1
|
||||
raise ArgumentError if block_given?
|
||||
resources.each { |r| resources(r, options) }
|
||||
return self
|
||||
end
|
||||
|
||||
resource = Resource.new(resources.pop)
|
||||
|
||||
if @scope[:scope_level] == :resources
|
||||
nested do
|
||||
resources(resource.name, options, &block)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
scope(:path => "/#{resource.name}", :controller => resource.controller) do
|
||||
with_scope_level(:resources, resource) do
|
||||
yield if block_given?
|
||||
|
||||
with_scope_level(:collection) do
|
||||
get "(.:format)", :to => :index, :as => resource.collection_name
|
||||
post "(.:format)", :to => :create
|
||||
get "/new(.:format)", :to => :new, :as => "new_#{resource.singular}"
|
||||
end
|
||||
|
||||
with_scope_level(:member) do
|
||||
scope("/:id") do
|
||||
get "(.:format)", :to => :show, :as => resource.member_name
|
||||
put "(.:format)", :to => :update
|
||||
delete "(.:format)", :to => :destroy
|
||||
get "/edit(.:format)", :to => :edit, :as => "edit_#{resource.singular}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def collection
|
||||
unless @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't use collection outside resources scope"
|
||||
end
|
||||
|
||||
with_scope_level(:collection) do
|
||||
scope(:name_prefix => parent_resource.collection_name, :as => "") do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def member
|
||||
unless @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't use member outside resources scope"
|
||||
end
|
||||
|
||||
with_scope_level(:member) do
|
||||
scope("/:id", :name_prefix => parent_resource.member_name, :as => "") do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def nested
|
||||
unless @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't use nested outside resources scope"
|
||||
end
|
||||
|
||||
with_scope_level(:nested) do
|
||||
scope("/#{parent_resource.id_segment}", :name_prefix => parent_resource.member_name) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def match(*args)
|
||||
options = args.extract_options!
|
||||
|
||||
if args.length > 1
|
||||
args.each { |path| match(path, options) }
|
||||
return self
|
||||
end
|
||||
|
||||
if args.first.is_a?(Symbol)
|
||||
begin
|
||||
old_name_prefix, @scope[:name_prefix] = @scope[:name_prefix], "#{args.first}_#{@scope[:name_prefix]}"
|
||||
return match("/#{args.first}(.:format)", options.merge(:to => args.first.to_sym))
|
||||
ensure
|
||||
@scope[:name_prefix] = old_name_prefix
|
||||
end
|
||||
end
|
||||
|
||||
args.push(options)
|
||||
|
||||
case options.delete(:on)
|
||||
when :collection
|
||||
return collection { match(*args) }
|
||||
when :member
|
||||
return member { match(*args) }
|
||||
end
|
||||
|
||||
if @scope[:scope_level] == :resources
|
||||
raise ArgumentError, "can't define route directly in resources scope"
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
protected
|
||||
def parent_resource
|
||||
@scope[:scope_level_resource]
|
||||
end
|
||||
|
||||
private
|
||||
def with_scope_level(kind, resource = parent_resource)
|
||||
old, @scope[:scope_level] = @scope[:scope_level], kind
|
||||
old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource
|
||||
yield
|
||||
ensure
|
||||
@scope[:scope_level] = old
|
||||
@scope[:scope_level_resource] = old_resource
|
||||
end
|
||||
end
|
||||
|
||||
include Base
|
||||
include HttpHelpers
|
||||
include Scoping
|
||||
include Resources
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -216,7 +216,14 @@ module ActionDispatch
|
|||
|
||||
def draw(&block)
|
||||
clear!
|
||||
Mapper.new(self).instance_exec(DeprecatedMapper.new(self), &block)
|
||||
|
||||
mapper = Mapper.new(self)
|
||||
if block.arity == 1
|
||||
mapper.instance_exec(DeprecatedMapper.new(self), &block)
|
||||
else
|
||||
mapper.instance_exec(&block)
|
||||
end
|
||||
|
||||
@set.add_route(NotFound)
|
||||
install_helpers
|
||||
@set.freeze
|
||||
|
|
|
@ -83,7 +83,7 @@ class ActiveSupport::TestCase
|
|||
# have been loaded.
|
||||
setup_once do
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.connect ':controller/:action/:id'
|
||||
match ':controller(/:action(/:id))'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -155,7 +155,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
|
|||
def with_test_route_set(options = {})
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.connect "/:action", :controller => "active_record_store_test/test"
|
||||
match ':action', :to => 'active_record_store_test/test'
|
||||
end
|
||||
@app = ActiveRecord::SessionStore.new(set, options.reverse_merge(:key => '_session_id'))
|
||||
yield
|
||||
|
|
|
@ -221,8 +221,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
|||
def test_assert_redirect_to_named_route
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.route_one 'route_one', :controller => 'action_pack_assertions', :action => 'nothing'
|
||||
map.connect ':controller/:action/:id'
|
||||
match 'route_one', :to => 'action_pack_assertions#nothing', :as => :route_one
|
||||
match ':controller/:action'
|
||||
end
|
||||
set.install_helpers
|
||||
|
||||
|
@ -235,9 +235,9 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
|||
def test_assert_redirect_to_named_route_failure
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.route_one 'route_one', :controller => 'action_pack_assertions', :action => 'nothing', :id => 'one'
|
||||
map.route_two 'route_two', :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
|
||||
map.connect ':controller/:action/:id'
|
||||
match 'route_one', :to => 'action_pack_assertions#nothing', :as => :route_one
|
||||
match 'route_two', :to => 'action_pack_assertions#nothing', :id => 'two', :as => :route_two
|
||||
match ':controller/:action'
|
||||
end
|
||||
process :redirect_to_named_route
|
||||
assert_raise(ActiveSupport::TestCase::Assertion) do
|
||||
|
@ -255,8 +255,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
|||
def test_assert_redirect_to_nested_named_route
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.admin_inner_module 'admin/inner_module', :controller => 'admin/inner_module', :action => 'index'
|
||||
map.connect ':controller/:action/:id'
|
||||
match 'admin/inner_module', :to => 'admin/inner_module#index', :as => :admin_inner_module
|
||||
match ':controller/:action'
|
||||
end
|
||||
@controller = Admin::InnerModuleController.new
|
||||
process :redirect_to_index
|
||||
|
@ -268,8 +268,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
|||
def test_assert_redirected_to_top_level_named_route_from_nested_controller
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.top_level '/action_pack_assertions/:id', :controller => 'action_pack_assertions', :action => 'index'
|
||||
map.connect ':controller/:action/:id'
|
||||
match '/action_pack_assertions/:id', :to => 'action_pack_assertions#index', :as => :top_level
|
||||
match ':controller/:action'
|
||||
end
|
||||
@controller = Admin::InnerModuleController.new
|
||||
process :redirect_to_top_level_named_route
|
||||
|
@ -282,8 +282,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
|||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
# this controller exists in the admin namespace as well which is the only difference from previous test
|
||||
map.top_level '/user/:id', :controller => 'user', :action => 'index'
|
||||
map.connect ':controller/:action/:id'
|
||||
match '/user/:id', :to => 'user#index', :as => :top_level
|
||||
match ':controller/:action'
|
||||
end
|
||||
@controller = Admin::InnerModuleController.new
|
||||
process :redirect_to_top_level_named_route
|
||||
|
|
|
@ -179,8 +179,8 @@ class DefaultUrlOptionsTest < ActionController::TestCase
|
|||
def test_default_url_options_are_used_if_set
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.default_url_options 'default_url_options', :controller => 'default_url_options'
|
||||
map.connect ':controller/:action/:id'
|
||||
match 'default_url_options', :to => 'default_url_options#default_url_options_action', :as => :default_url_options
|
||||
match ':controller/:action'
|
||||
end
|
||||
|
||||
get :default_url_options_action # Make a dummy request so that the controller is initialized properly.
|
||||
|
@ -210,7 +210,7 @@ class EnsureNamedRoutesWorksTicket22BugTest < ActionController::TestCase
|
|||
def test_named_routes_still_work
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :things
|
||||
resources :things
|
||||
end
|
||||
EmptyController.send :include, ActionController::UrlWriter
|
||||
|
||||
|
|
|
@ -70,8 +70,8 @@ class PageCachingTest < ActionController::TestCase
|
|||
def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.main '', :controller => 'posts', :format => nil
|
||||
map.formatted_posts 'posts.:format', :controller => 'posts'
|
||||
match 'posts.:format', :to => 'posts#index', :as => :formatted_posts
|
||||
match '/', :to => 'posts#index', :as => :main
|
||||
end
|
||||
@params[:format] = 'rss'
|
||||
assert_equal '/posts.rss', @rewriter.rewrite(@params)
|
||||
|
@ -422,8 +422,7 @@ class ActionCacheTest < ActionController::TestCase
|
|||
def test_xml_version_of_resource_is_treated_as_different_cache
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.connect ':controller/:action.:format'
|
||||
map.connect ':controller/:action'
|
||||
match ':controller(/:action(.:format))'
|
||||
end
|
||||
|
||||
get :index, :format => 'xml'
|
||||
|
|
|
@ -853,9 +853,11 @@ class RespondWithControllerTest < ActionController::TestCase
|
|||
def with_test_route_set
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :customers
|
||||
map.resources :quiz_stores, :has_many => :customers
|
||||
map.connect ":controller/:action/:id"
|
||||
resources :customers
|
||||
resources :quiz_stores do
|
||||
resources :customers
|
||||
end
|
||||
match ":controller/:action"
|
||||
end
|
||||
yield
|
||||
end
|
||||
|
|
|
@ -233,8 +233,8 @@ class RedirectTest < ActionController::TestCase
|
|||
def test_redirect_to_record
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :workshops
|
||||
map.connect ':controller/:action/:id'
|
||||
resources :workshops
|
||||
match ':controller/:action'
|
||||
end
|
||||
|
||||
get :redirect_to_existing_record
|
||||
|
|
|
@ -2,6 +2,11 @@ require 'abstract_unit'
|
|||
require 'controller/fake_models'
|
||||
require 'pathname'
|
||||
|
||||
ActionController.add_renderer :simon do |says, options|
|
||||
self.content_type = Mime::TEXT
|
||||
self.response_body = "Simon says: #{says}"
|
||||
end
|
||||
|
||||
class RenderOtherTest < ActionController::TestCase
|
||||
class TestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
@ -109,6 +114,10 @@ class RenderOtherTest < ActionController::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def render_simon_says
|
||||
render :simon => "foo"
|
||||
end
|
||||
|
||||
private
|
||||
def default_render
|
||||
if @alternate_default_render
|
||||
|
@ -240,4 +249,9 @@ class RenderOtherTest < ActionController::TestCase
|
|||
xhr :get, :render_alternate_default
|
||||
assert_equal %(Element.replace("foo", "partial html");), @response.body
|
||||
end
|
||||
|
||||
def test_using_custom_render_option
|
||||
get :render_simon_says
|
||||
assert_equal "Simon says: foo", @response.body
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,35 +39,35 @@ class TestController < ActionController::Base
|
|||
render :action => 'hello_world'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def conditional_hello_with_public_header
|
||||
if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123], :public => true)
|
||||
render :action => 'hello_world'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def conditional_hello_with_public_header_and_expires_at
|
||||
expires_in 1.minute
|
||||
if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123], :public => true)
|
||||
render :action => 'hello_world'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def conditional_hello_with_expires_in
|
||||
expires_in 60.1.seconds
|
||||
render :action => 'hello_world'
|
||||
end
|
||||
|
||||
|
||||
def conditional_hello_with_expires_in_with_public
|
||||
expires_in 1.minute, :public => true
|
||||
render :action => 'hello_world'
|
||||
end
|
||||
|
||||
|
||||
def conditional_hello_with_expires_in_with_public_with_more_keys
|
||||
expires_in 1.minute, :public => true, 'max-stale' => 5.hours
|
||||
render :action => 'hello_world'
|
||||
end
|
||||
|
||||
|
||||
def conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
|
||||
expires_in 1.minute, :public => true, :private => nil, 'max-stale' => 5.hours
|
||||
render :action => 'hello_world'
|
||||
|
@ -272,7 +272,7 @@ class TestController < ActionController::Base
|
|||
def builder_layout_test
|
||||
render :action => "hello", :layout => "layouts/builder"
|
||||
end
|
||||
|
||||
|
||||
# :move: test this in ActionView
|
||||
def builder_partial_test
|
||||
render :action => "hello_world_container"
|
||||
|
@ -1093,8 +1093,8 @@ class RenderTest < ActionController::TestCase
|
|||
def test_head_with_location_object
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :customers
|
||||
map.connect ':controller/:action/:id'
|
||||
resources :customers
|
||||
match ':controller/:action'
|
||||
end
|
||||
|
||||
get :head_with_location_object
|
||||
|
@ -1306,22 +1306,22 @@ class ExpiresInRenderTest < ActionController::TestCase
|
|||
def setup
|
||||
@request.host = "www.nextangle.com"
|
||||
end
|
||||
|
||||
|
||||
def test_expires_in_header
|
||||
get :conditional_hello_with_expires_in
|
||||
assert_equal "max-age=60, private", @response.headers["Cache-Control"]
|
||||
end
|
||||
|
||||
|
||||
def test_expires_in_header_with_public
|
||||
get :conditional_hello_with_expires_in_with_public
|
||||
assert_equal "max-age=60, public", @response.headers["Cache-Control"]
|
||||
end
|
||||
|
||||
|
||||
def test_expires_in_header_with_additional_headers
|
||||
get :conditional_hello_with_expires_in_with_public_with_more_keys
|
||||
assert_equal "max-age=60, public, max-stale=18000", @response.headers["Cache-Control"]
|
||||
end
|
||||
|
||||
|
||||
def test_expires_in_old_syntax
|
||||
get :conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
|
||||
assert_equal "max-age=60, public, max-stale=18000", @response.headers["Cache-Control"]
|
||||
|
@ -1425,12 +1425,12 @@ class EtagRenderTest < ActionController::TestCase
|
|||
get :conditional_hello_with_bangs
|
||||
assert_response :not_modified
|
||||
end
|
||||
|
||||
|
||||
def test_etag_with_public_true_should_set_header
|
||||
get :conditional_hello_with_public_header
|
||||
assert_equal "public", @response.headers['Cache-Control']
|
||||
end
|
||||
|
||||
|
||||
def test_etag_with_public_true_should_set_header_and_retain_other_headers
|
||||
get :conditional_hello_with_public_header_and_expires_at
|
||||
assert_equal "max-age=60, public", @response.headers['Cache-Control']
|
||||
|
|
|
@ -61,8 +61,8 @@ class RenderXmlTest < ActionController::TestCase
|
|||
def test_rendering_with_object_location_should_set_header_with_url_for
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :customers
|
||||
map.connect ':controller/:action/:id'
|
||||
resources :customers
|
||||
match ':controller/:action'
|
||||
end
|
||||
|
||||
get :render_with_object_location
|
||||
|
|
|
@ -456,8 +456,8 @@ XML
|
|||
def test_array_path_parameter_handled_properly
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.connect 'file/*path', :controller => 'test_test/test', :action => 'test_params'
|
||||
map.connect ':controller/:action/:id'
|
||||
match 'file/*path', :to => 'test_test/test#test_params'
|
||||
match ':controller/:action'
|
||||
end
|
||||
|
||||
get :test_params, :path => ['hello', 'world']
|
||||
|
@ -628,17 +628,6 @@ XML
|
|||
assert_nothing_raised(NoMethodError) { @response.binary_content }
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def with_foo_routing
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.generate_url 'foo', :controller => 'test'
|
||||
map.connect ':controller/:action/:id'
|
||||
end
|
||||
yield set
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class InferringClassNameTest < ActionController::TestCase
|
||||
|
@ -673,7 +662,7 @@ class NamedRoutesControllerTest < ActionController::TestCase
|
|||
|
||||
def test_should_be_able_to_use_named_routes_before_a_request_is_done
|
||||
with_routing do |set|
|
||||
set.draw { |map| map.resources :contents }
|
||||
set.draw { |map| resources :contents }
|
||||
assert_equal 'http://test.host/contents/new', new_content_url
|
||||
assert_equal 'http://test.host/contents/1', content_url(:id => 1)
|
||||
end
|
||||
|
|
|
@ -247,7 +247,7 @@ class UrlWriterTests < ActionController::TestCase
|
|||
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.home '/home/sweet/home/:user', :controller => 'home', :action => 'index'
|
||||
match '/home/sweet/home/:user', :to => 'home#index', :as => :home
|
||||
end
|
||||
|
||||
kls = Class.new { include ActionController::UrlWriter }
|
||||
|
@ -264,7 +264,7 @@ class UrlWriterTests < ActionController::TestCase
|
|||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
match 'home/sweet/home/:user', :to => 'home#index', :as => :home
|
||||
map.connect ':controller/:action/:id'
|
||||
match ':controller/:action/:id'
|
||||
end
|
||||
|
||||
# We need to create a new class in order to install the new named route.
|
||||
|
@ -331,8 +331,8 @@ class UrlWriterTests < ActionController::TestCase
|
|||
def test_named_routes_with_nil_keys
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.main '', :controller => 'posts', :format => nil
|
||||
map.resources :posts
|
||||
match 'posts.:format', :to => 'posts#index', :as => :posts
|
||||
match '/', :to => 'posts#index', :as => :main
|
||||
end
|
||||
|
||||
# We need to create a new class in order to install the new named route.
|
||||
|
@ -350,7 +350,7 @@ class UrlWriterTests < ActionController::TestCase
|
|||
def test_formatted_url_methods_are_deprecated
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :posts
|
||||
resources :posts
|
||||
end
|
||||
# We need to create a new class in order to install the new named route.
|
||||
kls = Class.new { include ActionController::UrlWriter }
|
||||
|
|
|
@ -255,9 +255,7 @@ class WebServiceTest < ActionController::IntegrationTest
|
|||
def with_test_route_set
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.with_options :controller => "web_service_test/test" do |c|
|
||||
c.connect "/", :action => "assign_parameters"
|
||||
end
|
||||
match '/', :to => 'web_service_test/test#assign_parameters'
|
||||
end
|
||||
yield
|
||||
end
|
||||
|
|
|
@ -151,7 +151,7 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
|
|||
def with_test_routing
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.connect ':action', :controller => "multipart_params_parsing_test/test"
|
||||
match ':action', :to => 'multipart_params_parsing_test/test'
|
||||
end
|
||||
yield
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
stub_controllers do |routes|
|
||||
Routes = routes
|
||||
Routes.draw do |map|
|
||||
Routes.draw do
|
||||
controller :sessions do
|
||||
get 'login', :to => :new, :as => :login
|
||||
post 'login', :to => :create
|
||||
|
@ -58,8 +58,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
resources :people do
|
||||
namespace ":access_token" do
|
||||
resource :avatar
|
||||
nested do
|
||||
namespace ":access_token" do
|
||||
resource :avatar
|
||||
end
|
||||
end
|
||||
|
||||
member do
|
||||
|
@ -93,9 +95,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
end
|
||||
|
||||
controller :articles do
|
||||
scope 'articles' do
|
||||
scope ':title', :title => /[a-z]+/, :as => :with_title do
|
||||
match ':id', :to => :with_id
|
||||
scope '/articles', :name_prefix => 'article' do
|
||||
scope :path => '/:title', :title => /[a-z]+/, :as => :with_title do
|
||||
match '/:id', :to => :with_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -194,14 +196,26 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
assert_equal 'projects#index', @response.body
|
||||
assert_equal '/projects', projects_path
|
||||
|
||||
get '/projects.xml'
|
||||
assert_equal 'projects#index', @response.body
|
||||
assert_equal '/projects.xml', projects_path(:format => 'xml')
|
||||
|
||||
get '/projects/new'
|
||||
assert_equal 'projects#new', @response.body
|
||||
assert_equal '/projects/new', new_project_path
|
||||
|
||||
get '/projects/new.xml'
|
||||
assert_equal 'projects#new', @response.body
|
||||
assert_equal '/projects/new.xml', new_project_path(:format => 'xml')
|
||||
|
||||
get '/projects/1'
|
||||
assert_equal 'projects#show', @response.body
|
||||
assert_equal '/projects/1', project_path(:id => '1')
|
||||
|
||||
get '/projects/1.xml'
|
||||
assert_equal 'projects#show', @response.body
|
||||
assert_equal '/projects/1.xml', project_path(:id => '1', :format => 'xml')
|
||||
|
||||
get '/projects/1/edit'
|
||||
assert_equal 'projects#edit', @response.body
|
||||
assert_equal '/projects/1/edit', edit_project_path(:id => '1')
|
||||
|
@ -236,10 +250,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
put '/projects/1/participants/update_all'
|
||||
assert_equal 'participants#update_all', @response.body
|
||||
|
||||
pending do
|
||||
assert_equal '/projects/1/participants/update_all', update_all_project_participants_path(:project_id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/participants/update_all', update_all_project_participants_path(:project_id => '1')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -255,9 +266,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
get '/projects/1/companies/1/avatar'
|
||||
assert_equal 'avatars#show', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/companies/1/avatar', project_company_avatar_path(:project_id => '1', :company_id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/companies/1/avatar', project_company_avatar_path(:project_id => '1', :company_id => '1')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -269,9 +278,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
post '/projects/1/images/1/revise'
|
||||
assert_equal 'images#revise', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/images/1/revise', revise_project_image_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/images/1/revise', revise_project_image_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -287,27 +294,19 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
get '/projects/1/people/1/7a2dec8/avatar'
|
||||
assert_equal 'avatars#show', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/people/1/7a2dec8/avatar', project_person_avatar_path(:project_id => '1', :person_id => '1', :access_token => '7a2dec8')
|
||||
end
|
||||
assert_equal '/projects/1/people/1/7a2dec8/avatar', project_person_avatar_path(:project_id => '1', :person_id => '1', :access_token => '7a2dec8')
|
||||
|
||||
put '/projects/1/people/1/accessible_projects'
|
||||
assert_equal 'people#accessible_projects', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/people/1/accessible_projects', accessible_projects_project_person_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/people/1/accessible_projects', accessible_projects_project_person_path(:project_id => '1', :id => '1')
|
||||
|
||||
post '/projects/1/people/1/resend'
|
||||
assert_equal 'people#resend', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/people/1/resend', resend_project_person_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/people/1/resend', resend_project_person_path(:project_id => '1', :id => '1')
|
||||
|
||||
post '/projects/1/people/1/generate_new_password'
|
||||
assert_equal 'people#generate_new_password', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/people/1/generate_new_password', generate_new_password_project_person_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/people/1/generate_new_password', generate_new_password_project_person_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -319,27 +318,19 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
get '/projects/1/posts/archive'
|
||||
assert_equal 'posts#archive', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/posts/archive', archive_project_posts_path(:project_id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/posts/archive', archive_project_posts_path(:project_id => '1')
|
||||
|
||||
get '/projects/1/posts/toggle_view'
|
||||
assert_equal 'posts#toggle_view', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/posts/toggle_view', toggle_view_project_posts_path(:project_id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/posts/toggle_view', toggle_view_project_posts_path(:project_id => '1')
|
||||
|
||||
post '/projects/1/posts/1/preview'
|
||||
assert_equal 'posts#preview', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/posts/1/preview', preview_project_post_path(:project_id => '1', :id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/posts/1/preview', preview_project_post_path(:project_id => '1', :id => '1')
|
||||
|
||||
get '/projects/1/posts/1/subscription'
|
||||
assert_equal 'subscriptions#show', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/posts/1/subscription', project_post_subscription_path(:project_id => '1', :post_id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/posts/1/subscription', project_post_subscription_path(:project_id => '1', :post_id => '1')
|
||||
|
||||
get '/projects/1/posts/1/comments'
|
||||
assert_equal 'comments#index', @response.body
|
||||
|
@ -347,9 +338,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
post '/projects/1/posts/1/comments/preview'
|
||||
assert_equal 'comments#preview', @response.body
|
||||
pending do
|
||||
assert_equal '/projects/1/posts/1/comments/preview', preview_project_post_comments_path(:project_id => '1', :post_id => '1')
|
||||
end
|
||||
assert_equal '/projects/1/posts/1/comments/preview', preview_project_post_comments_path(:project_id => '1', :post_id => '1')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -407,7 +396,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|||
|
||||
assert_raise(ActionController::RoutingError) { get '/articles/123/1' }
|
||||
|
||||
assert_equal '/articles/rails/1', with_title_path(:title => 'rails', :id => 1)
|
||||
assert_equal '/articles/rails/1', article_with_title_path(:title => 'rails', :id => 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -187,10 +187,9 @@ class ScrollsController < ActionController::Base
|
|||
end
|
||||
|
||||
protected
|
||||
|
||||
def rescue_action(e)
|
||||
raise(e)
|
||||
end
|
||||
def rescue_action(e)
|
||||
raise(e)
|
||||
end
|
||||
end
|
||||
|
||||
class AtomFeedTest < ActionController::TestCase
|
||||
|
@ -311,11 +310,12 @@ class AtomFeedTest < ActionController::TestCase
|
|||
assert_select "summary div p", :text => "after 2"
|
||||
end
|
||||
end
|
||||
private
|
||||
|
||||
private
|
||||
def with_restful_routing(resources)
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources(resources)
|
||||
resources(resources)
|
||||
end
|
||||
yield
|
||||
end
|
||||
|
|
|
@ -114,7 +114,7 @@ module ActionView
|
|||
|
||||
test "is able to use named routes" do
|
||||
with_routing do |set|
|
||||
set.draw { |map| map.resources :contents }
|
||||
set.draw { |map| resources :contents }
|
||||
assert_equal 'http://test.host/contents/new', new_content_url
|
||||
assert_equal 'http://test.host/contents/1', content_url(:id => 1)
|
||||
end
|
||||
|
@ -122,7 +122,7 @@ module ActionView
|
|||
|
||||
test "named routes can be used from helper included in view" do
|
||||
with_routing do |set|
|
||||
set.draw { |map| map.resources :contents }
|
||||
set.draw { |map| resources :contents }
|
||||
_helpers.module_eval do
|
||||
def render_from_helper
|
||||
new_content_url
|
||||
|
|
|
@ -451,7 +451,7 @@ class UrlHelperControllerTest < ActionController::TestCase
|
|||
def with_url_helper_routing
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.show_named_route 'url_helper_controller_test/url_helper/show_named_route', :controller => 'url_helper_controller_test/url_helper', :action => 'show_named_route'
|
||||
match 'url_helper_controller_test/url_helper/show_named_route', :to => 'url_helper_controller_test/url_helper#show_named_route', :as => :show_named_route
|
||||
end
|
||||
yield
|
||||
end
|
||||
|
@ -505,7 +505,7 @@ class LinkToUnlessCurrentWithControllerTest < ActionController::TestCase
|
|||
def with_restful_routing
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :tasks
|
||||
resources :tasks
|
||||
end
|
||||
yield
|
||||
end
|
||||
|
@ -625,8 +625,8 @@ class PolymorphicControllerTest < ActionController::TestCase
|
|||
def with_restful_routing
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.resources :workshops do |w|
|
||||
w.resources :sessions
|
||||
resources :workshops do
|
||||
resources :sessions
|
||||
end
|
||||
end
|
||||
yield
|
||||
|
|
|
@ -269,7 +269,7 @@ module Rails
|
|||
#
|
||||
# === Example
|
||||
#
|
||||
# route "map.root :controller => :welcome"
|
||||
# route "root :to => 'welcome'"
|
||||
#
|
||||
def route(routing_code)
|
||||
log :route, routing_code
|
||||
|
|
|
@ -1,43 +1,60 @@
|
|||
ActionController::Routing::Routes.draw do |map|
|
||||
# The priority is based upon order of creation: first created -> highest priority.
|
||||
# The priority is based upon order of creation:
|
||||
# first created -> highest priority.
|
||||
|
||||
# Sample of regular route:
|
||||
# map.connect 'products/:id', :controller => 'catalog', :action => 'view'
|
||||
# match 'products/:id', :to => 'catalog#view'
|
||||
# Keep in mind you can assign values other than :controller and :action
|
||||
|
||||
# Sample of named route:
|
||||
# map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
|
||||
# match 'products/:id/purchase', :to => 'catalog#purchase', :as => :purchase
|
||||
# This route can be invoked with purchase_url(:id => product.id)
|
||||
|
||||
# Sample resource route (maps HTTP verbs to controller actions automatically):
|
||||
# map.resources :products
|
||||
# resources :products
|
||||
|
||||
# Sample resource route with options:
|
||||
# map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
|
||||
# resources :products do
|
||||
# member do
|
||||
# get :short
|
||||
# post :toggle
|
||||
# end
|
||||
#
|
||||
# collection do
|
||||
# get :sold
|
||||
# end
|
||||
# end
|
||||
|
||||
# Sample resource route with sub-resources:
|
||||
# map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
|
||||
|
||||
# resources :products do
|
||||
# resources :comments, :sales
|
||||
# resource :seller
|
||||
# end
|
||||
|
||||
# Sample resource route with more complex sub-resources
|
||||
# map.resources :products do |products|
|
||||
# products.resources :comments
|
||||
# products.resources :sales, :collection => { :recent => :get }
|
||||
# resources :products do
|
||||
# resources :comments
|
||||
# resources :sales do
|
||||
# get :recent, :on => :collection
|
||||
# end
|
||||
# end
|
||||
|
||||
# Sample resource route within a namespace:
|
||||
# map.namespace :admin do |admin|
|
||||
# # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
|
||||
# admin.resources :products
|
||||
# namespace :admin do
|
||||
# # Directs /admin/products/* to Admin::ProductsController
|
||||
# # (app/controllers/admin/products_controller.rb)
|
||||
# resources :products
|
||||
# end
|
||||
|
||||
# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
|
||||
# map.root :controller => "welcome"
|
||||
# You can have the root of your site routed with "root"
|
||||
# just remember to delete public/index.html.
|
||||
# root :to => "welcome"
|
||||
|
||||
# See how all your routes lay out with "rake routes"
|
||||
|
||||
# Install the default routes as the lowest priority.
|
||||
# Note: These default routes make all actions in every controller accessible via GET requests. You should
|
||||
# consider removing or commenting them out if you're using named routes and resources.
|
||||
map.connect ':controller/:action/:id'
|
||||
map.connect ':controller/:action/:id.:format'
|
||||
# Install the default route as the lowest priority.
|
||||
# Note: The default route make all actions in every controller accessible
|
||||
# via GET requests. You should consider removing or commenting it out if
|
||||
# you're using named routes and resources.
|
||||
match ':controller(/:action(/:id(.:format)))'
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ module Rails
|
|||
class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
|
||||
|
||||
def add_resource_route
|
||||
route "map.resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
|
||||
route "resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -17,7 +17,7 @@ Description:
|
|||
For example, 'scaffold post title:string body:text published:boolean'
|
||||
gives you a model with those three attributes, a controller that handles
|
||||
the create/show/update/destroy, forms to create and edit your posts, and
|
||||
an index that lists them all, as well as a map.resources :posts
|
||||
an index that lists them all, as well as a resources :posts
|
||||
declaration in config/routes.rb.
|
||||
|
||||
If you want to remove all the generated files, run
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
ActionController::Routing::Routes.draw do |map|
|
||||
map.connect '/engine', :controller => "engine"
|
||||
match '/engine', :to => "engine"
|
||||
end
|
||||
|
|
|
@ -171,7 +171,7 @@ class ActionsTest < GeneratorsTestCase
|
|||
|
||||
def test_route_should_add_data_to_the_routes_block_in_config_routes
|
||||
run_generator
|
||||
route_command = "map.route '/login', :controller => 'sessions', :action => 'new'"
|
||||
route_command = "route '/login', :controller => 'sessions', :action => 'new'"
|
||||
action :route, route_command
|
||||
assert_file 'config/routes.rb', /#{Regexp.escape(route_command)}/
|
||||
end
|
||||
|
|
|
@ -62,7 +62,7 @@ class ResourceGeneratorTest < GeneratorsTestCase
|
|||
run_generator
|
||||
|
||||
assert_file "config/routes.rb" do |route|
|
||||
assert_match /map\.resources :accounts$/, route
|
||||
assert_match /resources :accounts$/, route
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,7 +70,7 @@ class ResourceGeneratorTest < GeneratorsTestCase
|
|||
run_generator ["account", "--singleton"]
|
||||
|
||||
assert_file "config/routes.rb" do |route|
|
||||
assert_match /map\.resource :account$/, route
|
||||
assert_match /resource :account$/, route
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -93,7 +93,7 @@ class ResourceGeneratorTest < GeneratorsTestCase
|
|||
run_generator ["account"], :behavior => :revoke
|
||||
|
||||
assert_file "config/routes.rb" do |route|
|
||||
assert_no_match /map\.resources :accounts$/, route
|
||||
assert_no_match /resources :accounts$/, route
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ class ScaffoldGeneratorTest < GeneratorsTestCase
|
|||
|
||||
# Route
|
||||
assert_file "config/routes.rb" do |route|
|
||||
assert_match /map\.resources :product_lines$/, route
|
||||
assert_match /resources :product_lines$/, route
|
||||
end
|
||||
|
||||
# Controller
|
||||
|
@ -99,7 +99,7 @@ class ScaffoldGeneratorTest < GeneratorsTestCase
|
|||
|
||||
# Route
|
||||
assert_file "config/routes.rb" do |route|
|
||||
assert_no_match /map\.resources :product_lines$/, route
|
||||
assert_no_match /resources :product_lines$/, route
|
||||
end
|
||||
|
||||
# Controller
|
||||
|
|
|
@ -16,7 +16,7 @@ class InfoControllerTest < ActionController::TestCase
|
|||
|
||||
def setup
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.connect ':controller/:action/:id'
|
||||
match ':controller/:action'
|
||||
end
|
||||
@controller.stubs(:consider_all_requests_local => false, :local_request? => true)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue