我有一个名为custom
的字段,定义为NestedHstore:
# project.rb
serialize :custom, ActiveRecord::Coders::NestedHstore
我为此模型创建了用于测试的灯具:
one:
company: one
user: one
custom:
:name:
:prompt: 'What is your name?'
运行此操作时,嵌套的哈希值将保存为字符串,即@project.custom = {"name"=>"{:prompt=>\"What is your name?\"}"}
我通过添加prepare_custom
方法在单元和功能测试中解决了这个问题,该方法在任何运行之前从字符串手动重建嵌套哈希。
def prepare_custom(p)
if p.custom.present?
if p.custom.is_a? Hash
p.custom.each do |k,v|
if (v.class == String) && (v[0] == "{") && (v[-1] == "}")
p.custom[k] = eval(v)
end
end
end
p.save
p.reload
puts "*** project: #{p.inspect}"
end
end
当我运行集成测试时(使用Capybara / Poltergeist / Puma),会发生这种情况:
prepare_custom(@project)
似乎有效。最后的p.inspect
表明自定义是一个正确嵌套的哈希。prepare_custom
之后立即运行的集成测试代码似乎完全忽略项目已更改。它认为p.custom[:name]
再次是一个字符串。如何才能获得固定装置以正确保存嵌套哈希,或者让我的集成测试反映prepare_custom
中完成的工作?
在灯具中尝试:custom: <%= {name: { prompt: 'What is your name?'}}.to_yaml.inspect %>
后,我们得到:
ActiveRecord::StatementInvalid: ActiveRecord::StatementInvalid: PG::InternalError: ERROR: Syntax error near ':' at position 4
LINE 1: ...company_id") VALUES ('Simple prompt', 0, '---
^
: INSERT INTO "projects" ("name", "custom", "created_at", "updated_at", "id", "company_id") VALUES ('Simple prompt', '---
:name:
:prompt: What is your name?
', '2017-05-17 21:15:25', '2017-05-17 21:15:25', 159160234, 980190962, 159160234)