lets say I have a method as follows
def index
applications = Application.all
render json: applications, each_serializer: ApplicationIndexSerializer, status: 200
end
now this works and it returns me my custom serializer, but if I want to add custom keys to the payload like {data: application} it stops working.
however when I change the render method to
render json: {meta: {}, data: applications}, each_serializer: ApplicationIndexSerializer, status: 200
it throughs an error or the serializer does not get hit.
You probably want something like this:
render json: applications, each_serializer: ApplicationIndexSerializer, meta: {}, status: 200
Related
I use find_or_initialize_by in my controller and then would like to apply the additional params to the record, whether new or existing. Is this possible to do in a Railsy way or do I have to loop through the parameters?
def create
re_evaluation = #client.re_evaluations.find_or_initialize_by(program_id: re_evaluation_params[:program_id], check_in_id: re_evaluation_params[:check_in_id])
# apply remaining re_evaluation_params here
if re_evaluation.save
render json: re_evaluation, status: :created
else
render json: re_evaluation.errors.full_messages, status: :unprocessable_entity
end
end
You should be able to assign the parameters as you'd do normally.
re_evaluation.assign_attributes(re_evaluation_params)
if re_evaluation.save
...
I'd like to know if is possible to render variable without params on render with brackets with AMS?
for exemple:
render json: { comments: #comments, status: 200, hasMore: hasMore }
i'd like to render just #comments without the comments: and with hasMore: hasMore showing on the json that is just possible inside brackets!
with this way
render json: #comments, hasMore: hasMore, include: ['user', 'replies.**']
did not show the hasMore on the json
If you're rendering json, you need to make sure what you pass as json is actually valid json. Here's a most simple example:
# this does not work and will throw a syntax error
render json: 'foo: 'foo', bar: 'bar'
but
# this works
render json: {foo: 'foo', bar: 'bar'}
# this works because it will render an array type
render json: #comments # assuming that is a collection
I'm using this method to pass back outfits from an ajax call:
def givemeoutfits
if current_user
#outfits = Outfit.search(params[:search],1000000,1,1000000,1,1000000,1,1000000,1).page(1).per(7).results
#results = Outfit.search(params[:search],1000000,1,1000000,1,1000000,1,1000000,1).page(1).per(7).results.total_count
if request.xhr?
render status: 200, json: #outfits
end
end
end
I want to add the integer 'results' to the json produced by the #outfits and returned to the ajax call. How can I do this?
Are you just wanting to include #results in the returned JSON object, like this?
render status: 200, json: {
outfits: #outfits,
results: #results
}
Then, in your javascript, you can interact with both keys.
I am trying to create multiple database entries using only one JSON request.
Each entry consists only of two values, a type (of action) and a time (when the action happened). To get multiple of those into one request, I am using a JSON Array.
This is what my create action in the controller looks like:
def create
respond_to do |format|
#actions = []
save_succeeded = true
params[:action].each do |action|
new_action = Action.new(type: action.type, time: action.time)
save_succeeded = false unless new_action.save
#actions << new_action
end
if save_succeeded
format.json { render json: #actions, status: :created }
else
format.json { render json: #actions.errors, status: 501 }
end
end
end
When I send a post request to the controller (/actions.json) like this:
[{ "type": 0, "time": 1234567890 },{ "type": 0, "time": 1234567891 }]
I get back an empty array [] and a status code of 201 Created.
This means, the save_succeeded variable is still true, but the actions did not get added to the array. Furthermore, the actions are not in my database.
What am I doing wrong? What am I overlooking?
I would refactor the code a bit:
def create
actions = params[:action].inject([]) do |memo, action|
memo << Action.create!(type: action[:type], time: action[:time])
end
render json: #actions, status: :created
rescue ActiveRecord::RecordInvalid => e
render json: e.message, status: 501
end
end
Couple of notable changes:
use create! and rescue ActiveRecord::RecordInvalid - create! will raise a ActiveRecord::RecordInvalid if the save fails. Then, the rescue block will rescue the exception and you can render a nice error message.
you cannot use action.time, because params is a Hash, not an object.
if you want to build an array to render later, you can use inject.
if you would like to have some atomicity to this (either everything is created or nothing!), you can wrap the whole thing in a transaction block.
It's worth mentioning that I haven't tested the code above, but it should give you a direction and (maybe) it will be a drop-in replacement.
Hope that helps!
What is the simplest/shortest way to respond in an API controller. Currently the following works:
respond_to do |format|
format.json { render 'client', status: :ok }
end
however this controller will only ever respond to json (respond_to :json) so the whole respond_to do |format| thing seems like unnecessary code.
Ideally I would just like to do something simple like:
render 'client', status: :ok
Update:
I neglected to mention that: 'client' is a jbuilder template that does not match my action name.
You can use render directly
render json: 'client', status: :ok
According to #hassasin, you can indicate your controller to render json: format on each action of your controller.
Other option is to take advantage of your config.routes.rb to set the entire response format of your controller, e.g. contacts_controller:
resources :contacts, defaults: {format: :json}
If you want to indicate the status, add this to your actions:
def index
render status: :ok # 200, 400, 500, what ever you want
end
I tested the code above with Rails 3.2.16
I hope it helps you.
Since you are using json views (assume you are using jbuilder), you dont need that render statement if your action name matches the view name.