Reputation: 7001
Is there a more efficient way to map a collection of objects to an array of hashes?
def list
@photos = []
current_user.photos.each do |p|
@photos << {
id: p.id, label: p.name, url: p.uploaded_image.url(:small),
size: p.uploaded_image_file_size
}
end
render json: { results: @photos }.to_json
end
This seems a bit verbose but the structure it returns is required by the frontend.
Update
So .map
is the preferred method then?
Upvotes: 0
Views: 1256
Reputation:
You can also do that like this
def array_list
@photos = current_user.photos.map { |p| { id:
p.id, label: p.name, url: p.uploaded_image.url(:small), size: p.uploaded_image_file_size } }
render json: { results: @photos }
end
Upvotes: 0
Reputation: 20263
As a starting point, it should be closer to:
def list
@photos = current_user.photos.map do |p|
{
id: p.id, label: p.name, url: p.uploaded_image.url(:small),
size: p.uploaded_image_file_size
}
end
render json: { results: @photos }
end
Just for fun, you could do something like:
class PhotoDecorator < SimpleDelegator
def attributes
%w(id label url size).each_with_object({}) do |attr, hsh|
hsh[attr.to_sym] = send(attr)
end
end
def label
name
end
def url
uploaded_image.url(:small)
end
def size
uploaded_image_file_size
end
end
And then:
> @photos = current_user.photos.map{ |photo| PhotoDecorator.new(photo).attributes }
=> [{:id=>1, :label=>"some name", :url=>"http://www.my_photos.com/123", :size=>"256x256"}, {:id=>2, :label=>"some other name", :url=>"http://www.my_photos/243", :size=>"256x256"}]
Upvotes: 1
Reputation: 44370
map
, let's as_json(*)
method do that for you.@
variable in the json render.{}.to_json
the render json: {}
do it under the hood.in the photo model.
def as_json(*)
super(only: [:id], methods: [:label, :url, :size])
end
alias label name
def size
uploaded_image_file_size
end
def url
uploaded_image.url(:small)
end
controller code.
def list
render json: { results: current_user.photos }
end
Upvotes: 3
Reputation: 3175
Please try
def list
@photos = current_user.photos.map { |p| { id: p.id, label: p.name, url: p.uploaded_image.url(:small), size: p.uploaded_image_file_size } }
render json: { results: @photos }
end
Upvotes: 1