rails render page as json - ruby-on-rails

How to render page as json correctly
my chunk of code
respond_to :html, :xml, :json
def getOffersByURL
#my_model= Mymodel.where(attr1: params[:url], :validFrom => {:$lte => Time.now}).all
respond_with #my_model
end
When in trying to do like this nothing happens
http://0.0.0.0:3000/getOffersByURL?url=some_data.xml
or
http://0.0.0.0:3000/getOffersByURL?url=some_data.json
concretely it comes like this
Processing by MyController#getOffersByURL as HTML
Parameters: {"url"=>"some_data.xml"}

Try to change your function:
def getOffersByURL
#my_model= Mymodel.where(attr1: params[:url], :validFrom => {:$lte => Time.now}).all
respond_to do |format|
format.json {
render json: #my_model
}
format.html {
#my_model
}
end
end
What happens if you try to show your json like this in your view:
<%= #my_model.to_json %>
Do you have any data checking the page in the browser? Open the developers tool and try to find if the object brings any data...

Related

Rails 4 *.json.jbuilder files ignored

In my Rails 4.1.1 app (which has the jbuilder gem included), json views always output all columns in the table, ignoring the app/views/[model]/*.json.jbuilder files.
In routes.rb, I have:
resources :workshops do
resources :memberships
resources :events
end
In events_controller.rb, I have:
# GET /workshop/:workshop_id/events
# GET /workshop/:workshop_id/events.json
def index
#events = #workshop.events
respond_to do |format|
format.html
format.json { render json: #events }
end
end
I set the #workshop variable in a "before_action" in the controller.
When I visit /workshops/f00/events, it displays in HTML format as expected.
If I make the file, app/views/events/index.json.jbuilder:
json.events do
end
...when I visit /workshops/f00/events.json, I expect that the output would be empty. However, I get the contents of the entire #events in JSON format.
What I would like to see is only particular fields being output, given a app/views/events/index.json.jbuilder that contains:
json.array!(#events) do |event|
json.extract! event, :id, :title, :description
json.start event.starts_at
json.end event.ends_at
json.url workshop_event_url([#workshop, event], format: :json)
end
... but no matter the contents of the .jbuilder file, the output is always the same. Could anyone tell me why my .jbuilder file is being ignored, and how to get it working?
The line format.json { render json: #events } will always render the #events array since the url /workshops/f00/events accepts both html and json formats and you're rendering #events when hitting the url with the json format.
If you want to render the data in app/views/events/index.json.jbuilder change:
respond_to do |format|
format.html
format.json { render json: #events }
end
to:
respond_to do |format|
format.html
format.json
end
By not rendering the #events array you rely on Rails to output whatever is in app/views/events/index.json.jbuilder.

dynamic rendering based on data results

I am curious if this is even possible. I am looking to render data based on the results of an action in ruby on rails. Here is the code:
def convert
render :text => Item.convert(params[:file], params[:output])
end
As you can see currently it just renders text. The item model takes in two parameters: a file and output. The output could be xml, json, plain text, etc. Some type of data. What I was hoping I could do is that I could render the output based on the output parameter. But make it dynamic. I was hoping I could do:
def convert
#items = Item.convert(params[:file], params[:output])
respond_to do |format|
format.json { render :json => #items }
format.xml { render :xml => #items }
end
end
Something that would call the method and based on the data returned it would render the appropriate data. Testing the above code returns an empty page. The body tag is completely empty.
Any ideas?
thanks
Mike Riley
If you are relying on the name of params[:output] to determine what to render, I would write is as below:
def convert
#items = Item.convert(params[:file], params[:output])
if File.extname(params[:output].match("text"))
render :text => Item.convert(params[:file], params[:output])
elsif File.extname(params[:output].match("json"))
render :json => Item.convert(params[:file], params[:output])
elsif File.extname(params[:output].match("xml"))
render :xml => Item.convert(params[:file], params[:output])
else
render :html => "default_html"
end
end
and you should have a default_html.html.erb that you would render if the extension name of the file does not match what is expected

Rails: respond_to JSON and HTML

I have a controller "UserController" that should respond to normal and ajax requests to http://localhost:3000/user/3.
When it is a normal request, I want to render my view. When it is an AJAX request, I want to return JSON.
The correct approach seems to be a respond_to do |format| block. Writing the JSON is easy, but how can I get it to respond to the HTML and simply render the view as usual?
def show
#user = User.find(params[:id])
respond_to do |format|
format.html {
render :show ????this seems unnecessary. Can it be eliminated???
}
format.json {
render json: #user
}
end
end
As per my knowledge its not necessary to "render show" in format.html it will automatically look for a respective action view for ex : show.html.erb for html request and show,js,erb for JS request.
so this will work
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
also, you can check the request is ajax or not by checking request.xhr? it returns true if request is a ajax one.
Yes, you can change it to
respond_to do |format|
format.html
format.json { render json: #user }
end
The best way to do this is just like Amitkumar Jha said, but if you need a simple and quick way to render your objects, you can also use this "shortcut":
def index
#users = User.all
respond_to :html, :json, :xml
end
Or make respond_to work for all the actions in the controller using respond_with :
class UserController < ApplicationController
respond_to :html, :json, :xml
def index
#users = User.all
respond_with(#users)
end
end
Starting from Rails 4.2 version you will need to use gem responder to be able to use respond_with.
If you need more control and want to be able to have a few actions that act differently, always use a full respond_to block. You can read more here.

rails respond_to format.js API

I am an experienced JAVA and C++ developer and I am trying to understand how rails works.
I got this code below:
respond_to do |format|
if #line_item.save
format.html { redirect_to store_url }
format.js { render :json => #line_item, :mime_type => Mime::Type.lookup('application/json'),
:callback => 'javascriptFunction' }
and I've been searching the api that defines what I can pass inside the format.js {} but I could not find..
first of all: what kind of statement is format.js, is that a variable?
and most important: what attributes can I pass into format.js {} ? can you pass the direct link? I've searched over the http://api.rubyonrails.org/
respond_to do |format|
format.js # actually means: if the client ask for js -> return file.js
end
js here specifies a mime-type that the controller method would send back as a response;
Default Rails mime-types.
If you try also with format.yaml:
respond_to do |format|
format.js
format.yaml
end
that will mean that your controller will return yml or js depending on what the client-side is asking;
{} in terms of ruby is a block;
If you don't specify any rails will try to render a default file from app/views/[contoller name]/[controller method name].[html/js/...]
# app/controllers/some_controller.rb
def hello
respond_to do |format|
format.js
end
end
will look for /app/views/some/hello.js.erb; // at least in Rails v. 2.3.
If you do specify block:
respond_to do |format|
# that will mean to send a javascript code to client-side;
format.js { render
# raw javascript to be executed on client-side
"alert('Hello Rails');",
# send HTTP response code on header
:status => 404, # page not found
# load /app/views/your-controller/different_action.js.erb
:action => "different_action",
# send json file with #line_item variable as json
:json => #line_item,
:file => filename,
:text => "OK",
# the :location option to set the HTTP Location header
:location => path_to_controller_method_url(argument)
}
end
I believe this was the url you were looking for:
https://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
This might also be helpful to some, to see that you can actually render js directly within the format.js method, if you for example only have a small one line js statement you want to return, and you don't want to defer to a RJS file like controller_action_name.js.erb:
respond_to do |format|
format.html { redirect_to new_admin_session_path }
format.js { render :js => "window.location='#{ new_admin_session_path }'" }
end

Rails method that handles ajax complaining about no template?

I have a subscriber#create method that is only used for ajax submits to it (the html form uses data-remote="true" to do the Ajax. The form does indeed submit and the data ends up in the db but the method throws an error saying that the template was not found.
How can I specify a function as being an Ajax handler in Rails? -- one that doesn't have to render a template, etc.
Here is what the method looks like:
class SubscribersController < ApplicationController
def create
Subscriber.create(:email => params[:email],
:ip_address => request.remote_ip,
:referring_page => request.referer ) unless Subscriber.find_by_email(params[:email])
end
end
You should handle the call in your respond_to properly.
...
respond_to do |format|
format.html
format.js { :nothing => true }
end
The thing it, you should probably return something. Even if it is an AJAX call, you should send something back to let the caller know that the creation was a success.
def create
#subscriber = Subscriber.new(#your params)
respond_to do |format|
if #subscriber.save
format.js { render :json => #subscriber, :status => :created, :location => #susbscriber }
else
format.js { render :json => #susbcriber.errors, :status => :unprocessable_entity }
end
end
end
Also, you shouldn't have to do the unless Subscriber.find_by_email(params[:email]) in your controller. You should just add validates_uniqueness_of :email to the Subscriber model.
you want something like render :layout => !request.xhr? in your controller, this will prevent the layout if the request is ajax

Resources