I want to skip JBuilder for certain controllers and just use the as_json defined on the model. I find I often want to code the JSON uniformly there on the model, but in some cases I need Jbuilder.
Model
def as_json(options={})
super(only: :uuid)
end
Controller
render json: {success: #model}
I continue to get an error exclaiming template is missing.
EDIT: This is my entire render action right now, this is using devise.
def device_session
if signed_in?
render json: {user: current_user}
else
render json: {fail: 'Could not authenticate device'}
end
end
Related
I am new programming in ruby on rails and I need help with a problem of a render in an action of my controller
This is my action:
def events_calendar
render json: {events: all_events}, status: :ok
end
This is what it shows me:
I want you to show me my web page and not the data of my render, how could I solve this?
Take a look at respond_to.
def events_calendar
respond.to do |f|
f.html
f.js { render json: {events: all_events}, status: :ok }
end
end
That way, you get the JSON when you call events_calendar using AJAX, and still render events_calendar.html.erb when you use a plain HTTP resquest.
I have rails api with simple paperclip model:
def create
#photo = Photo.new(photo_params)
if #photo.save
render json: #photo, status: :created, location: #photo
else
render json: #photo.errors, status: :unprocessable_entity
end
end
private
def photo_params
params.require(:photo).permit(:image, :title)
end
My frontend framework send get like this
{"title"=>"simpletitletext", "photo"=>{"image"=>......}}
But it wrong, because rails waits following
{"photo"=>{"title"=>"simpletitle", "image"=>#...}}
I had been trying for different ways to fix angular for many hours, before wrote . May be it will be able to fix in rails
If your server has an incoming request that looks like this:
{"title"=>"simpletitletext", "photo"=>{"image"=>......}}
you can make it look like this:
{"photo"=>{"title"=>"simpletitle", "image"=>#...}}
The only difference between the two is that in the first, the title key is outside of the photo nested hash. but you want it to be inside.
So in your Rails controller,. you could write:
def photo_params
hash = params[:photo]
hash.merge(title: params[:title])
end
respond_with is acatually meant to use with ActiveModel's instances. I tried to use it with OpenStruct's instance, but it raises an error.
Is that ever possible to use respond_with with custom objects?
class CryptController < ApplicationController
respond_to :json
def my_action
respond_with OpenStruct.new(foo: 'foo', bar: 'bar')
end
# ...
end
Raises: **undefined method persisted?' for nil:NilClass**
ruby-2.1.4#rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:298:inhandle_list'
/home/workstat/.rvm/gems/ruby-2.1.4#rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:206:in polymorphic_method'
/home/workstat/.rvm/gems/ruby-2.1.4#rails4/gems/actionpack-4.2.5.1/lib/action_dispatch/routing/polymorphic_routes.rb:114:inpolymorphic_url'
respond_with is a helper method that exposes a resource to mime requests.
From the documentation
respond_with(#user)
for the create action, is equivalent (assuming respond_to :xml in the example) to:
respond_to do |format|
if #user.save
format.html { redirect_to(#user) }
format.xml { render xml: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.xml { render xml: #user.errors, status: :unprocessable_entity }
end
end
end
The precise equivalent is dependent upon the controller action.
The key takeaway is that respond_with takes a #instance variable as an argument and first attempts to redirect to the corresponding html view. Failing that, it renders an xml response, in the case above.
You are passing in an ostruct, which doesn't correspond to an instance of your model. In this case, respond_with doesn't know where to redirect to in your views and doesn't have an instance from which to render a mime response.
See this RailsCast and this blogpost from José Valim.
A note: The error undefined method persisted? is generated by Devise and probably because it can't find a route.
I have a method defined in the controller like this.
def index
end
def show
end
def new
end
def edit
end
def create
end
def findsomething
#do something using params and store it into an instance variable
return #thatvariable
end
I want to include this response into the show.jbuilder file. How Can I do that?
Every instance variable is available in the views, so no need in the return keyword.
Here is the railscast that will help
Update
In your controller action you may specify what view to render:
render "show.json.jbuilder"
So the overall code will be as follows:
def findsomething
#do something using params and store it into an instance variable
#thatvariable
render "show.json.jbuilder"
end
You may read the guides for further information.
You may specify the way to you view you wish to renders and to which all the instance variables from controller#action will be available in different ways:
render :edit
render action: :edit
render "edit"
render "edit.html.erb"
render action: "edit"
render action: "edit.html.erb"
render "books/edit"
render "books/edit.html.erb"
render template: "books/edit"
render template: "books/edit.html.erb"
render "/path/to/rails/app/views/books/edit"
render "/path/to/rails/app/views/books/edit.html.erb"
render file: "/path/to/rails/app/views/books/edit"
render file: "/path/to/rails/app/views/books/edit.html.erb"
We can use something like this in show.json.jbuilder to do that.
json.findsomething(#thatvariable)
I am currently working on a web application built on Rails 3 that heavily uses Ajax/REST for the client side. Thus, I often find myself writing controller actions like this:
def create
if !params[:name]
respond_to do |format|
format.html { render json: {}, status: :not_found }
format.json { render json: {}, status: :not_found }
end
return
end
account = ...
respond_to do |format|
format.html { render json: account }
format.json { render json: account }
end
end
Nearly all of my actions are returning a json object in a success case or an error code. However, I always have to write this verbose respond_to block and a return, if I want the action to return earlier.
Instead I would like to use something like this instead, or a similar alternative:
def create
if !params[:name]
throw :not_found
end
account = ...
return account
end
How can this be done with Rails 3+ ?
Have a look into inherited_resources. This will allow you to rewrite your controller as:
class SomeController < ApplicationController
inherit_resources
respond_to :html, :js, :json
end
That is it. All of your create/read/update/delete methods will be accessible as usual. You can, as I have in the past, inherit from a master resources controller which uses inherited_resources, and then you can tweak the responses in a more general way.
class ResourcesController < ApplicationController
inherit_resources
respond_to :html, :js
def create
create! do |format|
format.js do
# generic code here for managing all create methods initiated via js
# current model is avialbe via 'resource'
# e.g 'resource.errors'
end
end
end
Then simply inherit from that controller:
class SomeController < ResourcesController
end
This abstraction can be overkill for most purposes, but it has come in extremely handy when working 30 or 40 models which all require similar controllers.
Inherited_resources offers many helpers for accessing the current model (referred to as resource) to facilitate dynamic references, so you can, for example, return relevant forms, or partials based on resource/model name.
To give you an idea of how to use this, you could return forms for the current controller by using the controller name in the parameters. Should be noted that malformed controller names will not reach this method (as it will return 404), so it is safe to use:
format.js do
render "#{params[:controller]}/form"
end
Best of all, you can override any of the methods yourself by defining them in a particular controller.
If your are always returning json, you can ommit the respond_to block and write it like :
def create
if !params[:name]
render json: {}, status: :not_found
return
end
account = ...
render json: account
end