I am having an problem routing to my delete method on my restful web service for permissions.
My routes are set up as follows :
namespace :service do
namespace :v1 do
resources :surveys do
resources :permissions, only: [:index, :create, :delete, :update]
end
end
end
The following spec passes
it "routes toya expected controller method" do
{:get => 'service/v1/surveys/3/permissions'}.should route_to(controller: 'service/v1/permissions', action: 'index', :survey_id => "3")
end
This spec fails
describe 'DELETE :destroy' do
it "routes to expected controller method" do
{:delete => 'service/v1/surveys/3/permissions'}.should route_to(controller: 'service/v1/permissions', action: 'destroy', :survey_id => "3")
end
end
The snippet from my controller is as follows
module Service
module V1
class PermissionsController < ApplicationController
before_filter :authenticate_user!, :only => []
def index
render :json => permissions, :each_serializer => Service::V1::PermissionSerializer
end
def destroy
debugger
# cant route to here
a = 1
end
end
end
end
Any suggestions ? I am slightly confused between destroy and delete, I think that might be the source of my problem
You need to pass permission id as well like:-
{:delete => 'service/v1/surveys/3/permissions/permission_id'}.should route_to(controller: 'service/v1/permissions', action: 'destroy', :survey_id => "3", :id => "permission_id")
Related
I need to test that a flash message comes up when a specific exception is raised. I am getting a no route matches error and have looked through the other topics with "Rspec Controller test, No Routes matches" and am still not sure what is wrong. This is my first time writing an rspec test. Commented out lines are various other attempts to get test to pass.
audit/businesses_controller.rb:
class Audit::BusinessesController < ApplicationController
# PUT /audit/businesses/:id
def update
remove_deleted_account_numbers_in(params)
#business = #jurisdiction.businesses.find(params[:id])
#business.changed_by = current_user
if #business.update_attributes(audit_business_params)
success_message('update')
else
#business.initialize_accounts
#business = #business
render :edit, alert: t('flash.save_failed')
end
rescue ActiveRecord::StatementInvalid => e
if e.message.include? "foreign key constraint"
#business = #jurisdiction.businesses.find(params[:id])
#business.initialize_accounts
#business = #business
render :edit, alert: "This account number is in use and cannot be deleted"
else
raise e
end
end
business_controller_spec.rb:
require "spec_helper"
describe Audit::BusinessesController do
describe "handling ActiveRecord::StatementInvalid" do
before {delete, url = 'audit/jurisdictions/:jurisdiction_id/businesses/:id(.:format)'}
it "should rescue with a flash message" do
# /audit/jurisdictions/:jurisdiction_id/businesses/:id(.:format)
# delete, businesses_id: '80776', jurisdiction_id: '795', format: 'html', id: "234769"
expect(page).to have_content("This account number is in use and cannot be deleted")
end
end
end
rake routes:
audit_businesses GET
/audit/jurisdictions/:jurisdiction_id/businesses(.:format)
audit/businesses#
POST /audit/jurisdictions/:jurisdiction_id/businesses(.:format)
audit/businesses#create
new_audit_business GET
/audit/jurisdictions/:jurisdiction_id/businesses/new(.:format)
audit/businesses#new
edit_audit_business GET
/audit/jurisdictions/:jurisdiction_id/businesses/:id/edit(.:format)
audit/businesses#edit
audit_business
GET /audit/jurisdictions/:jurisdiction_id/businesses/:id(.:format)
audit/businesses#show
PUT /audit/jurisdictions/:jurisdiction_id/businesses/:id(.:format) audit/businesses#update
DELETE /audit/jurisdictions/:jurisdiction_id/businesses/:id(.:format) audit/businesses#destroy
Error Message:
Failure/Error: before { delete audit_business_path(:jurisdiction_id, :id, :format) }
ActionController::RoutingError:
No route matches {:controller=>"audit/businesses", :action=>"/audit/jurisdictions/jurisdiction_id/businesses/id.format"}
# ./spec/controllers/businesses_controller_spec.rb:6:in `block (3 levels) in <top (required)>'
When I change the spec to:
describe Audit::BusinessesController do
describe "handling ActiveRecord::StatementInvalid" do
it "should rescue with a flash message" do
put :update, :jurisdiction_id => 1, :id => 1, :format => html
expect(controller).to set_flash[:alert].to(/This account number is in use and cannot be deleted/).now
The error is:
Failure/Error: put :update, :jurisdiction_id => 1, :id => 1, :format => html
NoMethodError:
undefined method `can_update?' for nil:NilClass
routes.rb:
namespace :audit do
root to: 'site#home'
resources :labels, only: ['index', 'destroy'] do
post 'delete_queue', on: :collection
get 'print', on: :collection
get 'print_view', on: :collection
get 'mark_printed', on: :collection
get 'users', on: :collection
end
resources :auditor_goals
resources :contracts
resource :contract_work, only: %w[show update], controller: 'contract_work'
resources :manpower
resource :county_budgets, only: :update do
get 'search'
end
get 'intro_letter_search' => 'files#intro_letter_search'
put 'intro_letter_update' => 'files#intro_letter_update'
get 'search' => 'files#search'
get 'calendar' => 'files#calendar'
get 'autocomplete' => 'files#autocomplete'
get 'direct' => 'files#direct'
get 'size_code_select' => 'businesses#size_code_select'
scope '/jurisdictions/:jurisdiction_id' do
resources :businesses, controller: 'businesses'
resources :files, controller: 'files' do
get 'print', on: :member
end
# get 'page/:page', action: :index, on: :collection
end
end
for rspec test instead write
expect(page).to have_content("flash message")
where "flash message" is the actual message of the error or exception you're trying to make pass. Eg for, flash[:notice] = "An error occurred", you would put have_content("An error occurred")
Hope that helps?!
Justin
#TzokinB - I believe "Capybara::ElementNotFound: Unable to find xpath "/html" typically means the test set is now looking for a view. Have you associated a view for to action in your controller?
So I keep getting the error:
No route matches {:action=>"create", :controller=>"xaaron/api_keys"}
Which is thrown in the test:
it "should not create an api key for those not logged in" do
post :create
expect(response).to redirect_to xaaron.login_path
end
when I go to spec/dummy and run the rake routes command I see:
api_keys GET /api_keys(.:format) xaaron/api_keys#index
POST /api_keys(.:format) xaaron/api_keys#create
new_api_key GET /api_keys/new(.:format) xaaron/api_keys#new
edit_api_key GET /api_keys/:id/edit(.:format) xaaron/api_keys#edit
api_key GET /api_keys/:id(.:format) xaaron/api_keys#show
PATCH /api_keys/:id(.:format) xaaron/api_keys#update
PUT /api_keys/:id(.:format) xaaron/api_keys#update
DELETE /api_keys/:id(.:format) xaaron/api_keys#destroy
Which shows that yes this route does exist. My routes file for this engine looks like:
Xaaron::Engine.routes.draw do
get 'login' => 'sessions#new', :as => 'login'
get 'logout' => 'sessions#destroy', :as => 'logout'
get 'signup' => 'users#new', :as => 'signup'
get 'permission_denied' => 'error#denied', :as => 'permission_denied'
get 'record_not_found' => 'error#error', :as => 'record_not_found'
get 'password_reset' => 'password_resets#edit', :as => 'rest_user_password'
resource :error, controller: 'error'
resources :users
resources :api_keys
resources :sessions
resources :roles
resources :password_resets
end
What am I missing?
update
For those of you curious how I am getting these routes, its because the dummy app's routes file is set up (by default) as such:
Rails.application.routes.draw do
mount Xaaron::Engine => "/xaaron"
end
Update II
I have been reading this api docs on how routing is done in engines and I believe the way I have done this is correct, how ever the controller is defined as such:
module Xaaron
class ApiKeysController < ActionController::Base
before_action :authenticate_user!
def index
#api_key = Xaaron::ApiKey.where(:user_id => current_user.id)
end
def create
#api_key = Xaaron::ApiKey.new(:user_id => current_user.id, :api_key => SecureRandom.hex(16))
create_api_key(#api_key)
end
def destroy
Xaaron::ApiKey.find(params[:id]).destroy
flash[:notice] = 'Api Key has been deleted.'
redirect_to xarron.api_keys_path
end
end
end
You need to tell your spec you are using the engine routes:
describe ApiKeysController do
routes { Xaaron::Engine.routes }
it "should not create an api key for those not logged in" do
post :create
expect(response).to redirect_to xaaron.login_path
end
end
I have a refinery extension that I created that manages Fieldtrips for a school.
My current fieldtrips_controller for the admin side has the following.
module Refinery
module Fieldtrips
module Admin
class FieldtripsController < ::Refinery::AdminController
crudify :'refinery/fieldtrips/fieldtrip', :xhr_paging => true
def destory_pin
#pin = Refinery::Pins::Pin.find(params[:id])
if #pin.delete
render :json => {result: "success"}
else
render :json => {result: "error"}
end
end
end
end
end
end
As you can see I added a method for destroying what I'm calling a pin, witch is a model that I have associated with fieldtrips.
I'm using an ajax request from my Fieldtrip edit page. the url I'd like to call would be "refinery/fieldtrips/destory_pin
currently in my routes file for fieldtrips I have the following
Refinery::Core::Engine.routes.append do
# Frontend routes
namespace :fieldtrips do
resources :fieldtrips, :path => '', :only => [:index, :show]
end
# Admin routes
namespace :fieldtrips, :path => '' do
namespace :admin, :path => 'refinery' do
resources :fieldtrips, :except => :show do
collection do
post :update_positions
post :destory_pin
end
end
end
end
end
Currently when I run rake routes I get the following
POST /refinery/fieldtrips/destory_pin(.:format) refinery/fieldtrips/admin/fieldtrips#destory_pin
If I nav to /refinery/fieldtrips/destory_pin in my browser I get a NoMethodError in Refinery::Admin::BaseController#error_404
I'm sure I'm doing the routes wrong and need suggestions on how to correct this.
Use member instead of collection, e.g.
namespace :fieldtrips, :path => '' do
namespace :admin, :path => 'refinery' do
resources :fieldtrips, :except => :show do
collection do
post :update_positions
end
member do
post :destory_pin
end
end
end
end
im having some trouble creating a route for my non restfull action in my controller, here is my code:
controller:
class StoresController < ApplicationController
def toggle_store
#store=Store.find(params[:store])
if #store.available==true
#store.update_attribute(:available, false)
else
#store.update_attribute(:available, true)
end
redirect_to #store
end
end
routes:
resources :groups do
resources :stores do
member do
post :toggle_store
end
end
end
but when i use the path in a link i get this url: http://example.com/groups/1/stores/toggle_store.2
and i need something like this:
http://example.com/groups/1/stores/2/toggle_store
any ideas?
Thanks
EDIT:
rake routes:
toggle_store_group_store POST /groups/:group_id/stores/:id/toggle_store(.:format) stores#toggle_store
Link:
<%=link_to "toggle", toggle_store_group_stores_path(#group,store), :method => :post %>
ok i fixed it like this:
routes.rb:
resources :groups do
resources :stores do
post :toggle_store
end
end
controller:
def toggle_store
authorize! :toggle, :store
#store=Store.find(params[:store_id])
if #store.available==true
#store.update_attribute(:available, false)
else
#store.update_attribute(:available, true)
end
redirect_to #group
end
link:
<%=link_to "to", toggle_store_group_store_path(#group,store), :method => :post %>
I was able to successfully override url_after_create, but my url_after_destroy is being ignored.
What am I messing up?
routes:
map.resource :session,
:controller => 'sessions',
:only => [:new, :create, :destroy]
my Sessions controller:
class SessionsController < Clearance::SessionsController
private
def url_after_create
puts "************after create****************" #called on sign in
end
def url_after_destroy
puts "************after destroy****************" #never called
end
end
The docs say:
You may also need to add code such as
the following to your routes.rb:
map.sign_out 'sign_out',
:controller => 'sessions',
:action => 'destroy',
:method => :delete
That's what I'm missing. Perhaps 'may' is not the best choice of verb for documentation.