I'm trying to write test for my costume routes, along with non existing routes.
For the examples down here I have two problems:
It matches the actions that don't exist on my controller, so it doesn't really match to see if my controller have those actions, it just matches the syntax
the should_not be_routable doesn't work, which kind of goes back to the above problem of it doesn't check against my controller or the routes.rb file to see if the route should exist.
This one passes and is all good:
it "should route to method1" do
{ :get => '/my_controller/method1' }.should route_to(:controller => 'my_controller',
:action => 'method1')
end
this one fails, so it doesn't even check to see if I have a method zz defined in my controller or routes file.
it "should not route to zz" do
{ :get => '/my_controller/zz' }.should_not be_routable
end
the error I get is:
MyController routing zz should route to rescan
Failure/Error: { :get => '/my_controller/zz' }.should_not be_routable
expected {:get=>"/client_rescan/zz"} not to be routable, but it routes to {:controller=>"my_controller", :action=>"zz"}
So it obviously doesn't look at my routes file at all...
This is another example of it doesn't look at my routes file, in my routes I have ' resources :client_rescan, :only => [:index] ' and when I do rake routes it doesn't show delete as expected, but the test doesn't look at those:
it "should not have route to delete" do
{ :delete => '/my_controller/1'}.should_not be_routable
end
The Failure I get is the following. Which looks like it doesn't even see the delete function:
Failure/Error: { :delete => '/my_controller/1'}.should_not be_routable
expected {:delete=>"/my_controller/1"} not to be routable, but it routes to {:controller=>"my_controller", :action=>"1"}
Another problem is my post routes to index in the test:
it "should not have route to post" do
{ :post => '/my_controller' }.should_not be_routable
end
The Failure I get is:
Failure/Error: { :post => '/my_controller' }.should_not be_routable
expected {:post=>"/my_controller"} not to be routable, but it routes to {:controller=>"my_controller", :action=>"index"}
this is content of my routes.rb file
require 'resque/server'
require 'resque_scheduler'
Cdc::Application.routes.draw do
mount Resque::Server.new, :at => 'resque'
Resque.schedule = YAML.load_file(File.join(File.dirname(__FILE__), 'resque_schedule.yml')) # load the schedule
devise_for :users, :controllers => { :sessions => "sessions", :registrations => "registrations" }
[:assessments, :security_assessments, :privacy_assessments].each do |assessment_type|
resources assessment_type, :controller => :assessments do
resources :rsz do
post 'review', :on => :member
get 'judgement', :on => :member
end
get :judgement, :on => :member
resources :samples do
get 'download', :on => :member
end
resources :asm_reviews do
post :request_review, :on => :collection
end
end
end
resources :account_creator
match "/images/captcha/*file_name" => "captcha#show"
## this is where my route is!! :)
resources :my_controller, :only => [:index] do
collection do
get :rescan
get :cancel
end
end
match "alert_queue/words" => "alert_queue#words"
resources :alert_queue
match "calls_to_action/start/:id" => "calls_to_action#start", :id => /\d+/
match "calls_to_action/close/:id" => "calls_to_action#close", :id => /\d+/
match "calls_to_action/comment/:id" => "calls_to_action#comment", :id => /\d+/
match "calls_to_action/multiclose" => "calls_to_action#multiclose"
match "calls_to_action/multiscan" => "calls_to_action#multiscan"
match "application_instances/multiclose" => "application_instances#multiclose"
match "application_instances/multiscan" => "application_instances#multiscan"
resources :code_categories do
resources :code_families do
resources :code_family_versions
end
end
resources :code_policy_items
resources :application_instances do
collection do
post :resque_statuses
end
resources :code_indices
resources :application_analysis
get "smali/:smali_path", :as => :smali, :on => :member, :action => :smali, :smali_path => /.*/
member do
get :file
get :strings
get :dump
get :alerts
get :correlations
get :signers
get :icon
get :resque_status
get :assets
get :new_code_index
get :class_list
get :heuristic_hits
get :engine_artifacts
post :rescan
post :attach_artifact
post :engine_artifact, :action => :attach_engine_artifact
resources :alerts
end
post "multiscan", :on => :collection, :action => :multiscan
post "multiclose", :on => :collection, :action=> :multiclose
post "engines/:engine_name/:engine_version/assertions/:cookie",
:on => :member, :action => :register_assertion_set, :as => :register_assertion_set,
:engine_name => /[^\/]+/, :engine_version => /[^\/]+/, :cookie => /[^\/]+/
post "engines/:engine_name/:engine_version/network_data",
:on => :member, :action => :register_network_data, :as => :register_network_data,
:engine_name => /[^\/]+/, :engine_version => /[^\/]+/
post "assets", :on => :member, :action => :register_asset_set, :as => :register_asset_set
end
# index gets the list of families, show gets the assertion types for that family
resources :assertion_families
resources :artifacts
resources :dashboard do
collection do
get :last_app_instance
end
end
match '/direct_downloads/' => 'direct_downloads#index'
root :to => "stats#index"
match '/' => 'stats#index'
match 'explorer/query/:format' => 'explorer#query'
match '/:controller(/:action(/:id))'
end
The problem is this line of routes.rb:
match '/:controller(/:action(/:id))'
This is a catch all route, and will match for example /abc/xyz to controller abc, and action xyz.
It's best really not to use catch all routes, in favour of exposing only the functionality you want.
Related
I am trying to call an action from a controller 2 steps up the folder structure namespace
<%= link_to( "Reset Search" ,
{:controller => "../../application",
:action => 'reset_search',
:reset_search_redirect => reset_search_redirect},
class: 'tiny button') %>
The "../../application"works! however; i dont think it's rails-y. Is there a better way?
Here is the href link when I just put :controller => "application"
/human_resources/settings/application/reset_search?reset_search_redirect=%2Fhuman_resources%2Fsettings
Which does not work.
Here are my routes:
get 'human_resources/' => 'human_resources#index'
namespace :human_resources do
get 'settings/' => 'settings#index'
namespace :settings do
get 'constants/' => 'constants#index'
resources :constants
end
end
resources :test, only: :index
root to: 'home#index'
match ':controller(/:action(/:id))', :via => [:get, :post]
I update apllication from rails 2 to rails 3.
And I rewrite routes with resources. How to write route to this actions:
def delete_attachment
#object = Article.find(params[:id])
attachment = Attachment.find(params['attachment_id'])
attachment.attachment = nil
attachment.destroy
redirect_to :action => 'edit', :id => #object.id
end
def edit_attachment
#object = Article.find(params[:id])
attachment = Attachment.find(params['attachment_id'])
attachment.title = params['attachment_title']
attachment.description = params['attachment_description']
attachment.save
redirect_to :action => 'edit', :id => #object.id
end
def add_attachment
#object = Article.find(params[:id])
attachment = Attachment.new
attachment.attachment = params['attachment_file']
attachment.title = params['attachment_title']
attachment.description = params['attachment_description']
attachment.article_id = #object.id
attachment.save
params['attachment_title'] = nil
params['attachment_description'] = nil
redirect_to :action => 'edit', :id => #object.id
end
This is right solution?
resources :articles do
delete '/articles/delete_attachment', :to => 'articles#delete_attachment'
put '/articles/edit_attachment', :to => 'articles#edit_attachment'
post '/articles/add_attachment', :to => 'articles#add_attachment'
end
I have no way to check it on the server, because there are still many incompatibilities.
You can change the routes to:
resources :articles do
member do
delete 'delete_attachment'
put 'edit_attachment'
post 'add_attachment'
end
end
If you don't have multiple member routes, you can also pass :on to a route, eliminating the block:
Like,
resources :photos do
get 'preview', on: :member
end
I want to configure my Rails routing such that these cases work:
/username #=> { :controller => "houses",
# :action => "index",
# :user_id => "username" }
/username/housename #=> { :controller => "houses",
# :action => "show",
# :user_id => "username",
# :id => "housename" }
/username/edit #=> { :controller => "users",
# :action => "edit",
# :id => "username" }
In other words, I want /:user_id to be a regular user resource, and have a nested resource for it, which is mounted directly on the root. So, I want /username/housename instead of /username/houses/housename. I tried using :path => "/" for the nested resources, but this somehow clashes with other actions such as `:edit. I'm lost - can this be done?
What you are trying to do will create conflicts, which is why Rails is not letting you do it.
Consider the situation where some user bob has a house named "edit". In this case, where is Rails supposed to route '/bob/edit' to? There are two possibilities:
{ :controller => "houses", :action => "show", :user_id => "bob", :id => "edit" }
and:
{ :controller => "users", :action => "edit", :id => "bob" }
So to answer your question, as is what you are trying to do cannot be done until you remove the ambiguity.
UPDATE:
Borrowing from #sevenseacat's answer, I think this should do what you want, in the case of a route /bob/edit prioritizing the edit action for user "bob" over the show action for a house named "edit":
resources :users, path: '/', only: :edit
resources :users, path: '/', only: :show do
resources :houses, only: :show, path: ''
end
I get these routes:
edit_user GET /:id/edit(.:format) users#edit
user_house GET /:user_id/:id(.:format) houses#show
user GET /:id(.:format) users#show
Notice that the edit_user path appears above the user_house path, which guarantees that it will get priority when there is a conflict.
Something like this may be what you're after:
resources :users, path: '/', only: [:show, :edit] do
resources :houses, only: [:show], path: ''
end
rake routes tells me:
user_house GET /:user_id/:id(.:format) houses#show
edit_user GET /:id/edit(.:format) users#edit
GET /:id(.:format) users#show
I'm trying to route the following URL:
/shop/{category_id}/{product_id}/
to a controller action called 'product'
I've got this in my routes:
match "/shop/:category/:id" => "shop#product"
and i've got link_to's as follows:
link_to_unless_current "#{t('murals')}", url_for(:controller => 'shop', :category => 'walls', :id => 'murals')
When the urls are output, they are:
http://0.0.0.0:3000/shop?category=walls&id=murals
instead of the desired:
http://0.0.0.0:3000/shop/walls/murals
if i switch the route, so it goes to:
match "/shop/:category/:id" => "shop#index"
this works, but it's not the right action.
Any help would be appreciated.
try this
<%= link_to_unless_current "#{t('murals')}", custom_path(:category => 'walls', :id => 'murals') %>
match "/shop/:category/:id" => "shop#product", :as => :custom
I have implemented devise and set up the routes to prettyify the urls as so (in the routes file):
devise_scope :user do
get "/login" => "devise/sessions#new"
get "/logout" => "devise/sessions#destroy"
get "/register" => "devise/registrations#new"
end
I have global menu in my application.html.erb file, however, which now inserts devise/controller/action on every link that is on the login or register pages, such as
<%= link_to "Upload Video", {:controller => "videos", :action => "new"} %>
becomes devise/videos/new
Any ideas on how to fix this? I can hack around it but I'm pretty sure it is a simple fix.
Cheers,
s
Take out the devise_scope and try something like this:
devise_for :users,
:controllers => {:registrations => 'devise/registrations', :sessions => 'devise/sessions'},
:path => '/',
:path_names => {:sign_in => 'login', :sign_out => 'logout'}