I am encountering a problem with render_to_string
using Rails 3.2.18 in which the function is trying to render the wrong view format despite its :formats
option being correctly set (so for example rendering the kml
view when :formats
is set to text
).
TL-DR version :
If I call render_to_string('foos/bar', formats: 'text', layout: false)
and then render_to_string('foos/bar', formats: 'json', layout: false)
, the later renders bar.text
instead of bar.json
Long version :
I have a FoosControler
that uses render_to_text
when its bar
action is called. bar
can respond to three formats : text
, json
and kml
. Under my views, I have the three corresponding files bar.text.erb
, bar.json.erb
and bar.kml.erb
. I also have three different tests, in which the controller is instantiated and the output of bar
is tested for the different formats (so I am calling FoosControler.new.bar(format)
).
If I run each of those tests independently, I have no problems at all. So :
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
The problems start if I have more than one of these in my test suite. What happens is the following :
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 !
From the moment I rendered bar.text.erb
, any call to render_to_string
with the json
format renders bar.text.erb
instead of bar.json.erb
like it is supposed to.
The same happens between kml
and txt
:
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 !
I can't seem to understand why this problem happens, as the problem isn't linked to the views - they all exist and can be rendered as shown before. Even stranger, everything works if I force the format in the render instead of using the :format
parameter :
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
A few other precisions :
- It doesn't matter whether I use formats: '<format>'
or formats: ['<format>']
- The problem happens regardless of whether I use the different render_to_string
inside the same controller using a breakpoint or whether I simply call the sequence of FoosController.new.bar(format)
in the test, so the following two give the same result :
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 !
Any idea what can cause this unwanted behavior ? Forcing the format like I did seems to patch the issue, but I'd still want to know what exactly is going on.
Aucun commentaire:
Enregistrer un commentaire