2011-02-24 19 views
8
class Api::StoresController < ApplicationController 
    respond_to :json 

    def index 
    @stores = Store.all(:include => :products) 
    respond_with @stores 
    end 
end 

Devoluciones sólo almacena sin sus productos, al igual queInclusión de objetos anidados en respuesta JSON, desde MongoMapper objetos

Store.find(:all).to_json(:include => :products) 

se prueba la asociación, puedo ver los productos anidados en ouput consola de, digamos,

Store.first.products 

¿Cuál es la forma correcta de obtener productos incluidos con MongoMapper?

Éstos son mis modelos:

class Store 
    include MongoMapper::Document   
    many :products, :foreign_key => :store_ids 
    end 

    class Product 
    include MongoMapper::Document   
    key :store_ids, Array, :typecast => 'ObjectId' 
    many :stores, :in => :store_ids 
    end 

ACTUALIZACIÓN

Al tratar la sugerencia de Scott, he añadido lo siguiente para el modelo de la tienda:

def self.all_including_nested 
    stores = [] 
    Store.all.each do |store| 
    stores << store.to_hash 
    end 
end 

def to_hash 
    keys = self.key_names 
    hash = {} 
    keys.each{|k| hash[k] = self[k]} 
    hash[:products] = self.products 
    hash[:services] = self.services 
    hash 
end 

Y en el controlador :

def index 
    @stores = Store.all_including_nested 
    respond_with @stores 
end 

¿Cuál parece como debería funcionar? Suponiendo que la matriz de valores hash hubiera llamado a #to_json, y luego sucedería lo mismo con cada hash y cada Producto + Servicio. Estoy leyendo el origen de ActiveSupport :: JSON, y hasta ahora eso es lo que he deducido de él.

Pero, sin embargo, no funciona ... :(

Respuesta

17

Tenga una mirada en el método as_json(). se pone esto en sus modelos, definir su JSON, y luego simplemente llamar al método render :json y obtener lo que quiere.

class Something 
    def as_json(options={}) 
    {:account_name  => self.account_name, 
    :expires_on   => self.expires_on.to_s, 
    :collections  => self.collections, 
    :type    => "Institution"} 
    end 
end 

Notará self.collections que es una relación de muchos. Ese modelo también ha definido as_json():

class Collection 
    def as_json(options={}) 
    {:name   => self.name, 
    :title   => self.title, 
    :isbn   => self.isbn, 
    :publisher  => self.publisher, 
    :monthly_views => self.monthly_views} 
    end 
end 

Ésta contiene self.monthly_views que representa otra relación de muchos.

Luego, en su controlador:

@somethings = Something.all 
render :json => @somethings 
+0

en el borde del tiempo, acababa de figurar lo mismo y iba a actualizar la pregunta con ella;) respuesta muy apreciada, gracias – oliverbarnes

2

Puede que tenga que crear su propio método para generar un hash a continuación, gire el hash en JSON estoy pensando algo como esto:.

store = Store.first 
keys = store.key_names 
hash = {} 
keys.each{|k| hash[k] = store[k]} 
hash[:products] = store.products 
hash.to_json 
+0

Gracias, eso tiene sentido - acaba de descubrir el: incluye opción sólo funciona en a_json de active_record. Lo conseguí trabajando para una sola instancia, implementando un Store # to_json (solo tuve que eliminar la asignación hash = keys ...), pero todavía tengo que descubrir cómo hacerlo para las colecciones. Cansado de parchear mongo_mapper sí mismo :) – oliverbarnes

Cuestiones relacionadas