ruby-on-rails - rails 6 : form with remote: true and Turbolinks not showing flash after redirect

标签 ruby-on-rails simple-form turbolinks ujs ruby-on-rails-6

我有 <%= simple_form_for @offer, remote: true %>启用 Turbolinks。我正在尝试在我的 update 中使用类似这样的内容重定向并显示成功 Flash Action :

respond_to do |format|
  if @offer.update(offer_params)
    flash[:success] = "#{@offer.name} #{t(:updated)}"
    format.html { redirect_to seller_offers_path }
    format.js
  else
    format.html { render :edit }
  end
end

我的 update.js.erb具有与重定向或闪存无关的代码:

$(".ibox-content.actions").removeClass('sk-loading');
$('.sk-spinner').css("display", "none");

在 application.html.erb 中,我可以用这个渲染 flash:

<div class="row">
  <% flash.each do |message_type, message| %>
     <%= content_tag(:div, content_tag(:strong, message), id: "flash_message",
                   class: "text-bold alert alert-#{message_type}") %>
  <% end %>
</div>

目前我的表单已保存,但没有重定向。

当我添加 Turbolinks.visit(<%= seller_offers_path %>) 时在 update.js.erb表单已保存,重定向已完成,但是没有 flash。

有没有办法让我使用 Turbolinks 和 remote: true 在重定向页面上显示 Flash? ,好吗? 到目前为止,我已经试过了 this suggestion , 但它只适用于在同一页面上显示 flash - 它不适用于 redirect_to .

更新

这会重定向,但不会出现 flash:

respond_to do |format|
  if @offer.update(offer_params)
    format.js { redirect_to seller_offers_path, success: "#{@offer.name} #{t(:updated)}" }
  else
    format.html { render :edit }
  end
end

更新 2

目前我正在尝试实现类似 Turbolinks.visit(url, { keep: 'flash' });作为mentioned in docs ,但是似乎不适用于 Turbolinks 5.2

更新 3

我已经删除了 update.js.erb在我的 Controller 中我有

def update
  if @offer.update(offer_params)
    flash[:success] = "#{@offer.name} #{t(:updated)}"
    redirect_to seller_offers_path
  else
    render :edit
  end
end

重定向按预期完成,但 index 上仍未显示 flash .我可以在 update 的末尾打印我的 flash Action :

#<ActionDispatch::Flash::FlashHash:0x00007f180d2a1c60 @discard=#<Set: {}>, @flashes={"success"=>"My offer updated!"}, @now=nil>

但是在 index 的末尾 Action (我重定向到的地方)是空的:

#<ActionDispatch::Flash::FlashHash:0x00007f180eb3b780 @discard=#<Set: {}>, @flashes={}, @now=nil>

看起来我的闪存没有为下一个请求保留。是因为 Turbolinks,还是其他原因?我很乐意提供任何提示。

最佳答案

远程表单提交后重定向

当您使用通过 JS 提交的表单时(例如 remote: true 或默认的 form_with),Rails 将查找并呈现传统的 js 响应(在本例中为 offers/update.js.erb)并忽略任何其他响应,例如 html 重定向。

您原来的 update.js.erb 不包含任何代码来执行对重定向位置的访问,因此它只删除了类名并隐藏了微调器。

如您所知,js 响应需要对重定向位置进行 Turbolinks 访问。在提交表单后清除 Turbolinks 缓存也是一个好主意,因此您的 update.js.erb 可能看起来像:

$(".ibox-content.actions").removeClass('sk-loading');
$('.sk-spinner').css("display", "none");
Turbolinks.clearCache();
Turbolinks.visit(<%= seller_offers_path %>);

如果您安装了 turbolinks-rails gem,并且不需要像上面的前两行那样运行任何自定义 JS,那么在您的 Controller 中您可以简单地执行以下操作:

def update
  if @offer.update(offer_params)
    flash[:success] = "#{@offer.name} #{t(:updated)}"
    redirect_to seller_offers_path
  else
    render :edit # see note below*
  end

你不需要update.js.erb; turbolinks-rails 会自动清除缓存并访问重定向路径。这很好,因为它使您的 Controller 代码保持整洁(不需要 respond_to),并且适用于 HTML 和 JS 请求。

* 值得注意的是,JS 请求的错误响应仍然需要手动处理。为此,您可能会发现此评论很有用:https://github.com/turbolinks/turbolinks/issues/85#issuecomment-338784510

缺少闪存

我认为你的 flash 没有显示在你更新的代码中的原因是因为你在 redirect_to 中使用了设置 flash 消息的简写样式,它只支持notice警报`:

redirect_to seller_offers_path, notice: '…' # sets flash[:notice]
redirect_to seller_offers_path, alert: '…' # sets flash[:slert]
redirect_to seller_offers_path, success: '…' # doesn't work

如果您希望使用自己的闪存 key ,则需要明确设置闪存:

flash[:success] = "#{@offer.name} #{t(:updated)}"

我还应该补充一点,Turbolinks 5 不支持 Turbolinks keep 选项。我认为这是 Turbolinks 2 或 3 中的一个特性。Turbolinks README是最新文档的位置。

希望对您有所帮助:)

关于ruby-on-rails - rails 6 : form with remote: true and Turbolinks not showing flash after redirect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57935148/

相关文章:

ruby-on-rails - 简单表格是否适用于嵌套对象?

javascript - AdSense 无法与 Turbolinks 合作

ruby-on-rails - Rails 4 和 Turbolinks - 元标签不变

ruby-on-rails - 如何使用 bluepill 守护 Rails 脚本

ruby-on-rails - vcr 不知道如何处理这个请求

ruby-on-rails - Rails simple_form_for 与 form_for 值/标题

ruby-on-rails - 如何在simple_form 2的包装器中向输入组件添加类

javascript - ExecJS::RuntimeError <%= javascript_include_tag 'application' , 'data-turbolinks-track' => true %>

ruby-on-rails - 如何告诉 ruby​​ 网络库使用特定的网络接口(interface)?

ruby-on-rails - 将算术运算符作为参数传递给 rails 方法?