为什么Rails没有正确地转换我的灯具中的转义字符串?

时间:2016-06-20 04:36:50

标签: ruby-on-rails ruby

我有一个奇怪的事情,我试图更新到Ruby 2.3.1,但现在测试失败了。失败的测试似乎是破坏的数据在Rails装置中,而不是真正的失败。

在灯具中,我有:

one:
  name: "\u30C6\u30B9\u30C8"

当我在控制台中查看此值时,似乎已经双重转义:

irb(main):001:0> Organisation.first.name
  Organisation Load (0.1ms)  SELECT  "organisations".* FROM "organisations"  ORDER BY "organisations"."id" ASC LIMIT 1
=> "\\u30C6\\u30B9\\u30C8"

这也是我在调试测试时看到的。

到目前为止已知:

  • 如果我降级回Ruby 2.1.2,我会看到正确的非转义值。
  • 如果我降级到Ruby 2.2.2,问题仍然存在。
  • 如果我在Ruby 2.3.1上使用YAML.load加载完全相同的文件,我会看到正确的非转义值。
  • 如果我创建一个全新的Rails应用程序并复制完全相同的夹具线,我会看到正确的非转义值。

这可能会发生什么?是否有其他宝石干扰解析YAML,但只有在使用Rails用于加载灯具时加载?即使YAML.load看起来工作正常,Rails如何加载固定装置使其无效?

Rails是版本4.2.6。

正在使用的其他宝石:

gem 'rails', '~> 4.2.0'

gem 'sqlite3'
gem 'mysql2', platforms: %w( ruby )

group :development do
  gem 'capistrano', git: 'git://github.com/trejkaz/capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-rbenv'
end

gem 'uglifier'
gem 'execjs'
gem 'therubyracer'

group :development, :test do
  gem 'byebug'
end

gem 'rails3-restful-authentication', require: 'restful_authentication'
gem 'strip_attributes'
gem 'dynamic_form'
gem 'will_paginate'
gem 'acts_as_list'
gem 'jquery-tokeninput-rails'
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'exception_notification', '~> 4.0.0'
gem 'syck', '~> 1.0.0'

group :development, :test do
  gem 'simplecov'
  gem 'ci_reporter_minitest'
  gem 'mocha'
  gem 'metric_fu'
  gem 'flog', '~> 4.3.2'
end

在ActiveRecord中挖掘,低级夹具读取代码肯定是以某种方式做错了...

irb(main):014:0> ActiveRecord::FixtureSet::File.open('test/fixtures/organisations.yml') { |fh| fh.each { |fixture_name, row| puts fixture_name; puts row } }
one
{"name"=>"\\u30C6\\u30B9\\u30C8"}
=> [["one", {"name"=>"\\u30C6\\u30B9\\u30C8"}]]

加载YAML的行为取决于你只是加载irb,还是使用rails控制台...所以它看起来像环境中的其他东西会以某种方式混淆读取YAML。 :(

$ irb
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> YAML.load_file('test/fixtures/organisations.yml')
=> {"six"=>{"name"=>"テスト"}}
irb(main):003:0> 

$ bundle exec rails console
Loading development environment (Rails 4.2.6)
irb(main):001:0> YAML.load_file('test/fixtures/organisations.yml')
=> {"six"=>{"name"=>"\\u30C6\\u30B9\\u30C8"}}
irb(main):002:0> 

1 个答案:

答案 0 :(得分:1)

我会责怪syck - 这是来自pre ruby​​ 1.9.3的yaml解析器(尽管我认为它仍然可以在以后的版本中使用,而不是默认值)可以作为依赖它的人的宝石。引用gem的自述文件中的“问题”部分

  

Monkeypatches废话

除非你有一些非常特殊的遗留代码,否则你几乎肯定不需要它。它的替代(心理)是ruby标准库的一部分。