John Judd
John Judd

Reputation: 760

Rails Query Returns Results First Time Only

I'm having an unusual problem in an application I am developing.

I am writing a controller/view to generate a sitemap.xml resource. It works perfectly the first time I test it by viewing it in the browser.

However the second time, when I refresh the view, no page results are returned and the sitemap is effectively empty.

If I make a change to the code. It could be as little as adding a blank line, or removing it, then the sitemap is correctly generated the first time. Any additional refreshes are empty.

This is the code:

The sitemap controller

class SitemapController < ApplicationController
    layout nil

    def index
        @pages = Page.where(:publish => true)
        @base_url = "http://#{request.host_with_port}"
        headers['Content-Type'] = 'application/xml'
        def index
            respond_to do |format|
                format.xml
            end
        end
    end
end

Here is sitemap.xml.erb

<?xml version="1.0" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<% @pages.each do |page| %>
  <url>
    <loc><%= "#{@base_url}/#{page.permalink}" %></loc>
    <lastmod><%= page.updated_at %></lastmod>
    <priority>0.5</priority>
  </url>
<% end unless @pages.nil? %>
</urlset>

and the route

match "/sitemap.xml", :to => "sitemap#index", :defaults => {:format => :xml}

The odd thing is that it seems to be in the query in the controller.

@pages = Page.where(:publish => true)

This returns nil on consecutive attempts, but a similar query in other parts of the app works every time. I have tried using alternative methods such as Page.all, and Page.find :all but the problem persists.

I also uploaded this to the app on Heroku, wondering if it was something in my environment, but it happens there also.

Upvotes: 1

Views: 101

Answers (1)

willglynn
willglynn

Reputation: 11520

Your SitemapController#index method is redefining itself. To clarify the problem:

def fn
  def fn
    2
  end
  1
end

fn
# => 1
fn
# => 2

Try instead:

class SitemapController < ApplicationController
    layout nil

    def index
        @pages = Page.where(:publish => true)
        @base_url = "http://#{request.host_with_port}"
        headers['Content-Type'] = 'application/xml'
        respond_to do |format|
            format.xml
        end
    end
end

Also, the sitemap_generator gem works rather well.

Upvotes: 3

Related Questions