Как мне обновить вложенные атрибуты документа Mongo в Rails с Mongoid?
-
25-09-2019 - |
Вопрос
(Заранее извиняюсь, если этот вопрос сокращается подробно, я буду смотреть комментарии и добавить, что я могу)
У меня есть модель со следующим:
class Product
include Mongoid::Document
include Mongoid::Timestamps
#...
field :document_template, :type => Document
accepts_nested_attributes_for :document_template
Внутри документа Document_template, это следующие ссылки_Мены, которые я хочу изменить. В частности, я хочу изменить, какие шрифты ссылаются:
class Document
include Mongoid::Document
include Mongoid::Timestamps
#...
references_many :fonts, :stored_as => :array, :inverse_of => :documents
Какую логику и детали я должен иметь в моем контроллере и форме, чтобы сделать это сделать? Пожалуйста, прокомментируйте, если вы хотите, чтобы я добавил некоторые из зани, которые я пробовал; Однако мне не повезло ни с кем из них.
Вот быстрый показ вопроса с использованием Rails Console:
# 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.
Обновление объектов с использованием Mongo (а не моноида в рельсах) работает как ожидалось.
Kyle Banker попросил некоторую информацию о лесозаготовке, так что здесь она есть. К сожалению, я не мог найти лучший источник регистрации, чем вывод с сервера Rails, который, кажется, предлагает вызов обновления никогда не производится. Для некоторого контекста здесь есть некоторая информация от контроллера:
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
Вот выход из сервера Rails, когда пост обрабатывается:
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
Похоже, команда mongodb для обновления font_ids полностью отсутствует ...
Решение
Я частично, чтобы вернуться Мульнговидная проблема # 357 вызывает проблему. Вышеупотешиваемое вход свидетельствует о том, что обновление для Document_template Product_template.fonts (или font_ids), которое, кажется, соответствует описанию ошибки.
(Sidenote: я немного запутался, где именно массив Font_IDS исходит, если нет: Stored_as =>: массив. Я не на 100%, что я должен изменять либо но Поскольку font_ids - это массив, а шрифты - это критерии mongoid ::, путь наименьшего сопротивления - font_ids.)
С точки зрения данных: поле и: Embeds_ *, кажется, похоже в том, что информация встроена в родительский документ.
Другие советы
Монгоид имеет сложный конец. Следовательно, самый простой способ диагностики этого - включить регистрацию водителя. Тогда мы можем посмотреть точные сообщения, отправляемые в базу данных в обоих случаях, и мы обязательно получим ответ.
Можете ли вы прикрепить регистратор при подключении к MongoDB, а затем опубликовать соответствующие разделы вывода журнала?