【问题标题】:Rails unexpectedly routing to index after form submit提交表单后,Rails 意外路由到索引
【发布时间】:2021-02-14 15:06:01
【问题描述】:

我有一个“贡献”模型。创建表单有两个提交操作:“Preview”和“Submit for Review”。当用户单击“预览”时,我想收集表单数据,然后在同一页面上显示预览。以下是我的处理方式:

表格:

    <%= form_with(model: @contribution, local: true) do |form| %>
      <% if @contribution.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@contribution.errors.count, "error") %> prohibited this contribution from being saved:</h2>

          <ul>
            <% @contribution.errors.full_messages.each do |message| %>
              <li><%= message %></li>
            <% end %>
          </ul>
        </div>
      <% end %>

      <div class="field">
        <%= form.url_field :link, placeholder: "Unsplash photo link", required: true %>
      </div>

      <div class="actions">
        <%= submit_tag 'Preview', id: 'preview-button', name: 'preview_button' %>
        <%= submit_tag 'Submit for Review', id: 'submit-button' %>
      </div>
    <% end %>

贡献控制器:

  def create
    @contribution = Contribution.new(contribution_params)

    if params[:preview_button]
      /// do some stuff to collect data
      render action: "new"
    else

    ...

路线:

  resources :contributions
  get "/contribute" => "contributions#new"

当前结果

页面刷新并且控制器中处理的数据可用(耶!)。但是,URL 从 /contribute 更改为 /contributions。如果用户碰巧刷新页面,他们会遇到错误,因为我没有贡献#index 视图。

期望的结果

页面刷新,数据可用,但 url 保持为 /contribute。

【问题讨论】:

  • 也请分享表格。
  • 已编辑以包含完整表格
  • 尝试将render action: "new"更改为return render 'new'
  • @BroiSatse 不走运。它似乎仍然呈现“新”视图,但 url 是 /contributions
  • @rcrusoe 在你的路由中添加这个资源之后:contributions resolve("Contributions") { [:contributions] }.

标签: ruby-on-rails ruby forms


【解决方案1】:

这是因为创建操作的端点是POST /contributions。并且“呈现”不同的操作对 url 没有任何作用。

您需要改为重定向。

替换

render action: 'new'

return redirect_to action: :new

【讨论】:

  • 这样实现了正确的url,但是我想传递的变量没有传递。有没有办法重定向和传递数据而不将其填充到 URL 中?
【解决方案2】:

我能想到 2 个选项:

redirect_to + flash hash

您可以重定向到/contribute,但将收集到的数据存储在 Flash Hash 中:

flash[:collected_data] = something
redirect_to "/contribute"

你可以在那里存储字符串、数组和散列,虽然我不会滥用它。

然后您可以在您的 new 操作中执行 @collected_data = flash[:collected_data] 以了解它是否来自之前的 POST 请求。

渲染“新”并在加载后更改网址

您可以在页面加载后使用一些 javascript 来推送新状态,例如:

document.addEventListener('DOMContentLoaded', () => {
  history.pushState({}, 'Some title', '/contribute')
})

这会将您的当前路径更改为/contribute,而无需实际加载该网址,因此您保留来自POST /contributions 的响应,但网址会更改,因此您的刷新是安全的。

【讨论】:

    猜你喜欢
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多