This project is archived and is in readonly mode.
respond_with returns " " on PUT and DELETE verb
-
José Valim
- State changed from new to invalid
- Importance changed from to Low
Respond with does not save your resource. You need to call .save or update_attributes before calling respond_with accordingly.
-
Nikolay Belous
This is just an example.
Real code belowdef create @user = User.new(params[:user]) if can? :create, @user @user.save respond_with(@user) else raise SWC::Exceptions.new(I18n.t('user.errors.insufficientAccountPermissions')) end end def show @user = User.find(params[:id]) if can? :read, @user respond_with(@user) else raise SWC::Exceptions.new(I18n.t('user.errors.insufficientAccountPermissions')) end end def update @user = User.find(:id => params[:id]) if can? :update, @user @user.update_attributes(params[:user]) respond_with(@user) else raise SWC::Exceptions.new(I18n.t('user.errors.insufficientAccountPermissions')) end end def destroy @user = User.find(params[:id]) if can? :destroy, @user @user.destroy respond_with(I18n.t('user.successful.accountDestroyed')) else raise SWC::Exceptions.new(I18n.t('user.errors.insufficientAccountPermissions')) end endIf I try to remove non-existent user I get " " rather than the error in JSON format
-
Jamie Hill
Sorry to resurrect this ticket but what is the solution here? As far as I can see both update and destroy should return something for say a json response as otherwise the client will error, not being able to pass an empty string as json.
-
Jamie Hill
Sorry, should have said that to get around this I am currently using this for the json response:
render :text => '{}', :status => :okThis is the only way to get Rails to play nice with libraries such as http://github.com/benpickles/js-model
-
Brandon Keepers
I ran into this issue today too. As is, respond_with is not helpful for any API that expects JSON to be returned.
This ticket should be reopened.
-
José Valim
- Milestone set to 3.x
- State changed from invalid to incomplete
I cannot see what is the issue. Can someone post a better example? Maybe a failing patch to Rails test suite?
-
Rohit Arondekar
Can you try writing a test for this? I think you should try writing it in actionpack/test/controller/mime_responds_test.rb
-
José Valim
- State changed from incomplete to needs-more-info
-
jduff
The issue with this is if you are using a strict JSON parser on the client side it will try to parse " " and fail. This really depends on the client you are using. For example if I make an ajax put request with jQuery to an action that users respond_with it will always fail because it cannot parse the returned " "
$.ajax({ url: 'http://localhost:3000/users/1.json', dataType: 'json', type: 'PUT', data: { user: { name: "something new" } }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('error'); }, complete: function() {alert('complete');} });The error callback will always get thrown because it fails to parse the response of " ".
Personally I think Rails is behaving correctly; if it is a successful update there is no reason to return the object again since you already have it, head ok should be good enough.
The solution I have for this is on the jQuery side, I've added this line to my application.js and everything works perfectly:
jQuery.ajaxSetup({ dataFilter: function(data, type){ return (!data || jQuery.trim(data)=="") ? "{}" : data; } }); -
fj
Here's a minimal test case.
## Rails 3 doesn't seem to handle PUT methods correctly. ## routing FruitApplication::Application.routes.draw do resources :fruits do member do put :peel # A HTTP PUT method that will map to fruits/:id/peel end end end ## controller class FruitsController < ApplicationController respond_to :json def peel respond_with :status => :not_found # This appears to be ignored and 200 is returned. end end ## spec describe FruitController do subject { @controller } before(:each) { put :peel, :id => 1234 } it { should respond_with :not_found } end # Failure/Error: it { should respond_with :not_found } # Expected response to be a 404, but was 200 # # ./spec/controllers/fruit_controller_spec.rb:3 # # /home/johnf/.rvm/gems/ruby-1.8.7-p299@project-getaroom/gems/activesupport-3.0.0/lib/active_support/dependencies.rb:239:in `inject' -
José Valim
Please add a test case to Rails suite?
-
Szymon Nowak
I've ran into this issue recently as well.
The problem is with the Responder#api_behavior method:
def api_behavior(error) raise error unless resourceful? if get? display resource elsif has_errors? display resource.errors, :status => :unprocessable_entity elsif post? display resource, :status => :created, :location => api_location else head :ok end endIn this case for PUT and DELETE verbs it does "head :ok" that, because of some strange error in some old version of Safari, actually returns a single space instead of empty body (http://dev.rubyonrails.org/changeset/1818).
For PUT verb it could simply return an updated resource in specified format - just like for POST, but with different status. However, I'm not sure if it's necessary.
For DELETE verb I guess it should return a valid, empty document - whatever this means for specified format. For JSON, "" and " " strings are not considered valid by native JSON parser in WebKit. However, "{}" is valid. Maybe we could introduce a default "empty _ #{format} _ resource" methods for JSON (not sure about XML) that would return a valid document as a string. The Responder#api_behavior method would simply check if responder responds to this method and render an empty resource using "render :text", otherwise it would fallback to "head :ok". This would allow users to add new methods to Responder class for whatever formats they use.
-
José Valim
- State changed from needs-more-info to open
Can someone please check if this is still a bug in Safari? If not, removing the Safari hax is the best way to handle this issue.
-
Szymon Nowak
I'm not sure if this will actually solve this problem for JSON format, because empty string is still considered as invalid JSON - that's why most people use what Jamie mentioned before:
render :text => '{}', :status => :ok -
José Valim
Checking if the status is json and explicitly returning "{}" in such cases is ok. Patch with tests please?
-
Szymon Nowak
Here's a patch that changes the behavior to return "{}" instead of " " for JSON requests with PUT and DELETE.
It also allows to add new methods to return a valid resource in any format. Currently only empty_json_resource method is defined, but if for someone " " is not a valid XML, one can easily fix it by defining AC::Responder#empty_xml_resource method and return <?xml version="1.0" encoding="UTF-8" ?>* or something similar instead.
The patch is at http://gist.github.com/620923, because I couldn't upload it here.
-
Repository
- State changed from open to resolved
(from [0d3333257156544feba729ba28f6874d5a30d561]) Return a valid empty JSON on successful PUT and DELETE requests. [#5199 respond_with returns " " on PUT and DELETE verb state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/0d3333257156544feba729ba28f687... -
Repository
(from [1556e0874dd5c7e160a9bc5091dd60eb4bd5ec97]) Return a valid empty JSON on successful PUT and DELETE requests. [#5199 respond_with returns " " on PUT and DELETE verb state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/1556e0874dd5c7e160a9bc5091dd60...