Sinatra + Mongoid更新嵌入式文档

时间:2014-02-19 20:57:18

标签: ruby sinatra mongoid mongoid3

我在使用Sinatra 1.4.4和Mongoid 3.1.5一次更新文档及其嵌入文档时遇到问题。就目前而言,嵌入式文档不会被修改,只是采用嵌套属性并将它们添加到父级别。

假设:

给出如下形式:

<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>

像这样的模型:

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

文件如:

{
  name: "Default Name",
  address: {
    _id: ObjectId("52fc501f266d9841d000007c"),
    street: "Default Street"
  },
}

最后,这样的路线:

post '/persons/edit/:id' do |id|
  p = Persons.find(id)
  p.update_attributes params
end

结果

我希望该文件最终成为:

{
  name: "Some Guy", //this is okay
  address: {
    _id: ObjectId("52fc501f266d9841d000007c"),
    street: "Evergreen Street"
  }
}

但最终得到:

{
  name: "Some Guy", //this is okay
  address: {
    _id: ObjectId("52fc501f266d9841d000007c"),
    street: "Default Street" //not changed
  },
  street: "Evergreen Street" //WTF?
}

我知道我做错了什么,但对于我的生活,我看不出是什么。我觉得奇怪的是,如果我将表单上的name属性从使用括号更改为点(例如address.street),则更新有效,但Sinatra无法将参数识别为Hash ,而只是整个params中的一个键。

有关如何解决此问题的任何想法?我错过了什么吗?

感谢您帮助我!

1 个答案:

答案 0 :(得分:2)

我想,您在embedded_in文档中没有指定Address关系的问题。 我建议您使用polymorphic行为的常规做法 - http://mongoid.org/en/mongoid/docs/relations.html#common(多态)