Wie kann ich aktualisieren Nested Mongo Dokumentattribute in Rails mit Mongoid?
-
25-09-2019 - |
Frage
(Apologies im Voraus, wenn diese Frage auf Details kurz ist, werde ich die Kommentare sehen und fügen Sie, was ich kann)
Ich habe ein Modell mit dem folgenden:
class Product
include Mongoid::Document
include Mongoid::Timestamps
#...
field :document_template, :type => Document
accepts_nested_attributes_for :document_template
Im Inneren des Document document_template ist die folgende references_many, die ich ändern möchten. Insbesondere möchte ich ändern, welche Schriften verwiesen werden:
class Document
include Mongoid::Document
include Mongoid::Timestamps
#...
references_many :fonts, :stored_as => :array, :inverse_of => :documents
Was für eine Art von Logik und Details soll ich in meinem Controller und Form dies zu tun bekommen? Bitte kommentieren Sie, wenn Sie möchten, dass ich einige der verrückten Dinge hinzuzufügen, die ich habe versucht; aber ich habe nicht hatte kein Glück mit einem von ihnen.
Hier ist eine kurze Darstellung des Problems mit Schienen Konsole:
# Grab a Product and check how many fonts are in it's document_template
ruby-1.8.7-p302 > prod = Product.find(:first)
=> ...
ruby-1.8.7-p302 > prod._id
=> BSON::ObjectId('4d06af15afb3182bf5000111')
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 9
# Remove a font from the font_ids array
ruby-1.8.7-p302 > prod.document_template.font_ids.pop
=> BSON::ObjectId('...') # This font id was removed from font_ids
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 8
# Save the changes
ruby-1.8.7-p302 > prod.document_template.save!
=> true
ruby-1.8.7-p302 > prod.save!
=> true
# Instantiate a new product object of that same product
ruby-1.8.7-p302 > prod_new = Product.find(:first)
=> ...
# Confirm the _ids are the same
ruby-1.8.7-p302 > prod._id == prod_new._id
=> true
# Check to see if the changes were persisted
ruby-1.8.7-p302 > prod_new.document_template.font_ids.count
=> 9 # If the changes persisted, this should be 8.
# Grrrrr... doesn't look like it. Will the change disappear after a reload too?
ruby-1.8.7-p302 > prod.reload
=> ...
ruby-1.8.7-p302 > prod.document_template.font_ids.count
=> 9
# ಠ_ಠ ... no dice.
Aktualisieren von Objekten Mongo mit (und mongoid nicht in Schienen) wie erwartet funktioniert.
Kyle Banker hat für einige Logging Informationen gefragt, so ist es hier. Leider konnte ich nicht eine bessere Quelle der Protokollierung als die Ausgabe von Schienen-Server finden, das der Update Aufruf vorzuschlagen scheint nie gemacht. Aus irgendeinem Zusammenhang hier einige Informationen von der Steuerung:
def update_resource(object, attributes)
update_pricing_scheme(object, attributes)
update_document_template_fonts(object, attributes)
end
def update_document_template_fonts(object, attributes)
document_template = object.document_template
document_template_attributes = attributes[:document_template_attributes]
font_ids = document_template_attributes[:font_ids]
font_ids.delete("") # Removing an empty string that tags along with the font_ids.
font_ids.collect! { |f| BSON::ObjectId(f) } # Mongo want BSON::ObjectId
object.document_template.font_ids.replace font_ids
object.document_template.save!(:validate => false)
object.save!(:validate => false)
end
Dies ist die Ausgabe von Schienen-Server, wenn der POST verarbeitet wird:
Started GET "/admin/products/4d091b18afb3180f3d000111" for 127.0.0.1 at Wed Dec 15 13:57:28 -0600 2010
Started POST "/admin/products/4d091b18afb3180f3d000111" for 127.0.0.1 at Wed Dec 15 13:57:49 -0600 2010
Processing by Admin::ProductsController#update as HTML
Parameters: {"commit"=>"Update Product", "authenticity_token"=>"QUW0GZw7nz83joj8ncPTtcuqHpHRtp1liq8fB7/rB5s=", "utf8"=>"✓", "id"=>"4d091b18afb3180f3d000111", "product"=>{"name"=>"Ho Ho Ho Flat Multiple Photo Modern Holiday Card", "document_template_attributes"=>{"id"=>"4d091b18afb3180f3d000112", "font_ids"=>["", "4d091b17afb3180f3d000023"]}, "description"=>"", "pricing_scheme_id"=>"4d091b17afb3180f3d00003b"}}
development['users'].find({:_id=>BSON::ObjectId('4d091b17afb3180f3d00009b')}, {}).limit(-1)
development['products'].find({:_id=>BSON::ObjectId('4d091b18afb3180f3d000111')}, {}).limit(-1)
development['pricing_schemes'].find({:_id=>BSON::ObjectId('4d091b17afb3180f3d00003b')}, {}).limit(-1)
MONGODB development['products'].update({"_id"=>BSON::ObjectId('4d091b18afb3180f3d000111')}, {"$set"=>{"updated_at"=>Wed Dec 15 19:57:50 UTC 2010}})
in Document#set_default_color_scheme: self.color_scheme = #<ColorScheme:0xb52f6f38>
MONGODB development['documents'].update({"_id"=>BSON::ObjectId('4d091b18afb3180f3d000112')}, {"$set"=>{"color_scheme_name"=>"green_charcoal_black", "updated_at"=>Wed Dec 15 19:57:50 UTC 2010}})
Redirected to http://localhost:3000/admin/products/4d091b18afb3180f3d000111
Completed 302 Found in 49ms
Es sieht aus wie der MongoDB Befehl, um die font_ids zu aktualisieren ist völlig abwesend ...
Lösung
Ich bin teilweise zu glauben Mongoid Issue # 357 das Problem verursacht. Die Protokollierung schlägt oben, dass ein Update für das document_template.fonts Produkt (oder font_ids), die den Fehler Beschreibung zu passen scheint.
(Nebenbei bemerkt: Ich bin ein bisschen verwirrt, wo genau das font_ids Array herkommt, wenn nicht die: stored_as =>. Array Ich bin nicht 100% sicher, was ich sollte entweder zu modifizieren und da font_ids ist ein Array und Schriftarten ist ein Mongoid :: Kriterien, den Weg des geringsten Widerstandes ist font_ids.)
Aus daten Sicht: Feld und:. Embeds_ * scheinen in ähnlich zu sein, dass die Informationen in der übergeordneten Dokument eingebettet ist,
Andere Tipps
Mongoid hat ein kompliziertes Back-End. Daher ist der einfachste Weg, dies zu diagnostizieren ist der Fahrer Protokollierung zu aktivieren. Dann können wir die genauen Nachrichten suchen in beiden Fällen an die Datenbank gesendet werden, und wir sind sicher, eine Antwort zu bekommen.
Können Sie befestigen einen Logger, wenn Sie MongoDB verbinden und dann schreiben die entsprechenden Abschnitte der Protokollausgabe?