I guess, the problem that you didn't specify embedded_in
relation in Address
document.
I suggest you use common practice for polymorphic
behavior - http://mongoid.org/en/mongoid/docs/relations.html#common (Polymorphism)
Sinatra + Mongoid update embedded document
Question
I'm having issues updating both a document and its embedded document on one go with Sinatra 1.4.4 and Mongoid 3.1.5. As it stands, the embedded document is not modified, but just takes the nested attributes and adds them to the parent level.
Assumptions:
Given a form such as:
<form action="/persons/edit/52cad9f0d2a57d2ded000070 method="post">
<input name="name" value="Some Guy" />
<input name="address[street]" value="Evergreen Street" />
<button type="submit">Save</button>
</form>
A model like:
class Person
include Mongoid::Document
include Addressable
accepts_nested_attributes_for :address
field :name, type: String
end
class Addressable
extend ActiveSupport::Concern
included do
embeds_one :address, class_name: 'Address', cascade_callbacks: true
end
end
class Address
include Mongoid::Document
field :street, type: String
before_save :strip_whitespace
def remove_whitespace
attributes.each do |attr_name, value|
next unless value.is_a? String
send("#{attr_name}=", value.strip.gsub(/\s(\s+)/, ' '))
end
end
end
A document such as:
{
name: "Default Name",
address: {
_id: ObjectId("52fc501f266d9841d000007c"),
street: "Default Street"
},
}
And finally, a route like so:
post '/persons/edit/:id' do |id|
p = Persons.find(id)
p.update_attributes params
end
Results
I expect the document to end up as:
{
name: "Some Guy", //this is okay
address: {
_id: ObjectId("52fc501f266d9841d000007c"),
street: "Evergreen Street"
}
}
But instead end up with:
{
name: "Some Guy", //this is okay
address: {
_id: ObjectId("52fc501f266d9841d000007c"),
street: "Default Street" //not changed
},
street: "Evergreen Street" //WTF?
}
I know I'm doing something wrong, but for the life of me, I can't see what. I find weird that if I change the name
attribute on my forms from using brackets to dots, such as address.street
, the update works, but Sinatra doesn't recognize the parameter as a Hash
, but rather just a key within the whole params
.
Any ideas on how to fix this? Am I missing something?
Thanks for helping me out!
Solution