8 Stimmen

Einfügen von verschachtelten Objekten in die JSON-Antwort, von MongoMapper-Objekten

class Api::StoresController < ApplicationController  
  respond_to :json

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

Retouren nur Geschäfte ohne ihre Produkte, wie auch

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

Die Assoziation ist getestet, ich kann die verschachtelten Produkte in der Konsolenausgabe von z. B. sehen,

Store.first.products

Was ist der richtige Weg, um diese Produkte in MongoMapper einzubinden?

Hier sind meine Modelle:

   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

UPDATE

Ich habe Scotts Vorschlag ausprobiert und dem Store-Modell Folgendes hinzugefügt:

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

Und im Controller:

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

Welche siehe wie es funktionieren sollte? Angenommen, das Array von Hashes würde #to_json auf sie aufgerufen haben, und dann das gleiche würde passieren, um jeden Hash und jedes Produkt + Service. Ich lese durch ActiveSupport::JSON's Quelle, und so weit, dass ist, was ich von ihm grokked haben.

Aber es funktioniert noch nicht... :(

17voto

user634718 Punkte 186

Werfen Sie einen Blick auf die as_json() Methode. Sie fügen dies in Ihre Modelle ein, definieren Ihre json, und rufen dann einfach die render :json Methode und erhalten Sie, was Sie wollen.

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

Sie werden bemerken self.collections was eine Beziehung mit vielen ist. Dieses Modell hat auch as_json() definiert:

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

Dieser enthält self.monthly_views was eine weitere viele Beziehung darstellt.

Dann in Ihrem Controller:

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

2voto

Scott Messinger Punkte 159

Möglicherweise müssen Sie Ihre eigene Methode erstellen, um einen Hash zu generieren und dann den Hash in JSON umzuwandeln. Ich denke an etwas wie dieses:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X