【问题标题】:Efficient way to convert collection to array of hashes for render json将集合转换为渲染 json 的哈希数组的有效方法
【发布时间】:2018-01-31 04:29:08
【问题描述】:

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

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 是首选方法吗?

【问题讨论】:

  • 您的“更新”语句缺少上下文。最好将其作为对使用map 的答案之一的评论。

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


【解决方案1】:
  1. 不要在控制器中这样做
  2. 不要使用map 生成json 响应,让as_json(*) 方法为您完成。
  3. 不要在 json 渲染中使用 @ 变量。
  4. 不要在后台使用 {}.to_json render json: {}

在照片模型中。

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

【讨论】:

  • 这可能是最好的,因为它使 MVC 房子井井有条。
【解决方案2】:

请尝试

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】:

    作为起点,应该更接近:

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

    【讨论】:

    • 对不起。在这里迟到了。
    【解决方案4】:

    你也可以这样做

    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
    

    【讨论】:

    • 将一个方法指定为 Ruby 内置方法之一 (map) 的名称可能会造成混淆。
    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 2019-05-23
    • 2012-10-29
    • 2013-06-17
    • 2012-01-16
    • 2015-10-02
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多