为rails编写元刷新方法

时间:2010-01-31 02:47:48

标签: ruby-on-rails ruby redirect

我想在app / controllers / application.rb中使用一个方法,该方法可以将文本添加/附加到呈现的任何模板中。当然,我无法调用渲染两次而没有得到双重渲染错误,所以这可能吗?

我希望在使用元刷新延迟后重定向。这就是我所拥有的:

应用/控制器/ application_controller.rb:

def redirect_after_delay (url, delay)
  @redirect_delay = delay
  @redirect_url = url
  render
end

应用/视图/布局/ application.html.erb

<!DOCTYPE html>
<html lang="en">
  <head>
    <%= yield :refresh_tag %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

那么如果我想添加一个延迟后的重定向,我将以下内容添加到1)我的控制器和2)动作的视图:
应用/控制器/ my_controller.rb

def my_action
  redirect_after_delay 'http://www.google.com', 3 if some_condition
end

应用/视图/ my_controller / my_action.html.erb

<% content_for :refresh_tag do %>
  <meta http-equiv='refresh' content='<%=@redirect_delay%>;url=<%=@redirect_url%>'>
<% end %>
<h1>Please wait while you are redirected...</h1>

由于content_for块永远不会更改,是否可以通过某种通用方式执行此操作,以便我不必在每个模板中放置<%= yield :refresh_tag %>? (例如,redirect_after_delay可以将其添加到要呈现的任何模板中吗?)

3 个答案:

答案 0 :(得分:1)

@aaronstacy

我一直在寻找相同的功能,所以我借鉴并改进了你的方法。简单地:

app / controllers / application_controller.rb中的

    def redirect_with_delay(url, delay = 0)
      @redirect_url, @redirect_delay = url, delay
      render
    end
app / views / layouts / application.html.erb中的

<html>
  <head>
    [snip...]
    <% if @redirect_url %>
    <meta http-equiv='refresh' content='<%= @redirect_delay -%>;url=<%= @redirect_url -%>'>
    <% end %>
    [snip...]
  </head>
  [etc...]

这使得redirect_with_delay()可以从任何控制器和任何视图中使用。像冠军一样工作 - 谢谢你的灵感。

答案 1 :(得分:1)

您不需要在HTML中放置任何内容,并且担心模板。元标记与HTTP标头等效,使用Rails非常容易发送,例如在你的控制器中:

def my_action
  header['Refresh'] = "5"
  render :my_view
end

或者你可以将它重构为ApplicationController

中的方法
def redirect_after_relay(url, delay)
  header['Refresh'] = "#{delay}; url=#{url}"
end

答案 2 :(得分:0)

一个想法是在application_controller.rb中使用after_filter来添加元刷新标记,如果合适的话。

def after_filter
  if @redirect_url and @refresh_delay
    # update controller.response.body to add meta refresh tag
  end
end

我不确定这会像使用yield :refresh_tag一样高效,因为您需要解析HTML以在meta标记之后插入head标记,但它是可行的调查方法。

另一个想法是将您的标题HTML放在部分中,然后将其包含在其他页面中。 e.g。

标题部分:

<!DOCTYPE html>
<html lang="en">
  <head>
    <%= yield :refresh_tag %>
  </head>

页脚部分:

</html>