Ruby on rails 使用:include时展平Rails中的JSON数据

Ruby on rails 使用:include时展平Rails中的JSON数据,ruby-on-rails,ruby,json,curl,Ruby On Rails,Ruby,Json,Curl,我已经使用教程在我的应用程序中添加了一个高级搜索,并为它创建了一个API。一切正常,但现在我尝试显示JSON数据 这是cURL命令: curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X GET http://0.0.0.0:3000/api/searches/129 这是Curl命令的结果,请注意括号[],因此这是一个散列数组: [{"id":4,"state_id":5,"name":"S

我已经使用教程在我的应用程序中添加了一个高级搜索,并为它创建了一个API。一切正常,但现在我尝试显示JSON数据

这是cURL命令:

curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X 
GET http://0.0.0.0:3000/api/searches/129
这是Curl命令的结果,请注意括号[],因此这是一个散列数组:

[{"id":4,"state_id":5,"name":"School Liason Officer","created_at":"2014-10-16T03:13:00.000Z",
"updated_at":"2014-10-16T03:13:00.000Z","state":{"name":"California"}}]
但我想更改JSON结果,以便以某种方式使用JSON数据将状态名称压平

有人知道我如何做到这一点,或者是否有可能将数据展平

这是我想要的一个例子:

[{"id":4,"state":"California","name":"School Liason Officer","created_at":"2014-10-16T03:13:00.000Z",
"updated_at":"2014-10-16T03:13:00.000Z"}]
型号:

class State < ActiveRecord::Base  
  has_many :district_resources

end

class DistrictResource < ActiveRecord::Base
  belongs_to :state

end

class Search < ActiveRecord::Base

  def district_resources
    @district_resources ||= find_district_resources
  end

  def find_district_resources
    district_resources = DistrictResource.order(:name)
    district_resources = district_resources.where(state_id: state_id) if state_id.present?
    district_resources
  end

end
API控制器:

module Api
  module V1
    class SearchesController < ApplicationController

      respond_to :json

      def show
        @search = Search.find(params[:id])
        @searches = []
        (@searches << @search.district_resources).flatten!

        json = @searches.to_json

        def flatten_hash(h)
          new_hash = {}

          ###I get an error here undefined method `each_pair' for Array
          h.each_pair do |key, val|
            if val.is_a?(Hash)
              new_hash[key] = val.values.join(',')
            else
              new_hash[key] = val
            end
          end
          new_hash
        end

        flattened_hash = flatten_hash(JSON.parse(json))
        flattened_hash.delete("state_id")

        respond_to do |format|

          ###How can i merge the state name with the json results
          format.json { render :json => flattened_hash.to_json(:include => [:state => {:only => [:name]}] )}
        end
      end

    end
  end
end
错误


您可以随时操纵它,即将其传递给另一个变量、使用方法调用等:

  my_json["state"] = my_json["state"]["name"]
  my_json.delete("state_id")

这将把state=>设置为name=>的值,然后删除不需要的state\u id=>

我支持Beartech的评论,但假设这是不可能的,然后这样做

require 'json'

def flatten_hash(h)
  new_hash = {}
  h.each_pair do |key, val|
    if val.is_a?(Hash)
      new_hash[key] = val.values.join(',')
    else
      new_hash[key] = val
    end
  end
  new_hash
end

json = '{"id":4,"state_id":5,"name":"School Liason Officer","created_at":"2014-10-16T03:13:00.000Z", "updated_at":"2014-10-16T03:13:00.000Z","state":{"name":"California"}}'
flattened_hash = flatten_hash(JSON.parse(json).to_hash)
flattened_hash.delete("state_id")
给予


我把上面的两个答案结合起来,得到了我所需要的

  def show
    @search = Search.find(params[:id])
    @searches = []
    (@searches << @search.district_resources).flatten!

    json = @searches.to_json(:include => [:state => {:only => [:name]}] )

    def flatten_hash(h)
      new_hash = []
      h.each do |val|
        if val.is_a?(Hash)
          val["state"] = val["state"]["name"]
          val.delete("state_id")
          (new_hash << val).flatten!
        else
          new_hash << val
        end
      end
      new_hash
    end

    flattened_hash = flatten_hash(JSON.parse(json))

    respond_to do |format|
      format.html
      #(:include => [:state => {:only => [:name]}] )
      format.json { render :json => flattened_hash.to_json }
    end
  end

如果您不想干扰太多的后处理,您可以精心设计SQL查询以包括。。。地区资源。州为“州”。。。。。不知道你会怎么做,但这是一种方法。因此,与其只返回state\u id,不如让它查找state并给它state键。这应该会给你一个具有如图所示的别名的对象,但是我在每个Rails控制台中尝试这一点只会给我一个nil记录。i、 e.t=Tool.selectserial作为my_serial.whereid:38刀具加载1.3ms从tools中选择serial作为my_serial,其中tools.id=38=>[]我当前的输出是一个哈希数组。因此,我一直得到这个错误未定义的方法“to_hash”:在你的问题中找不到,但是不要使用to_hash,因为它是一个hash,只需在枚举数组时将其展平即可
{"id"=>4, "name"=>"School Liason Officer", "created_at"=>"2014-10-16T03:13:00.000Z", "updated_at"=>"2014-10-16T03:13:00.000Z", "state"=>"California"}
  def show
    @search = Search.find(params[:id])
    @searches = []
    (@searches << @search.district_resources).flatten!

    json = @searches.to_json(:include => [:state => {:only => [:name]}] )

    def flatten_hash(h)
      new_hash = []
      h.each do |val|
        if val.is_a?(Hash)
          val["state"] = val["state"]["name"]
          val.delete("state_id")
          (new_hash << val).flatten!
        else
          new_hash << val
        end
      end
      new_hash
    end

    flattened_hash = flatten_hash(JSON.parse(json))

    respond_to do |format|
      format.html
      #(:include => [:state => {:only => [:name]}] )
      format.json { render :json => flattened_hash.to_json }
    end
  end