代码之家  ›  专栏  ›  技术社区  ›  Stefan

需要一个真正的智能Rails助手

  •  1
  • Stefan  · 技术社区  · 16 年前

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

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

    如果我将页面称为“主页”,则使用:

    <%= render_page :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 回复  |  直到 16 年前
        1
  •  1
  •   Kevin    16 年前

    @@变量在请求之间保持不变。如果呈现页面引发异常,它将在@@列表中保留值,并可能导致后续请求出现异常行为。尝试此操作:@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
    
        2
  •  0
  •   kikito    16 年前

    你是复制粘贴,还是编辑了什么?

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

    unless list.include?(permalink)
    

    我想你的意思是:

    unless @@list.include? permalink
    

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

    编辑:另外,如果从列表中删除永久链接( @@list -= [ permalink ] )我相信你的第二部分,如果其他的永远不会发生(你永远不会得到一个“这页已经被呈现”的消息)。此外, @@list -= ... 效率不高。你可能想这么做 @@list.delete(permalink) 而是—— @@list.push(permalink) 而不是 @@list += ... .

    推荐文章