如何在 Mongoid & Rails 中使用数组字段?

Posted

技术标签:

【中文标题】如何在 Mongoid & Rails 中使用数组字段?【英文标题】:How do I work with array fields in Mongoid & Rails? 【发布时间】:2012-01-09 20:41:14 【问题描述】:

我有一个包含两个字段的地点模型:

class Place
  include Mongoid::Document

  field :name, :type => String
  field :loc, :type => Array

  index([[:loc, Mongo::GEO2D]], :background => true)

  validates_presence_of :name
end

我可以轻松地在我的视图中输出纬度和经度:

@place.loc['lat']

MongoDB 中代表每个地方的记录如下所示:

 "_id" : ObjectId( "0293uhjf2hfio2h3" ),
  "name" : "Starbucks",
  "loc" : 
    "lat" : 44.106667,
    "lon" : -73.935833
  

我的问题是如何创建允许我编辑或创建新位置(纬度/经度)字段的表单?

【问题讨论】:

就像任何其他形式一样。有问题吗? 如果我创建一个名为 place[loc][lat] 的输入字段,那么控制器的更新操作会返回错误:“字段被定义为一个(n)数组,但收到了一个 ActiveSupport: :HashWithIndifferentAccess 与值”。如果我将 loc 的数据类型更改为 Hash,那么即使我尝试更改名称字段,也不会发生任何事情。控制器确实说该地点已成功更新,尽管它没有。 经过更长时间的挖掘,我发现 update_attributes 并没有真正更新属性,即使有个新属性。如果我手动更改值并调用 place.save 它可以工作。但这是一个非常糟糕的解决方案......所以,我会继续寻找。 【参考方案1】:

我找到了解决方案。我没有在 place 模型中设置字段,而是创建了另一个名为“loc”的模型并在适当位置添加了“embeds_one :loc”。所以地方模型现在看起来像这样:

class Place
  include Mongoid::Document
  field :name

  index([[:loc, Mongo::GEO2D]], :background => true)

  embeds_one :loc
  validates_presence_of :name
end

现在 loc 模型看起来像这样:

class Loc
  include Mongoid::Document

  field :lat, :type => Integer
  field :lon, :type => Integer

  embedded_in :place
end

所以,现在我可以在表单中输入位置字段了:

<input type="text" name="place[loc][lat]" id="place_loc_lat">

【讨论】:

以上是关于如何在 Mongoid & Rails 中使用数组字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何将内存中的 MongoDB 与 Rails、Mongoid 和 Rspec 一起使用?

如何在现有的rails模型中使用mongoid来种植数据?

如何避免在 MongoDB(使用 Mongoid)或 ActiveRecord(使用 MySQL 的 Rails)中插入两次相同的记录?

Rails,mongoid,heroku 性能

Mongoid(Rails)中的两个 1 - N 关系

如何使用 mongoid、rails 和谷歌地图搜索“附近的用户”