代码之家  ›  专栏  ›  技术社区  ›  AnApprentice

轨道-设计-处理-设计错误消息

  •  122
  • AnApprentice  · 技术社区  · 14 年前

    在“我的用户编辑”页面中,有一行内容如下:

    <%= devise_error_messages! %>
    

    <% flash.each do |key, value| %>
        <div class="flash <%= key %>"><%= value %></div>
    <% end %>
    

    我的问题是,如何让designe错误消息像其他使用flash.each?

    20 回复  |  直到 8 年前
        1
  •  135
  •   Arturo Herrero Viren    11 年前

    我自己也在想办法。我刚在Github上发现这个问题 https://github.com/plataformatec/devise/issues/issue/504/#comment_574788

    何塞是这么说的 devise_error_messsages! 树桩 (尽管它包含了实现),我们应该重写/替换它。如果在维基的某个地方指出这一点会很好,这就是为什么我猜像我们这样的一些人一直在猜测。

    更新

    是的,这很管用。我创造了 app/helpers/devise_helper.rb

    module DeviseHelper
      def devise_error_messages!
        'KABOOM!'
      end
    end
    

    devise_helper.rb on Github

    messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
    

    这应该可以帮助您开始。:)

    另一个更新

    这个 resource 对象实际上是designe(go-figure)使用的模型。

    resource.class         #=> User
    resource.errors.class  #=> ActiveModel::Error
    

    在你助手的任何地方

    module DeviseHelper
      def devise_error_messages1!
        resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
      end
    
      def devise_error_messages2!
        resource.errors.full_messages.map { |msg| content_tag(:p, msg) }.join
      end
    end
    

    你的观点

    <div><%= resource.errors.inspect %></div>
    
        2
  •  38
  •   Lukasz Muzyka    9 年前

    下面的解决方案适用于目前最新的设计(4.1.1)和Rails 4.2.6。但是很简单,我不明白为什么10年后它就不能工作;)

    如果你想回收你的错误信息,让它们在你的应用程序中看起来是一样的,我建议你这样做(这是我从Michael Hartl tut那里学到的):

    layouts/_error_messages.html.erb

    <% if object.errors.any? %>
      <div id="error_explanation">
        <div class="alert alert-danger alert-dismissable">
          <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
          <p><strong>This form contains <%= pluralize(object.errors.count, 'error') %>.</strong></p>
          <ul>
            <% object.errors.full_messages.each do |msg| %>
              <li><%= msg %></li>
            <% end %>
          </ul>
        </div>
      </div>
    <% end %>
    

    现在你有了可回收的东西,你可以全面使用它。

    <%= devise_error_messages! %>
    

    你可以这样称呼它:

    <%= render 'layouts/error_messages', object: resource %>
    

    你可以把它放在任何形式。您可以像这样从窗体中传递变量,而不是传递designe资源:

    <%= form_for @post do |f| %>
      <%= render 'layouts/error_messages', object: f.object %>  
      <%= f.text_field :content %>
      <%= f.submit %>
    <% end %>
    
        3
  •  22
  •   Eric Hu    14 年前

    在整个设计过程中,您将看到使用 render_with_scope . 我相信这是一个由designe定义的方法,基本上是将当前范围应用到下一个呈现的视图。

    resource.errors ( @resource.errors

    如果您开始更改用户管理行为,则会出现这些错误的问题。通过添加 redirect_to render (代替 )如果designe以前没有,那么基本上就是抛出错误消息。在我看来,这使得设计对修改不友好。

    我的解决办法是

    # In application.html.erb
    <% flash.each do |name, msg| %>
    
      # New code (allow for flash elements to be arrays)
      <% if msg.class == Array %>
        <% msg.each do |message| %>
          <%= content_tag :div, message, :id => "flash_#{name}" %>
        <% end %>
      <% else %>
    
        # old code
        <%= content_tag :div, msg, :id => "flash_#{name}" %>
    
      <% end %> #don't forget the extra end
    <% end %>
    

    # Wherever you want Devise's error messages to be handled like 
    # your other error messages
    # (in my case, registrations_controller.rb, a custom controller)
    flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
    

    后一个代码块将designe的错误消息作为数组并附加到 flash[:notice]

        4
  •  12
  •   r123454321    11 年前

    我通过创建一个 app/helpers/devise_helper.rb 把这个放进去:

    module DeviseHelper
    
      # Hacky way to translate devise error messages into devise flash error messages
      def devise_error_messages!
        if resource.errors.full_messages.any?
            flash.now[:error] = resource.errors.full_messages.join(' & ')
        end
        return ''
      end
    end
    

    工作!

        5
  •  11
  •   Kulgar proteantech    12 年前

    我只想在这里带来一个新的小片段:

    所以我找到了一个更简单的方法来得到“实习医生”想要的结果。

    首先,如果您想自定义designe插件中的任何内容,我强烈建议您将“\Ruby\u repertory\lib\Ruby\gems\1.9.1\gems\designe version\app\controllers | helpers | mailers…”中的代码复制到项目中所需的文件中。

    class Users::RegistrationsController < Devise::RegistrationsController
    

    [2013年8月7日编辑]现在Devise甚至提供了一个生成控制器的工具: https://github.com/plataformatec/devise/wiki/Tool:-Generate-and-customize-controllers

    所以。。。不管怎样。。。我写了这篇文章就得到了“AnApprentice”想要的东西(要获得更清晰的解决方案,请参阅下面的大编辑):

    #/my_project/app/helpers/devise_helper.rb
    module DeviseHelper
       def devise_error_messages!
          return "" if resource.errors.empty?
    
          return resource.errors
       end
    end
    

    <% devise_error_messages!.each do |key, value| %>
        <div class="flash <%= key %>"><%= key %> <%= value %></div>
    <% end %>
    

    好。。。然后您可以访问特定属性的错误,如下所示:

        #Imagine you want only the first error to show up for the login attribute:
        <%= devise_error_messages![:login].first %> 
    

    <% if resource.errors.any? %>
      <% saved_key = "" %>
      <% devise_error_messages!.each do |key, value| %>
        <% if key != saved_key %>
            <div class="flash <%= key %>"><%= key %> <%= value %></div>
        <% end %>
        <% saved_key = key %>
      <% end %>
    <% end %>
    

    我知道这个问题发布已经有一段时间了,但我认为它会帮助很多设计用户:)。

    大编辑:

    所以,我的方法是:

     def devise_error_messages! 
        html = ""
    
        return html if resource.errors.empty?
    
        errors_number = 0 
    
        html << "<ul class=\"#{resource_name}_errors_list\">"
    
        saved_key = ""
        resource.errors.each do |key, value|
          if key != saved_key
            html << "<li class=\"#{key} error\"> This #{key} #{value} </li>"
            errors_number += 1
          end
          saved_key = key
        end
    
        unsolved_errors = pluralize(errors_number, "unsolved error")
        html = "<h2 class=\"#{resource_name}_errors_title\"> You have #{unsolved_errors} </h2>" + html
        html << "</ul>"
    
        return html.html_safe
     end
    

    这里没什么大不了的,我重用了我在视图中编写的代码,只显示一个error-pey属性,因为通常第一个是唯一相关的(比如当用户忘记一个必需字段时)。

    我正在计算那些“唯一”的错误,我正在使用pluralize制作一个H2 HTML标题,并将其放在错误列表之前。

    所以现在,我可以使用“设计错误消息”作为默认值,它完全呈现我之前已经呈现的内容。

    西娅, 库尔加。

        6
  •  6
  •   Scott    14 年前

    <% flash.each do |name, msg| %>
      <%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
    <% end %>
    

    尝试一下这个代码,看看它是否有什么不同-不同的ID属性可能会有所帮助。

        7
  •  5
  •   ddidier    13 年前

    我想到这一点,到目前为止,它的工作。 这就为flash添加了designe消息,所以它可以像往常一样使用。请考虑到我对Ruby和Rails是新手。。。

    class ApplicationController < ActionController::Base
      after_filter :set_devise_flash_messages, :if => :devise_controller?
      ...
    
      private:
    
      def set_devise_flash_messages
        if resource.errors.any?
          flash[:error] = flash[:error].to_a.concat resource.errors.full_messages
          flash[:error].uniq!
        end
      end
    end
    

    很抱歉,我在看守,出现了一些不必要的行为。自 after_filter 在渲染后调用,因此无法按预期工作。如果有人知道如何在操作之后但在呈现之前调用方法。。。

    但你可以用这样的方法来代替:

    module ApplicationHelper
    
      # merge the devise messages with the normal flash messages
      def devise_flash
        if controller.devise_controller? && resource.errors.any?
          flash.now[:error] = flash[:error].to_a.concat resource.errors.full_messages
          flash.now[:error].uniq!
        end
      end
    
    end
    

    views/shared/_messages.html.erb

    <% devise_flash %>
    <!-- then display your flash messages as before -->
    
        8
  •  3
  •   user1026130 user1026130    12 年前

    首先要做的是,在你的应用程序中_controller.rb,添加以下内容:

      # Adds the posibility to have more than one flash of a given type
      def flash_message(type, text)
        flash[type] ||= []
        flash[type] << text
      end
    

       <div class="flashes">
          <% flash.each do |key, messages| %>
            <% messages = Array(messages) unless messages.is_a?(Array) %>
            <% messages.each do |message| %>
            <div class="alert alert-<%= key %>">
              <%= message %>
            </div>
            <% end %>
          <% end %>
        </div>
    

    第三件要做的事是,无论何时您想在任何控制器中添加flash消息,请执行以下操作:

    flash_message(:success, "The user XYZ has been created successfully.")
    
        9
  •  3
  •   B-M    6 年前

    创建设备帮助:

    module DeviseHelper
      def devise_error_messages!
        return "" if resource.errors.empty?
    
        messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg)}.join
        return flash.now[:alert] = messages.html_safe
      end
    end
    

    在你看来,替代

    <%= devise_error_messages! %>
    

    <% devise_error_messages! %>
    
        10
  •  2
  •   typeoneerror    13 年前

    诚然,有点黑客,但我正在使用这个助手(app/helpers/devieve)_helper.rb)抓取闪光并使用那些如果设置,则默认为 resource.errors . 这只是基于designe lib中的helper。

    module DeviseHelper
    
      def devise_error_messages!
        flash_alerts = []
        error_key = 'errors.messages.not_saved'
    
        if !flash.empty?
          flash_alerts.push(flash[:error]) if flash[:error]
          flash_alerts.push(flash[:alert]) if flash[:alert]
          flash_alerts.push(flash[:notice]) if flash[:notice]
          error_key = 'devise.failure.invalid'
        end
    
        return "" if resource.errors.empty? && flash_alerts.empty?
        errors = resource.errors.empty? ? flash_alerts : resource.errors.full_messages
    
        messages = errors.map { |msg| content_tag(:li, msg) }.join
        sentence = I18n.t(error_key, :count    => errors.count,
                                     :resource => resource.class.model_name.human.downcase)
    
        html = <<-HTML
        <div id="error_explanation">
          <h2>#{sentence}</h2>
          <ul>#{messages}</ul>
        </div>
        HTML
    
        html.html_safe
      end
    
    end
    
        11
  •  2
  •   Douglas Drouillard    12 年前

    如果你想利用designe\u error\u消息,那么你可以通过添加resource.errors

    如果你越过注册控制器,它可能看起来像

    def create
      if validation_or_other_check_passes
        super
      else
        build_resource
        clean_up_passwords(resource)
        resource.errors.add(:notice, "The check failed.")
        render :new 
    
        12
  •  2
  •   SSR    11 年前

    显示每个字段的错误消息的非常简单的方法

    <%= resource.errors.messages[:email].join(" ") %>
    

    将每个字段的字段名放在要显示内联错误消息的每行下方的方括号中。

        13
  •  1
  •   Nick    13 年前

    显示控制器的设计错误,只显示第一个错误。

    flash[:error] = @resource.errors.full_messages.first
    
        14
  •  1
  •   ChuckJHardy    13 年前

    只是为了补充上面所有If语句的用法,不如这样做。

    # Controller
    flash.now[:error] = flash[:error].to_a.concat(resource.errors.full_messages)
    
    # View
    <% flash.each do |name, msg| %>
     <% Array(msg).uniq.each do |message| %>
      <%= message %>
     <% end %>
    <% end %>
    
        15
  •  1
  •   dev.guillaumem59    8 年前

    我只是这样做,为我工作:在 应用程序/帮助程序/ ,我创建了一个文件 设计_helper.rb

      module DeviseHelper
    
      def devise_error_messages_for(resource)
        return "" if resource.errors.empty?
    
        messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
        sentence = I18n.t("errors.messages.not_saved",
                          count: resource.errors.count,
                          resource: resource.class.model_name.human.downcase)
    
        html = <<-HTML
        <div id="error_explanation">
          <h2>#{sentence}</h2>
          <ul>#{messages}</ul>
        </div>
        HTML
    
        html.html_safe
      end
    end
    

    <%= devise_error_messages! %>
    

    <%= devise_error_messages_for(#your object in your formular)%>
    

    对我来说,在我的视图中编辑和新建用户:

      <%=form_for resource, as: @user, url: user_path(@user),...
          <%= devise_error_messages_for(@user) %>
    

    希望对您有所帮助;)

        16
  •  0
  •   Gacha    13 年前
    1. 删除“设计错误消息”从“app/views/users/passwords/new”模板。
    2. 为您的用户创建自定义控制器(应用程序/控制器/用户/密码_controller.rb)在后过滤器中添加错误闪存阵列:
    class Users::PasswordsController < Devise::PasswordsController
      after_filter :flash_errors
    
      def flash_errors
        unless resource.errors.empty?
          flash[:error] = resource.errors.full_messages.join(", ")
        end
      end
    end
    
        17
  •  0
  •   botbot    10 年前

    我喜欢做这件事,就像在另一个控制器里做的一样。

    <% if flash.count > 0 %>
      <div id="error_explanation">
        <h2>Errors prevented you from logging in</h2>
          <ul>
            <% flash.each do |name, msg| %>
            <li>
              <%= content_tag :div, msg, id: "flash_#{name}" %>
            </li>
           <% end %>
         </ul>
       </div>
    <% end %>
    
        18
  •  0
  •   Gregoire Mulliez    7 年前

    module DeviseHelper
      def devise_error_messages!
    
        messages = resource.errors.full_messages.map { |msg|
          String.new(" M.toast({html: '" + msg + "' }); ".html_safe )
        }.join
    
        messages = ("<script>" + messages + "</script>").html_safe
      end 
    end
    

    我相信他们会是最干净的方式来写它,但它的工作完美

        19
  •  0
  •   Muhammad Nasir Shamshad    5 年前

    DeviseHelper#devise_error_messages! 已弃用并将 在下一个主要版本中删除。

    devise/shared/error_messages 显示 错误消息,并使其更易于自定义。

          <%= devise_error_messages! %>
    

    收件人:

          <%= render "devise/shared/error_messages", resource: resource %>
    
        20
  •  -1
  •   YoyoS    11 年前

    我刚创建了一个 app/helpers/devise_helper.rb 像约翰一样,但却推翻了这样的方法:

    module DeviseHelper
      def devise_error_messages!
        flash[:error] = resource.errors.full_messages.join('<br />')
        return ''
      end
    end
    

    有了这个,我就不必再修改任何东西了。

        21
  •  -2
  •   Harry Moreno    12 年前

    我刚刚宣布设计错误信息!作为一个空助手。