将集合转换为渲染json的哈希数组的有效方法

时间:2018-01-31 04:29:08

标签: ruby-on-rails arrays ruby ruby-on-rails-5

是否有更有效的方法将对象集合映射到哈希数组?

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

这看起来有点冗长,但它返回的结构是前端所需要的。

更新

那么.map是首选方法吗?

4 个答案:

答案 0 :(得分:3)

  1. 不要在控制器中执行此操作
  2. 不要使用map生成json响应,让as_json(*)方法为您执行此操作。
  3. 不要在json渲染中使用@变量。
  4. 不要使用{}.to_json render json: {}在幕后做。
  5. 在照片模型中。

    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
    

    控制器代码。

    def list
      render json: { results: current_user.photos }
    end
    

答案 1 :(得分:1)

作为一个起点,它应该更接近:

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

只是为了好玩,你可以做类似的事情:

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

然后:

> @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"}]

答案 2 :(得分:1)

请尝试

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

答案 3 :(得分:0)

您也可以这样做

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