Включение вложенных объектов в ответ JSON из объектов MongoMapper - PullRequest
8 голосов
/ 24 февраля 2011
class Api::StoresController < ApplicationController  
  respond_to :json

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

Возвращает только магазины без их продуктов, как и

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

Ассоциация проверена, я вижу вложенные продукты в выводе консоли, скажем,

Store.first.products

Как правильно получить их продукты, включенные в MongoMapper?

Вот мои модели:

   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

ОБНОВЛЕНИЕ

При попытке Скотта предложитьЯ добавил следующее в модель Store:

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

И в контроллере:

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

Какой выглядит так, как он должен работать?Если предположить, что массиву хешей будет вызван #to_json, то же самое произойдет с каждым хешем и каждым продуктом + сервисом.Я читаю источник ActiveSupport :: JSON, и до сих пор это то, что я понял.

Но, пока не работает ...: (

Ответы [ 2 ]

17 голосов
/ 25 февраля 2011

Взгляните на метод as_json(). Вы помещаете это в свои модели, определяете свой json, а затем просто вызываете метод render :json и получаете то, что хотите.

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

Вы заметите self.collections, что много отношений. Эта модель также имеет 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

Этот содержит self.monthly_views, который представляет другое множество отношений.

Тогда в вашем контроллере:

@somethings = Something.all
render :json => @somethings
2 голосов
/ 25 февраля 2011

Возможно, вам придется создать свой собственный метод для создания хэша, а затем превратить его в JSON. Я думаю что-то вроде этого:

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