需要一个真正聪明的铁轨助手

时间:2010-03-07 20:45:53

标签: ruby-on-rails ruby

在我的rails应用程序中,我有一个辅助函数:

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

如果我用“

”将页面称为“主页”
<%= render_page :home %>

和“home”页面的正文是:

<h1>Home<h1/>
bla bla

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

我会得到“主页”页面,“关于”和“联系”,这很简单......直到有人去的地方并将“主页”的内容更改为:

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

将导致无限循环(webrick上的段错误)......

如何将辅助函数更改为不会陷入此陷阱的内容?

我的第一次尝试是:

@@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

对我的开发环境起作用,但在生产中遭到轰炸......

有什么建议吗?

谢谢你 斯蒂芬

2 个答案:

答案 0 :(得分:1)

@@变量在请求中保持不变。如果render_page引发异常,它将在@@ list中保留值,并可能导致后续请求的奇怪行为。试试这个:@list是视图的一个实例变量,它的作用域是请求。

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

答案 1 :(得分:0)

您是在复制粘贴,还是已编辑过任何内容?

如果没有,这里似乎有一个错字:

unless list.include?(permalink)

我认为你的意思是:

unless @@list.include? permalink

希望这会有所帮助。如果没有,请激活生产日志,以便您可以看到错误的确切位置(您可以在config / environments / production.rb文件中执行此操作)。如果您在问题中粘贴错误,您将获得更好的帮助。

编辑:此外,如果您从列表中删除固定链接(@@list -= [ permalink ]),我相信if-else的第二部分永远不会发生(您永远不会得到“此页面已被呈现”消息)。而且,@@list -= ...并不完全有效。您可能希望代替@@list.delete(permalink)@@list.push(permalink)代替@@list += ...