更改Json输出,将`icd3_code_id`作为`:id`返回

时间:2014-02-28 19:54:58

标签: ruby-on-rails ruby ruby-on-rails-3

当我的控制器看起来像这样:

def search
    @icd4 = Icd4Code.search_full(params[:search]).first(20)
    render json: { icd: @icd4.as_json(:only => [:bezeichnung, :nummer, :id])}
end

我想要更改的是,我的代码不会将@icd4.id作为:id返回,而是@icd4.icd3_code_id作为:id

所以render json: { icd: @icd4 }看起来像这样:

{"icd":[{"id":6,"nummer":"A00.1","bezeichnung":"Cholera","icd3_code_id":3,"created_at":"2014-02-28T19:38:20.530Z","updated_at":"2014-02-28T19:38:20.530Z"},{"id":7,"nummer":"A00.1","bezeichnung":"El-Tor-Cholera","icd3_code_id":3,"created_at":"2014-02-28T19:38:20.533Z","updated_at":"2014-02-28T19:38:20.533Z"}]}

我的实际代码render json: { icd: @icd4.as_json(:only => [:bezeichnung, :nummer, :id])}会返回:

{"icd":[{"id":6,"nummer":"A00.1","bezeichnung":"Cholera"},{"id":7,"nummer":"A00.1","bezeichnung":"El-Tor-Cholera"}]}

我想要这个输出:

{"icd":[{"id":3,"nummer":"A00.1","bezeichnung":"Cholera"},{"id":7,"nummer":"A00.1","bezeichnung":"El-Tor-Cholera"}]}

我怎样才能做到这一点?感谢

3 个答案:

答案 0 :(得分:1)

你一定要看看draperactive_model_serializers宝石。

http://railscasts.com/episodes/409-active-model-serializers

http://railscasts.com/episodes/286-draper

虽然我以不同的方式使用Draper,然后是Ryan Bates,通常我会做这样的事情:

render json: item.decorate.as_json

例如,作为最简单的解决方案,您可以使用此类:

class Icd4CodeDecorator < Draper::Decorator
  decorates :icd4_code
  delegate_all

  def as_json(options={})
    {
      id: icd3_code_id,
      bezeichnung: bezeichnung,
      nummer: nummer
    }
  end
end

然后在你的控制器中你可以做到:

render json: @icd4.decorate.as_json

虽然我认为最好在as_json方法中保持正确并且为id属性返回id值,并创建一个继承自Draper :: CollectionDecorator并定义的装饰器类有自定义方法,如:

class Icd4CodesDecorator < Draper::CollectionDecorator
  def as_search_json
    object.map do |o|
      {
        id: icd3_code_id,
        bezeichnung: bezeichnung,
        nummer: nummer
      }
    end
  end
end

然后在你的控制器中你可以做到:

render json: Icd4CodesDecorator.new(@icd4).as_search_json

通过这种方式,您可以轻松地为模型创建和维护任意数量的json输出版本。

答案 1 :(得分:1)

如果没有序列化程序,您可以遍历项目及其密钥,并在找到密钥时重命名密钥。

@icd4 = Icd4Code.search_full(params[:search]).first(20)
data = @icd4.as_json(:only => [:bezeichnung, :nummer, :icd3_code_id]).tap do |icd4_json|
    icd4_json.each do |icd4_item|
        icd4_item.each do |key|
            icd4_item[ 'id' ] = icd4_item.delete( key ) if key == 'icd3_code_id'
        end
    end
end
render json: { icd4: data }

答案 2 :(得分:0)

最简单的方法是巧妙地改变像这样的值

def search
   @icd4 = Icd4Code.search_full(params[:search]).first(20)
   r = icd: @icd4.as_json(:only => [:bezeichnung, :nummer, :icd3_code_id])
   final_value = []
   r["icd"].each do |h|
    f = {} 
    h.map do |k,v|
    if k == 'icd3_code_id'
     f["id"] = v
    else
      f[k] = v
    end
   end
  final_value << f
 end
 render json: final_value
end