开发者

Rails 3 is "_method=PUT" still supposed to work?

I'm using FLEX 3 to make XML request to Rails 3. Since FLEX 3 only offers POST and GET, I have to use the "?_method=PUT" hack to maintain proper RESTfulness:

http://127.0.0.1:3000/locator/locator_users/1.xml?_method=PUT

On the server side its showing up as a POST and I'm getting an ActionController::RoutingError (No Route Matches).

I did a rake routes and the route is there, properly namespaced and all. This worked fine with Rails 2, so I have reason to believe it must be Rails 3 that changed. After doing some searching, people seemed to have indicated that it should still work. But, it's not for me. Can anyone confirm or deny Rails 3 compatibility?

UPDATE

OK, a开发者_StackOverflow社区fter some more tinkering, I think this is actually a problem of Flash Player 10. Flash PLayer 9 seems to work fine with "_method=" hack, 10 does not. See this new post I wrote (Flash Player 9 vs Flash Player 10 with FLEX 3, ?_method=PUT/DELETE not working?).


Partly this is due to Rack::MethodOverride's behavior. It does not check the query params for _method, so a call to http://127.0.0.1:3000/locator/locator_users/1.xml?_method=PUT will not get overridden properly due to that.

I wrote a piece of Rack middleware that replaces it to fix this particular issue.

All you have to do is add it to the Gemfile

gem 'rack-methodoverride-with-params'

swap Rack::MethodOverride out in config/environment.rb

config.middleware.swap Rack::MethodOverride, Rack::MethodOverrideWithParams


If you can add _method=PUT in your request body, then no need to swap out the rack middleware.

If you cannot do that, then I've come across another (lower-impact) solution, which is to simply define a custom route that accomplishes what you're looking for, for example:

# config/routes.rb
post '/locator/locator_users/:id', to: 'locator_users#update', constraints: {_method: 'POST'} # allow http method override

Granted, you would have to add this route for every resource you need HTTP method override on, but that might be a good thing if you want to limit your exposure to potential weirdness since this breaks HTTP semantics.

EDIT: You can do the same thing with GET requests if you need to, just swap out post for get (this can be useful if you need to support REST over JSONP).


You might have to rewrite how you're making your request to the server. I'm using Rails 3, Flex 4, and Flash 10 together (but with an app developed in Flex 3) and use _method as a parameter in my HTTPService object (leaving the content-type as the default application/x-www-form-url).

HTTPService only supports GET and POST requests. If you use set useProxy property to true on the HTTPService object, you can use HEAD, OPTIONS, TRACE, and DELETE but only if you are also using a server-based proxy service. If this doesn't work, then you may want to try URLLoader or URLRequest or implementing your own custom solution instead.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜