0

我有一个带有 mongoid 的 Rails 4.2 应用程序,我在其中导入带有测试结果的 csv 文件。我无法定义模型中的所有字段,因为它们会随着测试而变化,并且总是大约有 700 个。我使用动态属性并且导入和显示工作正常。

我正在尝试使用 attribute_names 方法来获取所有属性名称,但我得到的只是模型中定义的那些。如果我没有在模型中定义任何东西,它只会返回“_id”。另一方面,attributes 方法可以看到实际文档中的属性。

>> @results.first.attributes.count
=> 763
>> @results.first.attribute_names
=> ["_id"]

我也试过fields.keys,同样的问题

>> @results.first.fields.keys
=> ["_id"]

我现在的模型看起来像这样

class Result
  include Mongoid::Document
  include Mongoid::Attributes::Dynamic

  def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|
        Result.create! row.to_hash
    end
  end
end

有人可以解释如何使它工作吗?

非常感谢任何帮助。

4

1 回答 1

0

这部分在文档中不是很清楚。而这个答案并没有解决你如何让你的案例有效(我真的不知道)......但它最后有一个猴子补丁......

我所知道的是为什么这个案子不起作用......

正如文件所述

处理动态属性时,适用以下规则:

如果文档中存在该属性,Mongoid 将为您提供标准的 getter 和 setter 方法。

例如,考虑一个在文档上设置了“性别”属性的人:

# Set the person's gender to male.
person[:gender] = "Male"
person.gender = "Male"

# Get the person's gender.
person.gender

这不是你的情况......因为看起来你没有在模型中定义任何属性......

适用于您的情况(根据您显示的代码和您描述的问题)

如果文档中不存在该属性,

Mongoid 不会为您提供 getter 和 setter,并将强制执行正常method_missing行为。

在这种情况下,您必须使用其他提供的访问器方法:( []and []=) 或 ( read_attributeand write_attribute)。

# Raise a NoMethodError if value isn't set.
person.gender
person.gender = "Male"

# Retrieve a dynamic field safely.
person[:gender]
person.read_attribute(:gender)

# Write a dynamic field safely.
person[:gender] = "Male"
person.write_attribute(:gender, "Male")

如您所见... mongoid 无法在运行时添加 setter 和 getter 方法...

猴子补丁

  • 您可以在文档中添加一个字段(可能是字符串、数组、哈希、任何适合您的)(属性存在于文档中)
  • 从 CSV 行填充文档.. 只需保存该字段中 CSV 的字段是什么...(在其中保存 CSV 键)
  • 使用您的预定义字段(包含密钥)而不是使用.keys.

您的情况下的代码示例。

class Result
  include Mongoid::Document
  include Mongoid::Attributes::Dynamic

  field :the_field_that_holds_the_keys, type: Array
  # ...
end

在你的控制器中:

@results.first.some_attribute
#=> method missing error
@results.first[:some_attribute]
#=> some_value
@results.first.the_field_that_holds_the_keys
#=> [:some_attribute, :some_other_attribute, :yada]
于 2015-04-16T20:32:00.723 回答