【问题标题】:Raise an alert/notice in rails controller WITHOUT redirect在没有重定向的情况下在 Rails 控制器中发出警报/通知
【发布时间】:2016-09-28 18:34:10
【问题描述】:

如果电子邮件已保存/未保存,我想显示通知/错误,不使用重定向。我在项目中使用 Rails 4,这是我的代码:

layouts/application.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>FarFlung Jobs</title>
  <!-- /.You can include style.css into stylesheet_link_tag too. If you do so, dont forget to add style.css in asset.rb -->
  <%= stylesheet_link_tag    'application', 'jobs', media: 'all' %>
  <%= javascript_include_tag 'application' %>
  <%= javascript_include_tag 'config', 'sharebutton', 'jobsalert', 'modernizr'%>
  <%= render 'payola/transactions/stripe_header' %>
  <%= csrf_meta_tags %>
</head>
<body>
    <%=  render 'shared/navbar' %>

    <div>
      <% flash.each do |name, msg| %>
        <%= content_tag :div, msg, class: 'alert alert-info' %>
      <% end %>
    </div>

<%= yield %>
    <%=  render 'shared/footer' %>
</body>
</html>

users/new.html.erb

<section class="cd-form-wrapper cd-container">
    <div class="column panel panel-default">
      <div class="cd-filter"><h4>SUBSCRIBE FOR JOBS ALERT</h4></div>
      <%= simple_form_for User.new do |f| %>
          <%= f.input :email, label: false, :placeholder => 'Enter your email address...', :input_html => { :class => 'newsletter-form-field-styling' } %>
          <%= f.button :submit, 'SUBMIT', :class => 'btn-block newsletter-form-styling btn-primary submit' %>
      <% end %>
    </div>
</section>

users_controller.rb

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(secure_params)
    if @user.valid?
      @user.save
      flash.now[:notice] = "#{@user.email} is signed up for Jobs Alert."
    else
      flash.now[:alert] = 'Error Subscribing!'
    end
  end

private

  def secure_params
    params.require(:user).permit(:email)
  end
end

如何在不重定向页面的情况下让 Rails flash 消息正常显示在我的订阅表单上?

【问题讨论】:

  • 不,你不能这样做。你会有模板丢失错误。你可以使用render,它不会刷新页面。但是你新添加的数据将不会出现,因为你必须使用重定向或 ajax。
  • @7urkm3n,我的 Ajax 知识有点生疏。如果我将成功和错误消息定义为“部分”,并在我的视图/注册表单中呈现该部分,这是否可以解决我的问题,使我的表单上有错误和成功消息而无需重定向?

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

您可以使用像 Gon 这样的 gem 来监控变量并自动为您处理所有 Ajax。

设置非常简单,您可以让它以您选择的任何时间间隔执行更新。如果您只是传输一个变量,这将为您节省一些 Ajax 编码。它会在不进行任何重定向的情况下更新您的页面,因此它完全符合您的要求。

【讨论】:

    【解决方案2】:

    您可以通过remote: true 提交您的表单。它会(如您所料)远程提交您的表单,因此您可以返回一个 json 并渲染预期的 flash。例如:

    您的表格:

    simple_form_for User.new, remote: true, class: 'your-form' do 
      <your code>
    

    您的控制器

    def create
    @user = User.new(secure_params)
    if @user.save
      render json: { status: 'success', message: "#{@user.email} is signed up for Jobs Alert." }
    else
      render json: { status: 'failure', message: 'Error Subscribing!' }
    end
    

    结束

    您的 JS(可能是 new.js - 并确保将其包含在您的视图中)

    // you can specify your bind container, here I just used the document
    $(document).on('ajax:success', '.your-form', function(e, data) {
      if(data.status == 'success'){
        showSuccessFlash(data);
      }else{
        showErrorFlash(data);
      }
    });
    

    解释:

    使用remote: true,您的页面将等待一个ajax 答案,您可以收听ajax:success(或其他绑定)。

    然后,它将接收json 并将存储在data 变量中。因此,您将获得data.statusdata.message,您可以将它们作为反馈显示给您的用户。

    更多关于remote: truehttp://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#form-for的信息

    更多关于 JS 回调的信息https://github.com/rails/jquery-ujs/wiki/ajax

    【讨论】:

    • 是的,我收到了 JSON 响应,但作为重定向到我的localhost:3000/users。我不想重定向。我的视图index.html.erb 中有订阅表格。也许我在这里做错了什么:有$(document).on('ajax:success', '.your-form', function(e, data) { 的行,我应该在我有.your-form 的地方添加什么?
    • 如果您在create 操作中添加render json,您将不会被重定向,因为您需要重定向redirect_to path.your-form 是您添加到表单中的一个类,因此您可以“跟踪”它。 simple_form_for User.new, remote: true, class: 'your-form' do |f|
    • 对不起,我按照您的建议在我的create 操作中执行了render json,但我被重定向到localhost:3000/users。我可能做错的唯一一件事是我的 new.html.erb 中的这个新更新 simple_form_for User.new, remote: true, class: 'your-form' do |f|,因为我没有添加 class。我会影响它。如果您可以更新答案,那就太好了。谢谢。
    • 非常好的解决方案。我喜欢它的简单优雅,以及它不引入新组件的事实。
    【解决方案3】:

    但是,我想出解决此问题的另一项调整是有/无重定向使用application helper 使您的 Flash 全局化并用于您选择的任何视图。

    将您的 Flash 消息移动到部分,例如

    shared/_flash_messages.html.erb

        <div class="text-center">
          <% flash.each do |name, msg| %>
              <%= content_tag :div, msg, class: 'alert alert-info' %>
          <% end %>
        </div>
    

    使用与以前完全相同的旧 rails 方法为您的 flash 消息定义自定义帮助器方法。这样该方法会呈现我们的部分,并且对象将被解析为您的部分。

    helpers/application_helper.rb

    module ApplicationHelper
       def flash_messages_for(object)
          render(:partial => 'shared/flash_messages', :locals => {:object => object})
       end
    end
    

    在我的视图中,你可以用erb标签调用它,并调用它上面的表单对象,例如&lt;%= flash_messages_for(User.new) %&gt;&lt;%= flash_messages_for(@user) %&gt;。见以下代码:

    users/new.html.erb

    <section class="cd-form-wrapper cd-container">
    <div class="column panel panel-default">
      <%= flash_messages_for(User.new) %>
      <div class="cd-filter"><h4>SUBSCRIBE FOR JOBS ALERT</h4></div>
      <%= simple_form_for(User.new) do |f| %>
          <%= f.input :email, label: false, :placeholder => 'Enter your email address...', :input_html => { :class => 'newsletter-form-field-styling' } %>
          <%= f.button :submit, 'SUBMIT', :class => 'btn-block newsletter-form-styling btn-primary submit' %>
      <% end %>
    </div>
    

    这样,我的错误消息会在我调用&lt;%= flash_messages_for(User.new) %&gt; 的任何视图或表单上闪烁。

    您可以参考 Lynda.com 上的 Kevin Skoglund formerrors Ruby on Rails 教程 Click to watch

    【讨论】:

      猜你喜欢
      • 2011-11-23
      • 1970-01-01
      • 2020-10-21
      • 2020-05-10
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多