【问题标题】:Rails render_to_string using wrong formatRails render_to_string 使用错误的格式
【发布时间】:2017-03-28 02:02:28
【问题描述】:

我在使用 Rails 3.2.18 时遇到了 render_to_string 的问题,其中该函数试图呈现错误的视图格式,尽管它的 :formats 选项设置正确(例如,当 @ 时呈现 kml 视图987654324@ 设置为text)。


TL-DR 版本:

如果我先调用render_to_string('foos/bar', formats: 'text', layout: false),然后再调用render_to_string('foos/bar', formats: 'json', layout: false),则后者会呈现bar.text 而不是bar.json


加长版:

我有一个FoosControler,它在调用bar 操作时使用render_to_textbar 可以响应三种格式:textjsonkml。在我看来,我有三个对应的文件bar.text.erbbar.json.erbbar.kml.erb。我还有三个不同的测试,其中控制器被实例化,bar 的输出针对不同的格式进行测试(所以我调用FoosControler.new.bar(format))。

如果我独立运行每个测试,我完全没有问题。所以:

render_to_string('foos/bar', formats: 'text', layout: false)
# => renders bar.text.erb


render_to_string('foos/bar', formats: 'json', layout: false)
# => renders bar.json.erb


render_to_string('foos/bar', formats: 'kml', layout: false)
# => renders bar.kml.erb

如果我的测试套件中有多个这些问题,就会出现问题。会发生以下情况:

render_to_string('foos/bar', formats: 'json', layout: false)
# => renders bar.json.erb
render_to_string('foos/bar', formats: 'text', layout: false)
# => renders bar.text.erb
render_to_string('foos/bar', formats: 'json', layout: false)
# => renders bar.text.erb instead of bar.json.erb !

从我呈现bar.text.erb 的那一刻起,任何使用json 格式的render_to_string 调用都会呈现bar.text.erb 而不是bar.json.erb,就像它应该的那样。

kmltxt 之间也会发生同样的情况:

render_to_string('foos/bar', formats: 'text', layout: false)
# => renders bar.text.erb
render_to_string('foos/bar', formats: 'kml', layout: false)
# => renders bar.kml.erb
render_to_string('foos/bar', formats: 'text', layout: false)
# => renders bar.kml.erb instead of bar.text.erb !

我似乎无法理解为什么会发生这个问题,因为问题与视图无关 - 它们都存在并且可以如前所示呈现。更奇怪的是,如果我在渲染中强制使用格式而不是使用:format 参数,一切都会正常工作:

render_to_string('foos/bar.text', layout: false)
# => renders bar.text.erb
render_to_string('foos/bar.kml', layout: false)
# => renders bar.kml.erb
render_to_string('foos/bar.text', layout: false)
# => renders bar.text.erb like it is supposed to

其他一些精度:
- 我用formats: '<format>'还是formats: ['<format>']都没有关系
- 无论我是使用断点在同一控制器内使用不同的render_to_string,还是在测试中简单地调用FoosController.new.bar(format) 的序列,都会出现问题,因此以下两个给出相同的结果:

FoosController.new.bar
    render_to_string('foos/bar', formats: 'kml', layout: false)
    # => renders bar.kml.erb
    render_to_string('foos/bar', formats: 'text', layout: false)
    # => renders bar.kml.erb instead of bar.text.erb !


FoosController.new.bar('kml')
# => renders bar.kml.erb
FoosController.new.bar('text')
# => renders bar.kml.erb instead of bar.text.erb !

知道什么会导致这种不良行为吗?像我一样强制格式似乎可以解决问题,但我仍然想知道到底发生了什么。

【问题讨论】:

  • 也保留这个,但问题似乎是在 Rails 更新到 3.2.18 时出现的。听起来像是特定于版本的错误

标签: ruby-on-rails ruby-on-rails-3 rspec


【解决方案1】:

从此更改您的格式选项:

render_to_string('foos/bar', formats: 'text', layout: false)
# => renders bar.text.erb
render_to_string('foos/bar', formats: 'kml', layout: false)
# => renders bar.kml.erb
render_to_string('foos/bar', formats: 'text', layout: false)
# => renders bar.kml.erb instead of bar.text.erb !

到这里:

render_to_string('foos/bar', :formats => [:text], layout: false)
render_to_string('foos/bar', :formats => [:kml], layout: false)
render_to_string('foos/bar', :formats => [:text], layout: false)

【讨论】:

  • 我不敢相信解决方案如此简单。我仍然对为什么它不适用于文本版本感到困惑......猜猜我的格式上一个简单的to_sym 就可以了。
  • @Hyruu 这不仅仅是因为您尝试使用String,还因为它期待Arrayformats 参数是复数形式。
猜你喜欢
  • 2013-02-01
  • 2023-03-05
  • 2017-03-22
  • 2011-10-28
  • 2012-02-01
  • 2011-08-27
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多