La ruta miembro "POST" de Rails responde a todos los tipos de solicitudes

I'm trying to set up a member route for my 'foo' controller, which is named 'bar' such that it should ONLY respond to post requests. However, I notice that in my RSpec tests it responds to ALL request types (GET, POST, PUT, DELETE).

I was under the impression that defining the route as so, would restrict it such that it would only respond to POST requests:

resources :foo do
  member do
    post 'bar'

This seems further confirmed by the fact that when I run rake routes it ONLY shows the 'bar' route like so:

bar_foo    POST    /foo/:id/bar(.:format)    {:action=>"bar", :controller=>"foo"}

However, from RSPEC, the following test fails (meaning the controller processes request successfully) for GET, PUT, & DELETE:

describe FooController do
    describe "GET bar" do
        it "should not be successful" do
            foo = FactoryGirl.create(:foo)
            get :bar, :id =>
            response.should_not be_ok

Am I missing something small here? How do I restrict my 'bar' member route to only respond to "post" requests.


This appears to be an issue with either RSpec 2.0 or ActionController :: TestCase, because I get the following error when I try to hit /foo/:id/bar on my sever with anything but POST:

Routing Error

No route matches [GET] "/foo/1/bar"

preguntado el 01 de febrero de 12 a las 22:02

"puts response.inspect" and check the output. -

the response is a 200, which is what the 'bar' action returns on success from the FooController -

just to validate your sanity, I've written similar tests relying on routes to reject non-POST etc, and have had it work. It's the right strategy, must be some "mundane detail" -

Thanks, it's always good to know you're not crazy :) -

Does your test log indicate what path is actually being accessed on the get :bar call? Does it list `Started GET "/foo/:id/bar" or something different? Also, do you have a "catch-all" route at the bottom of your routes.rb? -

1 Respuestas

From my own experience it appears that RSpec controller tests will no attempt to enforce routing behavior as long as the route exists. RSpec does provide route testing, específicamente el be_routable matcher.

Dado lo siguiente route.rb retazo:

post :foo, to: 'foo#create'


it "won't work as expected" do
  get :foo
  expect(response).to be_ok #=> pass

  post :foo
  expect(response).to be_ok #=> pass

will pass. Only when the route is missing entirely from route.rb will it fail.

The following will pass and can be used to perform the test we're interested in:

it "responds to only the proper HTTP verbs" do
  expect(get: :foo).not_to be_routable #=> pass - Cannot GET 🙅‍♂️
  expect(post: :foo).to be_routable    #=> pass - POST works 🎉

Respondido el 04 de Septiembre de 20 a las 16:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.