How not to send any data to client? - ruby-on-rails

I use Ruby-on-Rails in my project and there is a functionality to delete the whole data from table in one click. And in that case, I don't want to send any data to client from server. To do that, I wrote this part of code:
render :json => {}
Is there a better way to solve this problem?

I would use
head :ok
which returns an empty response with the HTTP status code 200 (OK).
Docs about head.

Related

What does Ember Data expect in response to deleting a record?

I'm using Ember Data with the RESTful adapter with a rails backend.
When I delete a record from Ember record.deleteRecord(); record.save() the DELETE request goes to the server and the model is deleted, but this error is printed to the javascript console:
Extract requested, but no data given for App.ThisModel. This may cause weird problems.
The response from the server was just render json: true, so I changed it to render json: deleted_model which renders the json for the deleted record.
That got rid of the previous error, but now the deleted record is recreated in Ember.
What does Ember expect in the response?
You should send back a 200 with an empty valid json response {}, any data returned is applied to the record as if they were attributes.
http://emberjs.jsbin.com/OxIDiVU/215/edit
Additionally you can send back a 204 with no response.
http://emberjs.jsbin.com/OxIDiVU/214/edit
jQuery 1.9 no longer treats a response of 200 for a JSON request as a success. Your server should now be returning a 204 response for DELETE requests with empty response body.
For a rails server, you can do something like this:
    
def destroy
  #something.destroy!
  head :no_content
end
In ember 1.5.1 and ember-data 1.0.0-beta.9+canary.410d62d6, I tried to return a empty json object/array, like { }, like in the answer above. It didn't work.
It only worked with a 200 response code and null as response value.
So maybe that has changed, or it depends on other things as well... I can't say, but only tell you what worked for me.

HEAD HTTP requests in Rails 3

Rails 3 currently routes a HEAD request to the matching GET route. There is a head? method on the request, but in returns false and the request acts like a get request. Can I detect if the request is a HEAD request?
Reasoning: I get that a HEAD request should return the EXACT same headers as the get, so Rails wants to perform the full GET and then shave off the body. However, I can conform to this request without issuing the same DB calls, etc that the GET would. Does this make sense?
I had this exact issue. It turns out that enabling caching causes this. Turn caching off in your environment and #head? will work as expected.
The issue is that Rack::Cache turns HEAD requests into GET requests so they can be cached. This is arguably the correct behavior, but it interfered with my application.
You can use the request.head? method to find out if it's a HEAD request:
http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-head-3F
Once you've determined that it is, you can also use the controller's head() method instead of the typical render:
http://guides.rubyonrails.org/layouts_and_rendering.html#using-head-to-build-header-only-responses
So I'd simply check request.head? before bothering with the database activities. Then use
head :ok, :custom_header => 'value'
def index
if request.head?
head :created
else
Rails.logger.info "Derp #{request.method}"
end
end
Hmm. The above controller method works like I'd expect on Ruby v1.9.3-p194 and Rails v3.2.3; 201's w/o response body for the HEAD requests and 200's w/ for the GET's.

Rails 3: HTTP 406 and blank page on trying to view json in browser

I am a little new with Rails and ajax, and I'm encountering the following frustration whilst trying to debug some fairly simple ajax requests in my controllers.
I have the following code:
respond_to do |format|
#format.html { render :json => db_clean_response.to_json }
format.json { render :json => db_clean_response.to_json }
end
When I try to debug this by manually entering the URL and parameters, the controller correctly prepares the response, but Rails responds with HTTP/406 Not Acceptable unless I uncomment the format.html command. (Note that the format.html stuff is just for trying to fix this.)
I don't want this function responding with html, as its only for ajax stuff. Besides, Rails responds with the json uglyprinted onto empty html, and I'd like to use a plugin like JSONView to prettify it.
What's going on here? I feel like the desired result is very simple, but something, somewhere is messing it up. When I try to debug ajax I want my browser to pull up the damn json without being lame :-(
It turns out that adding format=json to the URL parameters does what I want: forces Rails to return json with all the right headers

Rails Best Practices for RESTful controller CREATE and UPDATE methods

OK, I am trying to understand the best practices for the CREATE and UPDATE methods for both HTML and XML formats. The default code for a controller that the rails generator generates is a little unclear to me.
For the CREATE method, given a good save, the generator says to "redirect_to(#whatever)" for HTML and "render :xml => #whatever, :status => :created, :location => #whatever" for XML.
Given a bad save, the generator says to "render :action => 'new'" for HTML and "render :xml => #whatever.errors, :status => :unprocessable_entity" for XML.
However, for the UPDATE method, given a good update, the generator says to "redirect_to(#whatever)" for HTML and "head :ok" for XML.
And, given a bad update, the generator says to "render :action => 'edit'" for HTML and "render :xml => #whatever.errors, :status => :unprocessable_entity" for XML.
I understand this, and it makes sense to me, and works just fine - BUT, I have two questions:
First, for a successful CREATE and UPDATE, HTML format, why "redirect_to(#whatever)" instead of "render :action => 'show'"? I understand the differences between redirect and render, just more curious about which way you guys tend to do it and why. It seems the redirect would be an unnecessary extra trip for the browser to make.
Second, why "head :ok" upon successful UPDATE via XML, but "render :xml => #whatever, :status => :created, :location => #whatever" upon successful CREATE via XML? This seems inconsistent to me. Seems like a successful UPDATE via XML should be the same as a successful CREATE via XML. Seems like you would need the new/updated object returned so you could test it. How do you guys do it and why?
I'd already written this out when Sam C replied, but here it is anyway :-)
For the first part - why redirect instead of render? Two reasons I can think of:
1) It's consistent. If you rendered the show action and the user uses the back button later on return to that page, the user will see unexpected behaviour. Some versions of IE will give you some kind of session timeout error IIRC, other browsers may handle it a bit more gracefully.
Same goes for if the user bookmarked that page and returns to it at a later date using a GET request - they won't see the show action. Your app may throw an error or may render the index action because the user is requesting a URL like http://my.app.com/users, which would map to the index action when using a GET request.
2) if you render the show action without redirecting to a GET request and the user hits refresh, your browser will re-submit the POST request with all the same data, potentially creating duplicate instances of whatever it is you were creating. The browser will warn the user about this so they can abort, but it's potentially confusing and an unnecessary inconvenience.
As for the second part of your question, not too sure to be honest. My guess is that since you are already updating the object in question, you already have a copy of it so do not need another instance of it returned. Having said that, updating an object could trigger various callbacks which modify other attributes of the object, so returning that updated object with those modifications could make sense.
On create or update, redirect_to(#whatever) to clear the post, so that the user doesn't resubmit by refreshing. It also shows the correct url in the address bar for the create case, which posts to the collection path (/whatevers).
head :ok makes a minimal response on update, when usually you would already have the object in the dom. If you are updating the page after an update, the standard method is to use rjs views to update dom elements and render partials.

RESTful Content Negotiation in Rails

I'm looking to implement content negotiation on some resources in a Rails app. I'm using Mootools and will likely be able to tweak the content type accepted by an XMLHTTPRequest to "application/json".
Is there any way to pick up on this information in my controller and generate JSON responses instead of XHTML?
I'm trying to avoid doing something like:
http://site/resource/1?format=JSON
...as it dirties up my URL, imposes a certain degree of redundancy and is not as flexible.
Thanks!
http://site/resource/1.json is not correct use of content-negotiation. The point is that the URL should remain the same, but the client asks for a specific representation (JSON, PDF, HTML etc.) based on HTTP headers it sends with the request.
You can use a respond_to stanza in your controller method, like this:
respond_to do |format|
format.html { # Generate an HTML response... }
format.json { # Generate a JSON response... }
end
Rails determines the response format based on the value of the HTTP Accept header submitted by the client.
Surely http://site/resource/1.json should work? you may need to set it up in your Rails Environment, though, depending on how current the version of Rails you have is, I doubt it.
After much research, while rails has everything to automatically select a template for output, it still requires the call to respond_to for each one you wish to support.

Resources