Rails JSON request - ruby-on-rails

I have a issue where I cant get my rails v4 app to recognize a JSON request. I am sending the following header('Content-Type' => 'application/json') from my mobile/client app and the request payload is a JSON string.
Started POST "/devices" for 127.0.0.1 at 2013-12-25 17:50:46 -0800
Processing by DevicesController#create as */*
respond_to do |format|
format.html
format.json do
# Request does not come in this block
end
end
However when I append ".json" to my request URL, my rails app is able to process it as a JSON request
Started POST "/devices.json" for 127.0.0.1 at 2013-12-25 17:13:43 -0800
Processing by DevicesController#create as JSON
Anything I am doing wrong?

So the Content-Type header describes request's type, not respose's.
Rails determines the desired response format from the HTTP Accept
header submitted by the client.
What you can do is check for request.content_type and render json: {} or HTML accordingly.

Related

Respond with script from a Rails API app with limited middleware (config.api_only = true)?

I have a Rails 5 app build as an api app. So by default it only responds with json.
But for one specific request I need the app to respond with a script.
In a regular Rails app I would simply put my script in a js.erb file. This won't work here.
If my controller action looks like this:
def respond_with_js
end
and I request the app like this:
$.getScript("https://myapp.example.com/respond_with_js");
it responds with 204 No Content:
Started GET "/respond_with_js" for 127.0.0.1 at 2018-06-27 20:28:44 +0200
Processing by ApplicationController#respond_with_js as */*
Completed 204 No Content in 0ms
How do I work around this?
You cannot request as script, if rails server is only api version.
Rails by default responds json.
def respond_with_json
render json: {message: "works"}, status: :ok
end
To request it, you need to request as json dataType:
$.ajax({
url: "https://myapp.example.com/respond_with_json",
method: "GET",
dataType: "json",
success: function(res){
console.log(res.message)
}
})

Curl JSON POST request to Rails app

I am newbie in Rails and I am trying to create an engine in rails. The point is to send JSON data to app in this format {city: "Berlin", country: "Germany"} and receive back same JSON, but with reversed values like {city: "nilreB"} and so on.
My route is:
Rails.application.routes.draw do
post "collect/data" => 'data#create'
end
My controller is:
class DataController < ApplicationController
def create
render text: "#{request.body}"
end
end
I know that controller is not finished at all, but I am wondering why I am getting HTTP error when I am making POST request like:
curl -v -d '{"key1":"value1", "key2":"value2"}' http://0.0.0.0:3000/collect/data --header "Accept: application/json" --header "Content-Type: application/json"
HTTP/1.1 204 No Content
I have read that is fine when you use Rails 5, I am using it. So my question is am I missing something in controller or somewhere else? I would be much appreciated for any help.
These are logs:
INFO -- : [df2105a8-e2c5-4e27-a9c7-ffc91c8b92e8] Started POST "/collect/data" for 127.0.0.1 at 2018-02-09 20:26:49 +0000
INFO -- : [df2105a8-e2c5-4e27-a9c7-ffc91c8b92e8] Processing by DataController#create as JSON
INFO -- : [df2105a8-e2c5-4e27-a9c7-ffc91c8b92e8] Parameters: {"key1"=>"value1", "key2"=>"value2", "datum"=>{"key1"=>"value1", "key2"=>"value2"}}
INFO -- : [df2105a8-e2c5-4e27-a9c7-ffc91c8b92e8] No template found for DataController#create, rendering head :no_content
INFO -- : [df2105a8-e2c5-4e27-a9c7-ffc91c8b92e8] Completed 204 No Content in 1ms
As #ma_il said my parameters are available in DataController as params[:datum], I have searched a bit more about params in Rails 5.1 which I am using and discovered that my full amswer is:
def create
my_hash = params[:datum].permit!
render json: my_hash.to_h.collect { |keys, values| "#{keys}{values.reverse}" }
end

Additional quotes in parameters

i'm trying to learn simple stuff a make HTTP request to rails app.
the problem is, when i try to make HTTP post request to my rails app, code is :
uri = URI.parse("http://localhost:4000/posts")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data( :post=> {"name" => "My query", "title" => "50"} )
response = http.request(request)
when i look into console for incoming post request, the output is:
Started POST "/posts" for 127.0.0.1 at 2015-02-02 16:14:12 +0100
Processing by PostsController#create as */*
Parameters: {"post"=>"{\"name\"=>\"My query\", \"title\"=>\"50\"}"}
Completed 500 Internal Server Error in 1ms
NoMethodError (undefined method `permit' for "{\"name\"=>\"My query\", \"title\"=>\"50\"}":String):
app/controllers/posts_controller.rb:72:in `post_params'
app/controllers/posts_controller.rb:27:in `create'
Look closely on parameters. Why does ist add additional quotation marks? how to fix this problem?
Because you are sending a stringified JSON object. I don't know what set_form_data is doing but you should be converting your request .to_json.
Look at this so question for reference here.

What is difference, ruby HTTParty and angular $http

HTTParty
url = "https://my-url/locomotive/api/tokens.json"
response = HTTParty.post(url, body: { :api_key => #api_key })
On the server:
Started POST "/locomotive/api/tokens.json" for 202.4.224.66 at 2014-06-15 17:59:57 +1000
Processing by Locomotive::Api::TokensController#create as JSON
Parameters: {"api_key"=>"5fcfe580e42944c896a49469c30aa97a384b497d"}
$http
$http({
url: 'https://ernie-locomotive.12wbt.com/locomotive/api/tokens.json',
method: 'POST',
params: data
});
Started OPTIONS "/locomotive/api/tokens.json?api_key=5fcfe580e42944c896a49469c30aa97a384b497d" for 59.167.21.65 at 2014-06-15 17:53:43 +1000
Processing by Locomotive::Public::PagesController#show as JSON
Parameters: {"api_key"=>"5fcfe580e42944c896a49469c30aa97a384b497d", "path"=>"locomotive/api/tokens"}
WARNING: Can't verify CSRF token authenticity
Basically, I thought they are two same methods. Seems that $http doesn't pass http method. HTTParty does what it requers and grabs the results correctly.
Because it is cross origin request, browser sends CORS preflight request before actual one...
More about CORS: http://www.html5rocks.com/en/tutorials/cors/

NoMethodError users_url with devise (ajax)

I use devise 2.2.2 with rails 3.2.11
I use devise with ajax requests
I changed the following configuration in initializers/devise.rb
config.navigational_formats = [:json, :html]
config.http_authenticatable_on_xhr = false
when I submit an empty sign in request, I expect to get a json response with errors hash, but i get a 500 instead (see below for the trace) (it works fine with sign up request)
here are my routes (nothing special)
devise_for :users
the trace:
Started POST "/users/sign_in.json" for 127.0.0.1 at 2013-01-27 13:33:45 +0100
Processing by Devise::SessionsController#create as JSON
Parameters: {"user"=>{"email"=>"", "password"=>"[FILTERED]"}}
Completed 401 Unauthorized in 1ms
Processing by Devise::SessionsController#new as JSON
Parameters: {"user"=>{"email"=>"", "password"=>"[FILTERED]"}}
Completed 500 Internal Server Error in 40ms
NoMethodError (undefined method `users_url' for #<Devise::SessionsController:0x007fe88ddd9550>):
You are probably overriding after_sign_in_path_for and have a code path in there that returns nil.
This causes devise to fall back to its default behaviour and call users_url to get the path to redirect to.
Why do I think this? Because you are having the same error I had (and lost some hair over) and also this bug report contains the github usernames of many other people who have been humbled by this particular issue.

Resources