2

I’m having an issue rendering XML in the response body of a request in a Rails 4 application. In the example below the response body is blank. I’ve put a debugger in the template so I know it runs through it but doesn’t render anything out.

I created a simple rails app to demonstrate the issue I’m having using builder to return xml. Can anyone point me to the (probably stupid simple) problem with this example?

Here are the controller, template, and test:

controllers/bars_controller.rb

require 'builder'

class BarsController < ApplicationController
  before_action :set_bar, only: [:show]

  # GET /bars/1
  # GET /bars/1.json
  def show
    @xml = Builder::XmlMarkup.new
    render template: 'bars/show.xml.builder', formats: [:xml]
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_bar
      @bar = Bar.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def bar_params
      params.require(:bar).permit(:foo, :bar)
    end
 end

/views/bars/show.xml.builder

@xml.instruct!
@xml.bar do
  @xml.foo(@bar.foo)
  @xml.bar(@bar.bar)
end

/test/controllers/bars_controller_test.rb

 require 'test_helper'

 class BarsControllerTest < ActionController::TestCase
  setup do
    @bar = bars(:one)
  end

  test "should show bar" do
    get :show, id: @bar
    assert_response :success
    assert_match "<bar>", response.body
  end
 end

debugging session

     1: @xml.instruct!
     2: binding.pry
  => 3: @xml.bar do
     4:   @xml.foo(@bar.foo)
     5:   @xml.bar(@bar.bar)
     6: end

     [2] pry(#<#<Class:0x007fc669e9f610>>)> @xml.bar do
     [2] pry(#<#<Class:0x007fc669e9f610>>)*   @xml.foo(@bar.foo)  
     [2] pry(#<#<Class:0x007fc669e9f610>>)*   @xml.bar(@bar.bar)  
     [2] pry(#<#<Class:0x007fc669e9f610>>)* end  
      => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><bar><foo>MyString</foo><bar>MyString</bar></bar>"
2
  • does the entity you request in your test exist in the DB? Commented May 6, 2015 at 13:55
  • Yes. The test creates the entity and then displays it. If I debug the template then I can render the xml just fine manually in the debugging session. However, it doesn’t get pushed to the response.body. Commented May 6, 2015 at 13:58

1 Answer 1

7

It looks like creating the instance of the Builder::XmlMarkup.new is your problem. Remove the explicit creation of the builder so your controller looks like this:

def show
  # You can also simplify by removing "bars/"
  render 'bars/show.xml.builder', formats: [:xml]
end

And your view should look like this:

xml.instruct!
xml.bar do
  xml.foo(@bar.foo)
  xml.bar(@bar.bar)
end
Sign up to request clarification or add additional context in comments.

7 Comments

The first part of you answer doesn’t matter according to the Rails guides: guides.rubyonrails.org/….
The second part makes it work! Thanks! Now to figure out why. :-)
Yup, you're right -- red herring. I'm not super familiar with the XmlBuilder
Yes, I think the explicit creation of the XML builder is causing the issue. Thanks for the help.
These days, who is familiar with XmlBuilder? :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.