Rails - format Time in API response - ruby-on-rails

i have a model places in relationship with the model opening_times.
In my places_controller i have this:
def index
places = Place.all
if places
render json: {
status: :ok,
result: places.as_json(
only: [
:id,
:name,
],
include: [
{ opening_times: {only: [:dayWeek, :open, :close]}},
]
)
}
else
render json: { errors: 'invalid request' }, status: 422
end
end
private
def place_params
params.require(:place).permit(:user_id, :name)
end
The open and close columns in DB are time.
How can i force to return a format time as %H:%M?

I'm not developing on RoR 3+ years... fill free to fix if there is any problem
So can You try this:
places = Place.all.map {|place|
place.opening_times.map! {|opening_time|
opening_time[:open].strftime! "%H:%M"
opening_time[:close].strftime! "%H:%M"
}
}

Related

Rails API: how translate json request in spanish if my model is in english?

Model convention parameters need to be in English, but the input JSON request keys need to send it in Spanish, how is the best practice for rails to accept parameters in Spanish and save in database?
MODEL:
class Player < ApplicationRecord
validates :name, :level, :goals, :salary, :bonus, :team, presence: true
end
INPUT:
{
"jugadores" : [
{
"nombre":"Snow",
"nivel":"C",
"goles":10,
"sueldo":50000,
"bono":25000,
"sueldo_completo":null,
"equipo":"rojo"
},
{
"nombre":"JC",
"nivel":"A",
"goles":30,
"sueldo":100000,
"bono":30000,
"sueldo_completo":null,
"equipo":"azul"
}
]
}
Controller:
...
def create
#player = Player.new(player_params)
if #player.save
render json: #player, status: :created, location: #player
else
render json: #player.errors, status: :unprocessable_entity
end
end
...
def player_params
params.permit( jugadores: [ :nombre, :nivel, :goles, :salario, :bono, :salario_completo, :equipo ] )
end
...
thnx
Ill tried to translate with I18n, but I can't solve translate ActiveController
$"translation missing: en.{"jugadores"=>{"name"=>"Irving"}}"

Rails:Receive POST with JSON array

I'm currently using a controller to receive POST with one json object at a time. And I want it change to receiving the whole array. How can I modify my controller?
Current Controller
def create
respond_to do |format|
#targetrecord = TargetRecord.new(targetrecord_params)
#targetrecord.save
if #targetrecord.save
format.json{ render :json => #targetrecord.to_json ,status: 200 }
else
format.json { render json: #targetrecord.errors, status: 404 }
end
end
end
end
def targetrecord_params
params.require(:targetrecord).permit(:id, :uuid, :manor, :mac, :beacon_type, :longitude, :latitude, :address, :findTime, :rssi, :finderID, :created_at, :updated_at )
end
I'm sending the POST as below right now
"targetrecord":
{"id":"","name":"",.....}
And I want to send multiple sets as an array like
"targetrecord":[
{"id":"1","name":"",.....},
{"id":"2","name":"",.....},
....]
How can I let my controller know that she needs to extract and create one by one? Thanks a lot!
If you are POSTing an array, then the array will just be part of your params object when processed by the controller action. So you should be able to loop through the array and create an array of TargetRecord objects. You'll need to modify your targetrecord_params method to allow it to accept an argument since you can't just look at 'params' in that context once you make the change. You'll also need to find a way to track whether or not all the records have saved successfully.
I haven't tested this code, but something like this should get you going in the right direction, I think:
def create
respond_to do |format|
#targetrecords = []
save_succeeded = true
params[:targetrecord].each do |record|
tr = TargetRecord.new(targetrecord_params(record))
save_succeeded = false unless tr.save
targetrecords << tr
end
if save_succeeded
format.json{ render :json => #targetrecord.to_json ,status: 200 }
else
format.json { render json: #targetrecord.errors, status: 404 }
end
end
end
end
def targetrecord_params(record)
record.require(:targetrecord).permit(:id, :uuid, :manor, :mac, :beacon_type, :longitude, :latitude, :address, :findTime, :rssi, :finderID, :created_at, :updated_at )
end

Rails Controller Modify JSON Response

I have this method in my controller:
# GET /bios/1
# GET /bios/1.json
def show
if member_session?
#member = MemberPresenter.new(#bio.member)
# I need something here to add a flag to the json response to signal this is a member session.
else
#member = MemberPresenter.new(#bio.member)
end
end
I need to modify the json response to return something like:
{ member: #member, member_session: true }
Thanks in advance!
You can use json param for render functions:
render json: { member: #member, member_session: true }
But it's not the best way to render JSON in rails. I'd recommend you try to use https://github.com/rails-api/active_model_serializers
I'm not sure if you specifically want to return json all the time but here's an alternative to rendering other formats as well:
respond_to do |format|
format.html
format.json { render json: { member: #member, flag: #member.status } }
end
For small and simple objects, doing this is fine, but if you had to drag the associations along, you have the choice of using a serializer, or you could override the to_json method to something like this.
# member.rb
def as_json(options = {})
options = options.merge(
except: [
:updated_at,
:created_at,
],
include: { # Getting associations here
address: {
only: [:street, :zip_code],
include: {
neighbors: { only: :name }
}
}
}
)
super.as_json(options)
end
And finally within the controller, render json: #member.to_json and it will pull all the associations you want with it. This is the lazy man's way of serializing aka what I do :)

activemodel serializers with data as root when object is failed to save

I'm using active model serializer for my API to serialize data models.
class Api::V1::UsersController < Api::V1::ApiController
include ::ActionController::Serialization
def create
user = User.new(user_params)
if user.save
return render json: user, status: :ok, root: :data
end
render_error(user.errors)
end
private
def user_params
params.require(:user).permit(:email, :password)
end
def render_error(errors, status = :unprocessable_entity)
meta = { count: errors.messages.count }
render json: errors, status: status, meta: meta, root: :data
end
end
When user parameters are valid and it is saved to DB, the API returns with data as root. For example:
{
"data": {
"id": 11
}
}
However, when parameters are not valid and the user object is not saved to DB, it returns without data as root. Example:
{
"email": [
"has already been taken"
]
}
I'm not sure what I'm missing, but I just want the API to return data as root for also failed scenario. Btw, the user serializer only includes id attribute.
You can specify it in the JSON:
def render_error(errors, status = :unprocessable_entity)
meta = { count: errors.messages.count }
render json: { data: errors }, status: status, meta: meta
end

Create Nested Object with Rails 4 (JSON call)

I am refactoring a project, and I remembered that I had some troubles in realizing how to put a nested object, but I found this question useful.
So, as I understand it, you needed to pass as a parameter your associated model name in plural and add a '_attributes' to it. It worked great in Rails 3.2.13.
Now, here is what I have in Rails 4:
class TripsController < Api::V1::ApiController
def create
begin
#user = User.find(params[:user_id])
begin
#campaign = #user.campaigns.find(params[:campaign_id])
if #trip = #campaign.trips.create(trip_params)
render json: #trip, :include => :events, :status => :ok
else
render json: { :errors => #trip.errors }, :status => :unprocessable_entity
end
rescue ActiveRecord::RecordNotFound
render json: '', :status => :not_found
end
rescue ActiveRecord::RecordNotFound
render json: '', :status => :not_found
end
end
private
def trip_params
params.require(:trip).permit(:evnt_acc_red, :distance, events_attributes: [:event_type_id, :event_level_id, :start_at, :distance])
end
end
And the Trip model looks like this:
class Trip < ActiveRecord::Base
has_many :events
belongs_to :campaign
accepts_nested_attributes_for :events
end
So, I am doing a POST call with the following JSON:
{"trip":{"evnt_acc_red":3, "distance":400}, "events_attributes":[{"distance":300}, {"distance":400}]}
And, even though I don't get any kind of error, no event is being created. The trip is being created correctly, but not the nested object.
Any thoughts on what should I do to make this work on Rails 4?
Alright, so... I was sending the JSON wrongly:
Instead of:
{
"trip": {
"evnt_acc_red": 3,
"distance": 400
},
"events_attributes": [
{
"distance": 300
},
{
"distance": 400
}
]
}
I should have been sending:
{
"trip": {
"evnt_acc_red": 3,
"distance": 400,
"events_attributes": [
{
"distance": 300
},
{
"distance": 400
}
]
}
}

Resources