9

JSON API를 추가 할 기존 Rails 3 애플리케이션이 있습니다. 우리는 Vendor ActiveRecord 모델과 Employee ActiveRecord 모델을 가지고 있습니다. EmployeeVendor에 속합니다. API에서 EmployeeVendor을 JSON 직렬화에 포함하려고합니다. 예 :Rails JSON 직렬화에서 모델 연결 속성의 이름을 바꾸시겠습니까?

# Employee as JSON, including Vendor 
:employee => { 
    # ... employee attributes ... 
    :vendor => { 
     # ... vendor attributes ... 
    } 
} 

충분히 간단합니다. 그러나 공개 API가 내부 모델 이름을 공개하지 않는다는 비즈니스 요구 사항이 있습니다. 즉, 외부 세계에, 그것은 Vendor 모델이 실제로 Business라고 것처럼 보일 필요가있다 :이 최상위 개체에 대해 쉽게 할 수

# Employee as JSON, including Vendor as Business 
:employee => { 
    # ... employee attributes ... 
    :business => { 
     # ... vendor attributes ... 
    } 
} 

. 즉 의 이름을 @employee.as_json(:root => :dude_who_works_here)으로 변경하여 JSON에서 DudeWhoWorksHere으로 변경할 수 있습니다. 그러나 포함 된 협회는 어떨까요? 내가 성공하지 않고 몇 가지를 시도 : 내가 가지고있는

# :as in the association doesn't work 
@employee.as_json(:include => {:vendor => {:as => :business}}) 

# :root in the association doesn't work 
@employee.as_json(:include => {:vendor => {:root => :business}}) 

# Overriding Vendor's as_json doesn't work (at least, not in a association) 
    # ... (in vendor.rb) 
    def as_json(options) 
     super(options.merge({:root => :business})) 
    end 
    # ... elsewhere 
    @employee.as_json(:include => :vendor) 

유일한 다른 아이디어는 수동으로이 같은 키, 뭔가 이름을 변경하는 것입니다

# In employee.rb 
def as_json(options) 
    json = super(options) 
    if json.key?(:vendor) 
     json[:business] = json[:vendor] 
     json.delete(:vendor) 
    end 
    return json 
end 

을하지만 그 우아 보인다. 내가 원하는 것을보다 깨끗하고, 더 레일스 방식으로 사용할 수 있기를 바라고 있습니다. 어떤 아이디어?

답변

11

as_json에 내장 된 옵션을 사용하여 복잡한 JSON을 생성하려는 시도는 쉽지 않습니다. 귀하의 모델에서 as_json을 무시하고 super으로 전화하는 것을 귀찮게하지 않아야합니다. as_json에 대한 자체 옵션 키를 만들어 해시에 포함 할 항목을 제어하십시오.

# employee.rb 
def as_json(options = {}) 
    json = {:name => name, ...} # whatever info you want to expose 
    json[:business] = vendor.as_json(options) if options[:include_vendor] 
    json 
end 
+0

그건 제가 두려워했던 것입니다 ... – thefugal

0

음흉한 방식입니다.

class Business < ActiveRecord::Base 
    set_table_name "vendors" 
end 

지금 직원에 belongs_to를 추가 :

class Employee < ActiveRecord::Base 
    belongs_to :vendor 
    belongs_to :business, :foreign_key => :vendor_id 
    ... 
end 

전화 to_json를 옵션으로 "가상"협회에 전달 Employee에 :

공급 업체 테이블에 매핑 비즈니스라는 모델을 만들기
Employee.first.to_json(:only=>:name,:include=>:business) 
# "{\"employee\":{\"name\":\"Curly\",\"business\":{\"name\":\"Moe's Garage\"}}}" 
+0

그래, 그 전에 생각하지 않았어, 그건 꽤 비열합니다. 그래도 같은 데이터에 대해 2 가지 모델을 갖고 싶지는 않습니다. 새로운 비즈니스를 창안하고 내가 가진 모든 벤더 검증을 놓치기가 너무 쉽다. – thefugal

0

같은 문제가있어서 as_json을 재귀 적 방법으로 실행하여 옵션을 검사하고 th를 전환합니다. 별칭 이름에 대한 연관의 이름. 어쨌든, 내 애플 리케이션을 위해 일하고, 당신을 위해 일할 수도 있습니다.

관련 문제