使用 Turbo Frames 的内联设计注册表单

Lee*_*lly 5 ruby ruby-on-rails devise hotwire-rails turbo-frames

我在使用 Turbo Frames 设置 Devise 注册表单时遇到问题。我希望将 Devise 注册表单设置为“逐步参与”表单,只需要电子邮件即可从主页注册新用户。

到目前为止我的设置方式如下:

  • 首先,我使用此解决方法来获取与 Hotwire 一起使用的默认 Devise 视图。
  • 然后,我使用这种方法让设计注册表单在我的主页上运行
  • 最后,我使用此方法在 Devise 中设置了仅电子邮件注册。

这一切都按预期工作,但是当用户完成注册时,它会重定向并显示 Flash 页面。相反,我想使用 Turbo Frames 将表单替换为“感谢您注册”之类的消息,而无需重新加载任何页面或进行重定向。

此外,如果表单中存在任何错误(例如电子邮件为空),它会重定向到默认的设备注册视图并在那里显示错误。我希望这种情况发生在主页框架内,这样当显示错误时就不会重新加载页面。

那么,我该如何使用 Devise 和 Turbo Frames 来做到这一点呢?

这是在主页上运行的表单:

<%= form_for resource, :as => resource_name, :url => registration_path(resource_name), html: { class: "sm:flex" } do |form| %>
  <%= form.label :email, class: "sr-only" %>
  <%= form.email_field :email %>
  <div class="mt-3 rounded-md shadow sm:mt-0 sm:ml-3 sm:flex-shrink-0">
    <%= form.submit "Subscribe" %>
  </div>
<% end %>
Run Code Online (Sandbox Code Playgroud)

并且,为了使其正常工作,我创建了一个confirmations_controller.rb覆盖默认值的方法,Devise::ConfirmationsController如下所示:

class ConfirmationsController < Devise::ConfirmationsController
  private
  def after_confirmation_path_for(resource_name, resource)
    sign_in(resource) # In case you want to sign in the user
    root_path
  end
end
Run Code Online (Sandbox Code Playgroud)

我是否需要创建一个 UsersController 来覆盖 Devise 的某些部分才能使用 Turbo 帧?我该怎么做?

Aid*_*les 1

您将无法使用after_X_path_forTurbo 来完成此任务。当您点击 时after_confirmation_path_for,我的理解是 Devise 已经启动了重定向,因此更改为 Turbo 响应为时已晚。这些步骤应该会让您更接近:

  1. 您需要通过添加选项data: { turbo: true }或将其包装在turbo-frame元素中来在表单上启用 Turbo。您会看到整个页面重新加载和闪现消息,因为它丢失了。

  2. 您的表单(或父表单turbo-frame)需要 Turbo 响应目标的 ID(即控制器操作需要知道要更新哪个元素)。

  3. 看来您的表单提交是由 处理的RegistrationsController。您将需要调整控制器操作(可能#create?)以获得实际呈现 Turbo 响应的块,如下所示:

respond_to do |fmt|
  fmt.turbo_stream do
    render turbo_stream: turbo_stream.replace(
      form_element_id,
      partial: 'your_html_partial/here',
      locals: {
        current_user: your_user,
        other: "data"
      }
    )
  end
end
Run Code Online (Sandbox Code Playgroud)

最后,这并不能回答你的问题,但在没有 Devise 的情况下实现它会更简单,主要是因为你做了很多定制。Devise 最适合有限的定制(因为,像 Rails 一样,它具有非常强大的约定)。实现此流程应该只涉及几个控制器操作(呈现登录/注册表单、使用 Turbo 流处理表单提交)。