在Rails表单中处理MongoMapper EmbeddedDocument

时间:2011-04-28 10:52:58

标签: ruby-on-rails ruby forms mongodb mongomapper

首先,我是一般的新编程和Rails的新手。我选择了Rails,因为它似乎是一种简单的语言。对于我的项目,我正在使用带有Rails的MongoMapper。

我正在尝试以与文档相同的形式处理嵌入式文档。

我有以下型号:

class User
  include MongoMapper::Document

  key :email, String, :required => true
  key :first_name, String
  key :last_name, String
  key :role, String
  many :addresses
  timestamps!
end

class Address
  include MongoMapper::EmbeddedDocument

  key :location, String
  key :street, String
  key :city, String
  key :zip, Integer
  key :state, String
  key :country, String

end

我想在Document的同时创建/编辑EmbeddedDocument。我尝试过使用fields_for:

<% f.fields_for :address, @user.addresses do |address| -%>
  <div class="field">
    <%= address.label :street %><br />
    <%= address.text_field :street %>
  </div>
<% end %>   

但是我得到了

  

#&lt; \ Array的未定义方法`street':0x0000010126e3f8&gt;

提前谢谢。

2 个答案:

答案 0 :(得分:2)

如果您在fields_for上定义addresses_attributes=

User将有效。出于某种原因,如果您定义该方法,fields_for实际上会更改其行为。

以下是一个示例实现:

def addresses_attributes=(id_and_attrs)    
  id_and_attrs.each do |id, attrs|
    address = self.addresses.find(id) || self.addresses.build(:id => id)
    address.attributes = attrs
  end
end

未经测试,因此您必须解决问题。特别是,我不记得如果地址是全新的,因为用户是新的,嵌套参数是如何通过不同的方式进行的。

答案 1 :(得分:0)

据我所知,fields_for不包含对象的id,为此你需要添加一个隐藏的字段。

<%= address.hidden_field :id, :value => address.object.id %>

然后你的addresses_attributes =方法将如下所示:

def addresses_attributes=(addresses_attributes)    
  addresses_attributes.each do |index, attrs|
    address = self.addresses.find(attrs['id']) || self.addresses.build
    address.attributes = attrs
  end
end

感谢Brian,这为我遇到的类似问题提供了解决方案。