Skip to content

Commit

Permalink
Add support for actions on a new resource to the new routing DSL [#4328
Browse files Browse the repository at this point in the history
… state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information
pixeltrix authored and josevalim committed Jun 8, 2010
1 parent 67f411c commit 4740fba
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 29 deletions.
97 changes: 70 additions & 27 deletions actionpack/lib/action_dispatch/routing/mapper.rb
Expand Up @@ -476,6 +476,10 @@ def singular
name.to_s.singularize
end

def member_prefix
':id'
end

def member_name
singular
end
Expand Down Expand Up @@ -522,6 +526,10 @@ def collection_options
end
end

def nested_prefix
id_segment
end

def nested_options
options = { :name_prefix => member_name }
options["#{singular}_id".to_sym] = id_constraint if id_constraint?
Expand Down Expand Up @@ -549,9 +557,21 @@ def action_type(action)
end
end

def member_prefix
''
end

def member_name
name
end

def nested_prefix
''
end

def nested_options
{ :name_prefix => member_name }
end
end

def initialize(*args) #:nodoc:
Expand All @@ -571,17 +591,17 @@ def resource(*resources, &block)
scope(:path => resource.path, :controller => resource.controller) do
with_scope_level(:resource, resource) do

scope(:name_prefix => resource.name.to_s, :as => "") do
yield if block_given?
end
yield if block_given?

scope(resource.options) do
get :show if resource.actions.include?(:show)
post :create if resource.actions.include?(:create)
put :update if resource.actions.include?(:update)
delete :destroy if resource.actions.include?(:destroy)
get :new, :as => resource.name if resource.actions.include?(:new)
get :edit, :as => resource.name if resource.actions.include?(:edit)
with_scope_level(:member) do
scope(resource.options) do
get :show if resource.actions.include?(:show)
post :create if resource.actions.include?(:create)
put :update if resource.actions.include?(:update)
delete :destroy if resource.actions.include?(:destroy)
get :new, :as => resource.name if resource.actions.include?(:new)
get :edit, :as => resource.name if resource.actions.include?(:edit)
end
end
end
end
Expand Down Expand Up @@ -645,31 +665,36 @@ def collection
end

def member
unless [:resources, :resource].include?(@scope[:scope_level])
raise ArgumentError, "You can't use member action outside resources and resource scope."
unless resource_scope?
raise ArgumentError, "can't use member outside resource(s) scope"
end

case @scope[:scope_level]
when :resources
with_scope_level(:member) do
scope(':id', :name_prefix => parent_resource.member_name, :as => "") do
yield
end
with_scope_level(:member) do
scope(parent_resource.member_prefix, :name_prefix => parent_resource.member_name, :as => "") do
yield
end
when :resource
with_scope_level(:member) do
end
end

def new
unless resource_scope?
raise ArgumentError, "can't use new outside resource(s) scope"
end

with_scope_level(:new) do
scope(new_scope_prefix, :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"
unless resource_scope?
raise ArgumentError, "can't use nested outside resource(s) scope"
end

with_scope_level(:nested) do
scope(parent_resource.id_segment, parent_resource.nested_options) do
scope(parent_resource.nested_prefix, parent_resource.nested_options) do
yield
end
end
Expand Down Expand Up @@ -701,7 +726,7 @@ def match(*args)
@scope[:path] = old_path
end
else
with_exclusive_name_prefix(action) do
with_exclusive_name_prefix(action_name_prefix(action, options)) do
return match("#{action_path(action, path_names)}(.:format)", options.reverse_merge(:to => action))
end
end
Expand All @@ -714,10 +739,16 @@ def match(*args)
return collection { match(*args) }
when :member
return member { match(*args) }
when :new
return new { match(*args) }
end

if @scope[:scope_level] == :resources
raise ArgumentError, "can't define route directly in resources scope"
if @scope[:scope_level] == :resource
return member { match(*args) }
end

if resource_scope?
raise ArgumentError, "can't define route directly in resource(s) scope"
end

super
Expand All @@ -739,6 +770,10 @@ def action_path(name, path_names = nil)
path_names[name.to_sym] || name.to_s
end

def action_name_prefix(action, options = {})
(options[:on] == :new || @scope[:scope_level] == :new) ? "#{action}_new" : action
end

def apply_common_behavior_for(method, resources, options, &block)
if resources.length > 1
resources.each { |r| send(method, r, options, &block) }
Expand All @@ -752,7 +787,7 @@ def apply_common_behavior_for(method, resources, options, &block)
return true
end

if @scope[:scope_level] == :resources
if resource_scope?
nested do
send(method, resources.pop, options, &block)
end
Expand All @@ -762,6 +797,14 @@ def apply_common_behavior_for(method, resources, options, &block)
false
end

def new_scope_prefix
@scope[:path_names][:new] || 'new'
end

def resource_scope?
[:resource, :resources].include?(@scope[:scope_level])
end

def with_exclusive_name_prefix(prefix)
begin
old_name_prefix = @scope[:name_prefix]
Expand Down
50 changes: 48 additions & 2 deletions actionpack/test/dispatch/routing_test.rb
Expand Up @@ -96,8 +96,17 @@ def self.matches?(request)
end

scope 'pt', :name_prefix => 'pt' do
resources :projects, :path_names => { :edit => 'editar' }, :path => 'projetos'
resource :admin, :path_names => { :new => 'novo' }, :path => 'administrador'
resources :projects, :path_names => { :edit => 'editar', :new => 'novo' }, :path => 'projetos' do
post :preview, :on => :new
end
resource :admin, :path_names => { :new => 'novo' }, :path => 'administrador' do
post :preview, :on => :new
end
resources :products, :path_names => { :new => 'novo' } do
new do
post :preview
end
end
end

resources :projects, :controller => :project do
Expand Down Expand Up @@ -146,6 +155,10 @@ def self.matches?(request)
end

resources :replies do
new do
post :preview
end

member do
put :answer, :to => :mark_as_answer
delete :answer, :to => :unmark_as_answer
Expand Down Expand Up @@ -234,6 +247,14 @@ def self.matches?(request)
end

match "whatever/:controller(/:action(/:id))"

resource :profile do
get :settings

new do
post :preview
end
end
end
end

Expand Down Expand Up @@ -1077,6 +1098,31 @@ def test_assert_recognizes_account_overview
end
end

def test_resource_new_actions
with_test_routes do
assert_equal '/replies/new/preview', preview_new_reply_path
assert_equal '/pt/projetos/novo/preview', preview_new_pt_project_path
assert_equal '/pt/administrador/novo/preview', preview_new_pt_admin_path
assert_equal '/pt/products/novo/preview', preview_new_pt_product_path
assert_equal '/profile/new/preview', preview_new_profile_path

post '/replies/new/preview'
assert_equal 'replies#preview', @response.body

post '/pt/projetos/novo/preview'
assert_equal 'projects#preview', @response.body

post '/pt/administrador/novo/preview'
assert_equal 'admins#preview', @response.body

post '/pt/products/novo/preview'
assert_equal 'products#preview', @response.body

post '/profile/new/preview'
assert_equal 'profiles#preview', @response.body
end
end

private
def with_test_routes
yield
Expand Down

0 comments on commit 4740fba

Please sign in to comment.