написание метода метаобновления для рельсов

Мне нужен метод в app/controllers/application.rb, который может добавлять/добавлять текст к любому отображаемому шаблону. Конечно, я не могу дважды вызывать рендеринг без двойной ошибки рендеринга, возможно ли это?

Я хочу перенаправить после задержки, используя метаобновление. Вот что у меня есть:

приложение/контроллеры/application_controller.rb:

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

app/views/layouts/application.html.erb

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

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

Итак, если я хочу добавить перенаправление после задержки, я добавляю следующее к 1) моему контроллеру и 2) представлению действия:
app/controllers/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 добавить его в любой шаблон, который будет отображаться?)


person aaronstacy    schedule 31.01.2010    source источник
comment
да, я переформатировал его, так что вопрос теперь наверху   -  person aaronstacy    schedule 01.02.2010


Ответы (3)


Одна из идей состоит в том, чтобы использовать after_filter в application_controller.rb для добавьте метатег обновления, если это необходимо, например.

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-код вашего заголовка в партиал, который вы затем включите в свои другие страницы. например

Частичный заголовок:

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

Частичный нижний колонтитул:

</html>
person mikej    schedule 31.01.2010
comment
да, я думаю, что, возможно, я пытаюсь сделать это слишком сложным, я, вероятно, добавлю что-то в макет. спасибо за ваш вклад! - person aaronstacy; 01.02.2010

@aaronstacy

Я искал ту же функциональность, поэтому я позаимствовал и усовершенствовал ваш подход. Просто:

в приложении/контроллеры/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() доступным с любого контроллера и в любом представлении. Работает как чемпион -- спасибо за вдохновение.

person fearless_fool    schedule 30.12.2010

Вам не нужно ничего вставлять в 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
person Matthew Bloch    schedule 27.04.2015
comment
по крайней мере, в рельсах 4 это headers - person Fallenhero; 02.01.2017