开发者

A really smart rails helper needed

In my rails application I have a helper function:

def render_page( permalink )
   page = Page.find_by_permalink( permalink )
   content_tag( :h3, page.title ) + inline_render( page.body )
end

If I called the page "home" with:

<%= render_page :home %>

and "home" page's body was:

<h1>Home<h1/>
bla bla

<%= render_page :about %>
<%= render_page :contact %>

I would get "home" page, with "about" and "contact", it's nice and simple... right up to where someone goes and changes the "home" page's content to:

<h1>Home<h1/>
bla bla
<%= render_page :home %>    
<%= render_page :about %>
<%= render_page :contact %>

which will result in a infinite 开发者_如何学编程loop ( a segment fault on webrick )...

How would I change the helper function to something that won't fall into this trap?

My first attempt was along the lines of:

@@list = []

def render_page( permalink )
  unless @@list.include?(permalink)
    @@list += [ permalink ]
    page = Page.find_by_permalink
    result = content_tag( :h3, page.title ) + inline_render( page.body )
    @@list -= [ permalink ]
    return result
  else
    content_tag :b, "this page is already being rendered"
  end
end

which worked on my development environment, but bombed out in production...

any suggestions?

Thank You

Stefan


@@ variables persist across requests. If render_page threw an exception, it would leave values in @@list and probably cause weird behavior for subsequent requests. Try this: @list is an instance variable for the view and is scoped to the request.

def render_page( permalink )
  @list ||= []
  unless @list.include?(permalink)
    @list << permalink
    page = Page.find_by_permalink
    result = content_tag( :h3, page.title ) + inline_render( page.body )
    @list.delete permalink
    return result
  else
    content_tag :b, "this page is already being rendered"
  end
end


Are you copy-pasting, or have you edited anything out?

If not, there seems to be a typo here:

unless list.include?(permalink)

I think you meant:

unless @@list.include? permalink

Hope this helps. If it doesn't, activate the logs on production so you can see where the error is exactly (you can do this on the config/environments/production.rb file). If you paste the errors in your question, you will get better help.

EDIT: Also, if you remove the permalink from the list (@@list -= [ permalink ]) I believe the second part of your if-else will never happen (you will never get a "this page is already being rendered" message). Moreover, @@list -= ... isn't exactly efficient. You might want to do @@list.delete(permalink) instead - and @@list.push(permalink) instead of the @@list += ... .

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜