Reputation: 1215
I have a RoR app with postgresql as database
Currently, I have this code:
def return_mssg_as_json
id = params[:id].to_i
@message = Message.find(id)
render json: @message
end
and it returns this JSON:
{"id":13,"created_at":"2017-10-27T19:03:52.196Z","updated_at":"2017-10-27T19:03:52.196Z","text":"ASDF"}
How can I make it return only {"text":"ASDF"}
Upvotes: 1
Views: 45
Reputation: 20263
A few things here...
First, you don't need to do to_i
here:
def return_mssg_as_json
id = params[:id].to_i
@message = Message.find(id)
render json: @message
end
You can just do:
def return_mssg_as_json
@message = Message.find(params[:id])
render json: @message
end
Now, if there's any chance that you might receive an id
that doesn't have a matching record, you might want to do something like:
def return_mssg_as_json
begin
@message = Message.find(params[:id])
render json: @message
rescue ActiveRecord::RecordNotFound
render json: {errors: :not_found}, status: :not_found
end
end
Otherwise, if your record doesn't exist, you'll have an unhandled critical error. Instead, however, you could do:
def return_mssg_as_json
if @message = Message.find_by(id: params[:id])
render json: @message
else
render json: {errors: :not_found}, status: :not_found
end
end
Now, back to your main question, you could do (as in the accepted answer)
def return_mssg_as_json
if @message = Message.find_by(id: params[:id])
render json: { message: @message[:text] }
else
render json: {errors: :not_found}, status: :not_found
end
end
Although, to save yourself three characters, it seems you could do:
def return_mssg_as_json
if @message = Message.find_by(id: params[:id])
render json: { message: @message.text }
else
render json: {errors: :not_found}, status: :not_found
end
end
Which is a great answer! But, in the future, if you want to return multiple values from @message
(for example), you could do something like (assuming @message
responds to foo
and bar
):
def return_mssg_as_json
if @message = Message.find_by(id: params[:id])
render json: @message.attributes.with_indifferent_access.slice(:text, :foo, :bar)
else
render json: {errors: :not_found}, status: :not_found
end
end
This bit:
@message.attributes
converts the record into a hash of its values. This bit:
.with_indifferent_access
allows you to select key-value pairs using symbols instead of strings. And this bit:
.slice(:text, :foo, :bar)
specifies which key-value pairs to return. So, this would return something along the lines of (in JSON format, naturally):
{text: 'blah', foo: 'blah', bar: 'blah'}
Now, in your example, you didn't want text
, you wanted message
. So, you could do:
def return_mssg_as_json
if @message = Message.find_by(id: params[:id])
attr = @message.attributes.with_indifferent_access
render json: attr.slice(:foo, :bar).merge!(message: attr[:text])
else
render json: {errors: :not_found}, status: :not_found
end
end
Which would return something along the lines of (in JSON format, naturally):
{message: 'blah', foo: 'blah', bar: 'blah'}
Upvotes: 2
Reputation: 61
Also you can use jbuilder to achieve such behavior, check an example here https://richonrails.com/articles/getting-started-with-jbuilder
Upvotes: 1
Reputation:
Simply use the following:
render json: { message: @message[:text] }
Upvotes: 1