rails controller defaults to respond with application/xml in production - ruby-on-rails

I have a standard contacts_controller.rb with index action that responds as follows:
respond_to do |format|
format.html
format.xml { render :xml => #contacts }
end
In development, it works as intended: when I browse to http://localhost:3000/contacts, I get an html response.
But, when I start the app using capistrano on a remote Ubuntu server and browse to the same url, I get an xml response.
If I go to http://remote_host:8000/contacts.html, then I see the html response. If I comment out the format.xml { render :xml => #contacts }, then I see the desired html response.
Pretty sure I'm missing something subtle about difference between Rails development and production modes. Any ideas about what I'm overlooking?
Thanks,
- Dave

The following links explain the phenomenon:
http://rails_security.lighthouseapp.com/projects/15332/tickets/5-using-http-basic-authentication-with-ie-not-working
http://geminstallthat.wordpress.com/2008/05/14/ie6-accept-header-is-faulty/
I fixed my issue by adding this to development|test|production.rb:
config.action_controller.use_accept_header = false

Related

How to send (model object as) reponse in xml format in ruby on rails?

I'm very new to Ruby and Ruby on Rails and I have been searching for a way to send response in xml format via REST API that I am building using ruby on rails. No luck so far!
This is the code I have at the moment:
respond_to do |format|
format.json do
render json: { terminals: #terminals }
end
format.xml do
render xml: { terminals: #terminals }.to_xml
end
end
It kind of works but the output is something I cannot make sense of:
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<terminals type="Terminal">#<Terminal:0x007f1db02b6900></terminals>
</hash>
I don't even know how to search for this issue online. I've tried going through the documentation be I've found no solution. Really need some help with this one! Thanks in advance!
You don't need to call to_xmlon the object that you want to render. If you use the :xml option, render will automatically call to_xml for you.
respond_to do |format|
format.xml {render :xml => #terminals}
end
or in Rails 4 simply:
render :xml => #terminals
http://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to

My rendering in Rails (possibly) causes a 422 error

I have received reports from users to my website that they get Error 422 when visiting a "result" page using POST. I cannot re-create this error at all so I am wondering if there is anything in my code below that would cause this error in formatting? I expect there could be errors here since I have upgraded a Rails 3.x project to a Rails 4.2.
I would either like to know if there is anything obvious in the code that would create 422 errors or if there is anyway to troubleshoot 422-errors.
Basically, in #show there is a POST method to result. It is creating a result text and lands on a url like /this-post-name/result?r=abc123 . I am rendering #show in /result because it is basically loading the same page again but with a "result box". Having to use /result is a choice I made as a newbie programmer and is not absolutely necessary, I think.
I am quite sure the error lies within the "respond_to" but can't figure that out, or troubleshoot it (i.e. re-create it).
Also, I am not sure if this is important, but I get tons of AuthencityToken errors on this page.
Edit: I managed to recreate this issue by accessing it through my iPhone and post a form, then I disabled cookies and send the form again. That would not be something people would do often but I guess having cookies disabled may cause this?
def show
#avaliable_posts = Post.where(:available => true)
end
def result
if request.get? && params[:r].blank? # Just visiting /result withoutout POST or ?r url
redirect_to category_path(#category)
else
set_round(session[:round_by_number])
# Either the visitor just posted the result or is revisiting through URL
if !params[:r].blank? # Visitor arrived from URL
#result = Result.find_by_scrambled_identifier(params[:r])
params_to_use = #result.params_used
#params_to_use = #result.params_used
else
params_to_use = params
#params_to_use = params_to_use
end
post_instance = #post.get_post_instance(params_to_use)
if post_instance.valid?
#post_result_array = post_instance.calculate_me(params_to_use)
#post_result_text_array = #post_result_array[0]
respond_to do |format|
format.html { render :action => "show" }
format.json { render :json => #post }
end
else # post not valid
#errors = post_instance.errors
respond_to do |format|
format.html { render :action => "show" }
format.xml { render :xml => #validator.errors, :status => :unprocessable_entity }
format.json { render :json => #post }
end
end
end
end
A 422 means Unprocessable Entity. Within your sample code is only one place with this http status code:
format.xml { render :xml => #validator.errors, :status => :unprocessable_entity }
Obviously this happens when format is XML and #validator contains an error.
Edit:
With the new information about the exception within the logs and the second linked stackoverflow question it seems to be releated to a known Rails issue
It seems like this issue is related to another issue that I have written another question for. I have an InvalidAuthencityToken issue with my website and the exceptions created through that cause a 422 (and not a 500) error as far as I understand from http://api.rubyonrails.org/v2.3/classes/ActionController/RequestForgeryProtection/ClassMethods.html
I am not 100% sure that this is the same issue but it seems quite likely and therefore I will close this question.

Rails respond_to redirect all requests except X mime-type

Below is the typical respond_to block im using in my controller
respond_to do |format|
format.html # show.html.erb
end
I want to restrict all mime-types except html(lets say).
Couldn't come up with a solution, how is this possible? This block does nothing if the request is json, this is OK but what I want is to redirect any requests that are not html.
Thanks
The format object yielded by respond_to has all of the usual mime types (html, js, xml, etc), and it also has a catch-all mime type any that will handle everything else. So, in this case:
respond_to do |format|
format.html
format.any { redirect_to :foo }
end
will use default rendering for html, and will redirect for everything else. See the docs for (a tiny bit) more information: http://apidock.com/rails/ActionController/MimeResponds/respond_to

How can I make rails use plaintext errors and backtraces instead of html ones?

I am doing a lot of API development and tend to interact with my rails app from a command line or network proxy.
How can I make rails use plaintext errors and backtraces instead of html ones?
Errors are printed in the server log as plaintext. If you don't have easy access to the logs, you could write a custom exception handler which would print the error to the user in plaintext.
You can also change your responds_to handling:
def create
company = params[:person].delete(:company)
#company = Company.find_or_create_by_name(company[:name])
#person = #company.people.create(params[:person])
respond_to do |format|
format.html { redirect_to(person_list_url) }
format.js
format.xml { render :xml => #person.to_xml(:include => #company) }
end
end
So if you're rendering xml, json, or text, you've got options for output, and Rails shouldn't be generating HTML error messages.

How do I make a json request to a rails 3 website?

I know that if I have a url like
mysite/posts/1
The default type returned to me is html. I can get an xml version of the resource by just doing
mysite/posts/1.xml
But how do I get a json version? Is the following supposed to work?
mysite/posts/1.json
Reason I ask is because it doesn't seem to be working. So I figured I should find out if it's "supposed" to work this way before investigating further.
You're doing it right, but if the Controller isn't setup to respond to json requests you won't get anything. You'll have a respond_to block like this:
respond_to do |format|
format.html
format.xml { render :xml => #model_var.to_xml }
format.json { render :json => #model_var.to_json } #without this line, .json requests will go unanswered by the web server.
end

Resources