I would like to my create action on my rails API to accept either a JSON POST or and XML POST. Do I need to do anything special or should it just work out of the box as long as every comes through as params?
Rails just sees them as params that are passed in. However you will want to have a respond to block that responds properly to xml vs json
respond_to do |format|
format.xml { #render XML STUFF }
format.json { #render JSON STUFF }
end
http://api.rubyonrails.org/classes/ActionController/MimeResponds.html
Be careful, Rails 4 removed support for XML. You may need to install the actionpack-xml_parser gem to support receiving XML as POST params. This requires you to add the following to config/application.rb
config.middleware.insert_after ActionDispatch::ParamsParser, ActionDispatch::XmlParamsParser
This was answered originally here.
Don't forget to restart your Rails server once you're done :)
Related
Due to the fact that the asset pipeline es deactivated, how can I use js.erb - files in plugin-development?
These files (i.e. files in app/views/**/*.js.erb) are used as the view for an actual web request. There, the assets pipeline would never kick in at all.
Instead, you can just return the response as you normally would for html. Just make sure to correctly set the format on your render call in your controller, e.g.
respond_to do |format|
format.js {}
end
or (in case the requested format is not set as js), you can use an explicit render call:
render format: :js
How would this be updated for Rails 3.1?
http://railscasts.com/episodes/88-dynamic-select-menus
I just can't figure out how to call the js.erb file and have it run the code to generate the javascript dynamically.
Might be something: in Rails 3.1, you're most likely using jQuery instead of Prototype. The example code on the Railscasts site is using good old Prototype instead of the new hotness that is jQuery (default javascript library in Rails 3.1).
Once all your jquery pipes are connected, having rails respond to and render your js.erb is the same as always. In your controller:
def country_selected
// whatever you need to do
respond_to do |format|
format.js
end
end
Then in your view directory, you have a country_selected.js.erb that you can put in whatever javascript you want to update the second select menu. (Remember you have to escape your shiz for it to work correctly) e.g.
<%= escape_javascript(params[:country]) %>
By the way, I think .rjs was moved out of Rails proper and into it's own Gem. Something else to keep in mind regarding Rails 3.1 vs. javascript.
You can use head to build header-only responses. The Rails guide is very helpful in pointing out that you can send a :bad_request or :created header. Where is a list of all of these Rails HTTP header aliases?
Have a look at Rack::Utils::HTTP_STATUS_CODES, it's used by Rails to set the status codes. To have the symbol, just "downcase" and "underscore" the hash values.
I am working on an application where I use paperclip for uploading images, then the image is manipulated in a flash app and returned to my application using application/octet-stream. The problem is that the parameters from flash are not available using params. I have seen examples where something like
File.open(..,..) {|f| f.write(request.body) }
but when I do this, the file is damaged some how.
How can I handle this in rails 3?
After you make sure that the request parameters have hit the Rails application, you may want to ensure that there were no parsing problems. Try to add these lines in you controller's action:
def update # (or whatever)
logger.debug "params: #{params.inspect}"
# I hope you do not test this using very large files ;)
logger.debug "request.raw_post: #{request.raw_post.inspect}"
# ...
end
Maybe the variable names got changed somehow? Maybe something escaped the parameter string one time too much?
Also, you have said that the file into which you want to save the request body is damaged. How exactly?
The request.body object does not need to be String. It may be a StringIO, for example, so you may want to type this:
File.open(..,..) {|f| f.write(request.body.read) }
I've written functional tests for API endpoints built in Rails using shoulda testing framework.
An example looks like the following:
setup do
authenticated_xml_request('xml-file-name')
post :new
end
should respond_with :success
authenticated_xml_request is a test helper method that sets
#request.env['RAW_POST_DATA'] with XML content.
After upgrading the app from rails 2.3.3 to rails 2.3.8, the functional tests are failing because the XML content received is not merged in the params hash.
I'm setting the request with the correct mime type via #request.accept =
"text/xml"
I'm able to inspect the content of the request using request.raw_post but i'd like to keep the current setup working.
Also, running a test from the terminal using cURL or any other library (rest_http) in development mode, the API works perfectly well.
Any tips or help is much appreciated.
Now it's simpler:
post "/api/v1/users.xml", user.to_xml, "CONTENT_TYPE" => 'application/xml'
Note that you have to specify appropriate "CONTENT_TYPE". In other case your request will go as 'application/x-www-form-urlencoded' and xml won't be parsed properly.
I solved the issue by adding a custom patch to rails (test_process.rb file) to convert incoming xml to hash then merge into parameters hash.
on line 439:
parameters ||= {}
parameters.merge!(Hash.from_xml(#request.env['RAW_POST_DATA'])) if #request.env['RAW_POST_DATA'] && #request.env['CONTENT_TYPE']=='application/xml'