I'm really confused on the concept of this.
I'm supposed to make API that handles JSON responses. I read this
and other places, they all showed example on how to do it for the show or index aspect of the controller. I understand that, where you outputs all the attributes of the model. But my main question is, if somebody were to create or edit, what do I do with the whole JSON on there?
If all you need to do is pass back a 200 for a successfull create, then don't creating a response.
render :nothing => true
If on the other hand, you added some important information to the object that you are updating that the client will require (If you are not sure, then assume that the client will require it), then you should pass the updated object's attributes back
respond_to do |format|
format.json {render :json => {... }}
end
Related
I have a model that I only want to ever return JSON, regardless of any conneg or file-like extensions on the URI (e.g. /app/model.json). Google-fu is coming up short and this can't be that difficult.
In your controllers you simple have to create a respond_to block that only responds to JSON:
respond_to do |format|
format.json { render :json => #model }
end
This is actually a decision made by the controller, not because there is/is not a model or view present. In your controller you can:
render json: #your_model
However you will quickly find that the default implementation of to_json (which is what is used internally, above) can be annoying hard to do exactly what you want. When you reach that point you can use RABL to create views that massage the JSON from your model(s) exactly as you want.
I'm new to Ruby and Rails. I just completed a course in Laravel, so I am aware of the MVC system(not a newbie as far as the basic concepts are concerned).
I have a rather simple question,
I am sending a POST request to my RAILS REST API,the body of the post request contains a json encoded string like this--->
Array ( [method] => POST [timeout] => 45 [redirection] => 5 [httpversion] => 1.0 [blocking] => 1 [headers] => Array ( ) [body] => {"post_content":"here is the post","post_title":"here we are ","post_author":"1"} [cookies] => Array ( ) )
As you can see,its coming from my php based blog.
My rails API is supposed to be taking the post content and automatically adding links to certains words, by comparing the words with some stuff that i have in an SQLite database.
Ok, so my problem is this:
I just want the response from the Rails controller, I dont want anything loaded into a view. The Rails Controller - returns the content, with 'a href' tags around words that are found in my database. This is to be sent back as the response to my post request, and i want to access it directly as the body of the response.
As of now I dont know how this is to be done. Laravel has the ability to 'return' whatever you want to , at the end of the Controller Action, but in Rails, everything seems to want to load into a view.
I have researched some questions here and found one which said 'render :nothing => true',but that renders nothing at all.Here is what my code looks like.
def process
content = params['post_content']
##perform db function and get back the content with the links embedded.
##HOW TO RETURN THIS CONTENT.
end
Personally, I think, i have to use the render_to_string method, but I have no idea how to do this.
Any help is appreciated.
Best Regards,
Richard Madson.
Some options to consider:
Render just the raw string as the http response body:
render :text => content
Render a view without the default surrounding layout:
render :layout => false
In that case your view could just be:
<%= #content %>
Or render the content as json:
render :json => { :content => content }
The question is, what do you want returned? Text? XML? JSON?
I'm going to assume you want JSON back based on the JSON going in.
respond_to do |format|
format.json { render json: #someobject }
end
It might be helpful to see the rest of the controller method.
If I understand correctly believe what you are looking for is
render :text => "response"
there is also - JSON, XML, nothing, js, file, etc - more information here http://guides.rubyonrails.org/layouts_and_rendering.html
I have Vacancies controller and I need to pass #vacancies to json and also render another layout. The following code does not work (json is not passed however I have "wide" layout). If I remove format.html { render layout: "wide"} } json passes correctly. How to combine these two things?
class VacanciesController < ApplicationController
respond_to :html, :json
...
def index
#vacancies = Vacancy.all
respond_with(#vacancies) do |format|
format.html { render layout: "wide"} }
format.json { render json: #vacancies }
end
end
...
You can't call render twice, that's problem #1. You also can't send two responses to a single request.
There is also no purpose in rendering HTML (which means a fresh page load) and sending JSON (which is for AJAX requests, ie requests that don't reload the page) at the same time. It isn't possible, but it also would be pointless even if it was possible.
If you want to tell a request to use a specific layout, you can pass the layout option to a render call. However, a render call does not take a data object as the first argument, it takes a view name, or only an options hash. So to call this correctly you should use:
render :index, :layout => 'example'
I expect that will make your HTML views show up correctly.
Please understand however, the layout option is only useful for HTML responses, not JSON responses. Layout is telling your render call what outer HTML to wrap around the view your action is calling, and if you don't specify it uses 'application.html'
To help you understand one more thing: your respond block is telling the computer how to respond to different kinds of requests. It's like a switchboard. If you wrote it with if/else statements it might look like this:
if request_type == 'html'
render :index, :layout => 'wide'
elsif request_type == 'json'
render :json => #vacancies
else
raise raise ActionController::UnknownFormat
end
So, with your respond_with block, if you fix your html render call, and assuming you're developing on localhost, if you enter the following URL in your browser and hit enter...
http://localhost:3000/vacancies
That would be making an HTML format GET request, which will load the page with layout: 'wide' but no other data. If you type:
http://localhost:3000/vacancies.json
That will simulate a JSON request, and you'll get just the JSON representation of the #vacancies data.
I hope that helps you solve your problem. If not, please describe what you're trying to accomplish in more detail so I can help you understand how to do it.
PS: one last tip: if you want to specify layouts at the controller level you can just call layout at the top of your controller, like so:
class ExampleController < ApplicationController
layout 'awesome', :only => [:new,:edit]
...
end
This works like any other filter, you can pass :only, or :except, or no options at all.
I have a situation where I'm returning json objects to my application which are built from YML files. Because to parse the yml file and return it as json I always have to do something like this:
format.json { render json: YAML.load(render_to_string :file => File.join(Rails.root,'app','views','home','icons.yml.erb'), :layout => false ) }
I would like to make this operation shorter, by creating a custom format that (however) result in a json, so I don't want to create a new mime type.
My idea is to write:
format.myformat
Which will automatically search for myaction.myformat.erb inside views/mycontroller directory, and will automatically parse the yaml file returning it as a json object.
Is this possible? If yes, how can I eventually do this?
Edit 1:
I found an important suggestion in config/mime_types.rb:
Mime::Type.register_alias "text/html", :iphone
So I can alias a mime type, now the biggest problem is: how to define the default render action for a given format, like format.html does?
If I write
format.html
current_action.html.erb will be automatically rendered, how can I choose the correct method to render a custom format?
Edit 2:
I managed to create this code (inside a controller, through some helper methods I built):
def icons
respond_to do |format|
format.extjson { render_to_extjson }
end
end
Is possible to make rails understand that if I write:
def icons
respond_to do |format|
format.extjson
end
end
it has to do:
format.extjson { render_to_extjson }
by default?
You could do something like:
respond_to do |format|
format.html { #foo = Foo.all(:limit => 10) }
format.any(:atom, :rss) { #foo = Foo.all }
end
A longer post going into the guts of the render actions can be found here: http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/
While Josh's answer is a valid one, I would rather see your parsing code wrapped up into an object. If you put that object into app/models, it'll be testable and you can always verify any change to the logic with a test suite.
Another upside to this is that you can re-use the format.json call and make you controller that much simpler.
This is not doable at the moment, I read a lot of rails sources and there isn't a way to access that method, so isn't possible to customize it.
I'll write a rails plugin to support this and eventually I'll post it here, but for sure the answer actually is: this can't be done.
I have a controller named CourseRequests which will be accepting an ajax request for the "new" method.
Since it will be responding with json, should I use /course_requests/new.json?
I don't want to make a template for such a silly json response, how would I do that?
What does respond_to do? (I have seen it block style and I understand that, but what about non-block style)
Yes, your JS would be doing something along the lines of:
$.getJSON("/course_requests/new.json",...);
You don't have to, you just need to have a respond_to block with JSON handled there.
respond_to do |format|
format.json { render :json => "test" }
end
Blockless syntax, I think you mean this: http://davidwparker.com/2010/03/09/api-in-rails-respond-to-and-respond-with/ . Basically, you specify what mime types your controller responds to and then you can use the cooler responds_with method.