Rails에서 to_json을 재정의하는 방법은 무엇입니까?


94

최신 정보:

이 문제는 제대로 조사되지 않았습니다. 진짜 문제는 render :json.

원래 질문의 첫 번째 코드 붙여 넣기는 예상 결과를 산출합니다. 그러나 여전히 경고가 있습니다. 이 예를 참조하십시오.

render :json => current_user

이다 NOT 과 동일

render :json => current_user.to_json

즉 , User 개체와 연결된 메서드를 render :json자동으로 호출하지 않습니다 to_json. 실제로 모델에서 to_json재정의되는 경우 아래 에 설명 된 내용이 생성 됩니다.Userrender :json => @userArgumentError

요약

# works if User#to_json is not overridden
render :json => current_user

# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json

이 모든 것이 나에게는 어리석은 것 같습니다. 이것은 유형 이 지정 될 때 render실제로 호출되지 않는다는 것을 알려주는 것 같습니다 . 누군가 여기서 실제로 무슨 일이 일어나고 있는지 설명 할 수 있습니까?Model#to_json:json

이 문제를 해결할 수있는 모든 genii는 다른 질문에 답할 수 있습니다. Rails에서 @ foo.to_json (options) 및 @ bars.to_json (options)을 결합하여 JSON 응답을 빌드하는 방법


원래 질문 :

나는 다른 몇 가지 예를 보았지만 내가 찾고있는 것을하지 않습니다.

노력하고있어:

class User < ActiveRecord::Base

  # this actually works! (see update summary above)
  def to_json
    super(:only => :username, :methods => [:foo, :bar])
  end

end

나는 얻고 ArgumentError: wrong number of arguments (1 for 0)에서

/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json

어떤 아이디어?


귀하의 예제는 내 모델 중 하나에서 작동합니다. 의 어떤은 수행 username, foo또는 bar방법은 인수를 기대?
Jonathan Julian

아니, username방법 및되지 않습니다 foobar방법을 필요로하지 않는다. 오류가 발생한 위치를 표시하기 위해 질문을 업데이트했습니다.
maček 2010

1.8.7을 실행하고 있습니다. 해당 파일을 열고 인수가 0 인 메서드에 인수를 전달하는 이유를 확인해야합니다.
Jonathan Julian

답변:


214

하나의 매개 변수 인 해시 로 재정의해야하기 ArgumentError: wrong number of arguments (1 for 0)때문에 얻는 to_jsonoptions입니다.

def to_json(options)
  ...
end

의 긴 설명 to_json, as_json및 렌더링 :

ActiveSupport 2.3.3에서는 as_json발생한 문제와 같은 문제를 해결하기 위해 추가되었습니다. json 의 생성 은 json의 렌더링 과 분리되어야합니다 .

이제 언제든지 to_json객체에서 as_json호출되고 데이터 구조를 생성하기 위해 호출 된 다음 해당 해시는를 사용하여 JSON 문자열로 인코딩됩니다 ActiveSupport::json.encode. 이것은 객체, 숫자, 날짜, 문자열 등 모든 유형에 대해 발생합니다 (ActiveSupport 코드 참조).

ActiveRecord 개체는 동일한 방식으로 작동합니다. as_json모든 모델의 속성을 포함하는 해시를 생성 하는 기본 구현이 있습니다. 원하는 JSON 구조를 생성하려면 모델에서 재정의해야합니다as_json . as_jsonold와 마찬가지로 to_json는 선언적으로 포함 할 속성과 메서드를 지정할 수있는 옵션 해시를 사용합니다.

def as_json(options)
  # this example ignores the user's options
  super(:only => [:email, :handle])
end

컨트롤러에서 render :json => o문자열 또는 개체를받을 수 있습니다. 문자열 인 경우 응답 본문 (객체 인 경우) to_json이 호출 될 때 전달 as_json되며 위에서 설명한대로 트리거 됩니다.

따라서 모델이 as_json재정의 (또는 그렇지 않은 경우) 로 올바르게 표현되는 한 , 하나의 모델을 표시하는 컨트롤러 코드는 다음과 같아야합니다.

format.json { render :json => @user }

이야기의 교훈은 다음과 같습니다. 직접 전화하지 말고 그렇게 to_json하도록 허용 하십시오 render. JSON 출력을 조정해야하는 경우 as_json.

format.json { render :json => 
    @user.as_json(:only => [:username], :methods => [:avatar]) }

@Jonathan Julian, 이것은에 대한 매우 유용한 설명입니다 as_json. ActiveRecord :: Serialization 문서 ( api.rubyonrails.org/classes/ActiveRecord/… ) 에서 볼 수 있듯이 이에 대한 문서 는 거의 없습니다. 나는 이것을 시도 할 것입니다 :)
maček

1
@Jonathan Julian, 제가 이것을 10 번 찬성 할 수 있다면 그렇게 할 것입니다. 도대체 as_json문서 는 어디에 ! 다시 한 번 감사드립니다 :)
maček 2010

71

당신이 레일 3에서이 문제가 발생하는 경우, 오버라이드 (override) serializable_hash대신 as_json. 이렇게하면 XML 서식도 무료로 제공됩니다. :)

이것은 알아내는 데 영원히 걸렸습니다. 누군가에게 도움이되기를 바랍니다.


1
누구든지 방법에 대한 좋은 글을 알고 serializable_hash있습니까? 내가 그것을 사용할 때, 그것은 대신에 항상 "<hash>"로 그것을 감싸도록 객체를 그 이름으로 감싸는 것에서 내 후속 xml 출력을 변경한다 (예를 들어, 인용 객체의 경우 "quote").
Tyler Collier

@TylerCollier 같은 옵션이어야합니다to_xml
Sam Soffes

이 솔루션에 감사드립니다! 나는 ruby2 / rails4를 사용하고 있고 as_json은 중첩 된 객체로 작업하지 않았고, 재정의 된 메서드는 'include'에서 호출되지 않았으며 serializable_hash가 작동합니다!
santuxus

serializable_hash를 대신 대체해야하는 이유에 대한 설명은 robots.thoughtbot.com/better-serialization-less-as-json 을 참조하십시오 .
Topher Hunt

36

사용자 옵션을 무시하지 않고 옵션을 추가하고 싶지 않은 사람들을 위해 :

def as_json(options)
  # this example DOES NOT ignore the user's options
  super({:only => [:email, :handle]}.merge(options))
end

이것이 누구에게나 도움이되기를 바랍니다 :)


1
나는 기본을 제외하고 이것은 내가 그것을 할 방법이다 options와 해시 = {}가 호출 필요하지 그래서
mroach을

4

to_json이 아니라 as_json을 재정의하십시오. 그리고 as_json에서 원하는 것을 호출하십시오.

이 시도:

def as_json 
 { :username => username, :foo => foo, :bar => bar }
end

아닌가요 as_json단지 ActiveResource을 위해?
Jonathan Julian

분명히 ActiveRecord :: Serialization에는 as_json api.rubyonrails.org/classes/ActiveRecord/Serialization.html
glebm 2010

@glebm, 나는 이것을 시도했고 동일한 결과를 얻고 있습니다. 당신에게 보여주기 위해 내 질문을 업데이트했습니다.
maček 2010

@glebm, 여전히 똑같은 오류가 발생합니다. 내가 할 때에도 render :json => current_user예상되는 기본 결과 ( UserJSON 형식의 모델에 대한 모든 속성)를 얻습니다 . 모델에 as_json메서드를 추가하고 User동일한 작업을 시도하면 오류가 발생합니다. (
maček

@glebm, 감사합니다. 내가 뭔가 잘못하고 있다는 것을 알고 있습니다. 업데이트 된 질문을 확인하는 것이 좋습니다.
maček 2010
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.