programing tip

json 출력에 가상 속성 추가

itbloger 2020. 12. 3. 07:37
반응형

json 출력에 가상 속성 추가


TODO 목록을 처리하는 앱이 있다고 가정 해 보겠습니다. 목록에 완료 및 미완성 항목이 있습니다. 이제 목록 개체에 두 개의 가상 속성을 추가하고 싶습니다. 목록의 완료 및 미완성 항목 수. 또한 json 출력에 표시되어야합니다.

미완성 / 완성 된 항목을 가져 오는 두 가지 방법이 내 모델에 있습니다.

def unfinished_items 
  self.items.where("status = ?", false) 
end 

def finished_items 
  self.items.where("status = ?", true) 
end

그렇다면 json 출력 에서이 두 가지 방법의 수를 어떻게 얻을 수 있습니까?

Rails 3.1을 사용하고 있습니다.


Rails에서 객체의 직렬화는 두 단계로 이루어집니다.

  • 먼저 as_json객체를 단순화 된 해시로 변환하기 위해 호출됩니다.
  • 그런 다음 반환 값에서 to_json호출되어 as_json최종 JSON 문자열을 가져옵니다.

일반적으로 to_json혼자 두기를 원 하므로 다음 과 같이 자신의 as_json구현을 추가 하기 만하면 됩니다 .

def as_json(options = { })
  # just in case someone says as_json(nil) and bypasses
  # our default...
  super((options || { }).merge({
    :methods => [:finished_items, :unfinished_items]
  }))
end

다음과 같이 할 수도 있습니다.

def as_json(options = { })
  h = super(options)
  h[:finished]   = finished_items
  h[:unfinished] = unfinished_items
  h
end

메소드 지원 값에 다른 이름을 사용하려는 경우.

XML과 JSON에 관심이 있다면 serializable_hash.


Rails 4를 사용하면 다음을 수행 할 수 있습니다.

render json: @my_object.to_json(:methods => [:finished_items, :unfinished_items])

이것이 최신 / 최신 버전을 사용하는 사람에게 도움이되기를 바랍니다.


이를 수행하는 또 다른 방법은 다음을 모델에 추가하는 것입니다.

def attributes
  super.merge({'unfinished' => unfinished_items, 'finished' => finished_items})
end

이것은 xml 직렬화에도 자동으로 작동합니다. http://api.rubyonrails.org/classes/ActiveModel/Serialization.html 하지만 레일 3에서 키를 정렬 할 때이 메서드가 기호를 처리 할 수 ​​없기 때문에 키에 문자열을 사용하고 싶을 수도 있습니다.하지만 그렇지 않습니다. 레일 4에서 정렬되므로 더 이상 문제가 없을 것입니다.


단지 주변 모든 데이터를 하나의 해시에 같은

render json: {items: items, finished: finished, unfinished: unfinished}


저는이 답변을 기존 as_json 블록 에 통합하려는 저와 같은 모든 사람에게이 답변을 제공 할 것이라고 생각했습니다 .

  def as_json(options={})
    super(:only => [:id, :longitude, :latitude],
          :include => {
            :users => {:only => [:id]}
          }
    ).merge({:premium => premium?})

.merge({})끝까지 붙이 세요.super()


으로 Aswin는 위에 나열된, :methods그것은 기존의 모델 / assossiations에 기능을 추가하기 때문에이 트릭을 할 것입니다 복잡한 assosiations이 경우, JSON 속성으로 특정 모델의 방법 / 기능을 반환 할 수 있도록합니다 : D 그것이처럼 작동합니다 재정의하고 싶지 않다면 매력as_json

이 코드를 확인 :methods하고 :include[N + Query는 옵션이 아닙니다.)]

render json: @YOUR_MODEL.to_json(:methods => [:method_1, :method_2], :include => [:company, :surveys, :customer => {:include => [:user]}])

Overwritting as_json function will be way harder in this scenario (specially because you have to add the :include assossiations manually :/ def as_json(options = { }) end


This will do, without having to do some ugly overridings. If you got a model List for example, you can put this in your controller:

  render json: list.attributes.merge({
                                       finished_items: list.finished_items,
                                       unfinished_items: list.unfinished_items
                                     })

참고URL : https://stackoverflow.com/questions/6892044/add-virtual-attribute-to-json-output

반응형