Ruby on rails rails-设计-处理-设计错误消息

Ruby on rails rails-设计-处理-设计错误消息,ruby-on-rails,devise,Ruby On Rails,Devise,在“我的用户编辑”页面中,有一行内容如下: <%= devise_error_messages! %> 问题在于,这不会以应用程序其余部分的标准方式输出错误: <% flash.each do |key, value| %> <div class="flash <%= key %>"><%= value %></div> <% end %> 我的问题是,我如何让Desive错误消息像其他使用f

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

<%= devise_error_messages! %>

问题在于,这不会以应用程序其余部分的标准方式输出错误:

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

我的问题是,我如何让Desive错误消息像其他使用flash的人一样工作


谢谢。

我在Rails 3中使用Desive,您的flash代码与我得到的几乎相同。在我的应用程序中,代码按预期工作;i、 e.设计错误消息与我的其他flash消息一起输出:

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

如果msg.is_是一个?(字符串)%>

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

我自己也在努力解决这个问题。我刚刚在Github上发现这个问题

何塞是说
设计错误消息方法只是一个存根(尽管它包含实现),我们应该重写/替换它。如果在维基的某个地方有人指出这一点,那就太好了,这就是为什么我猜像我们这样的一些人一直在猜测的原因

因此,我将尝试重新打开模块并重新定义方法,有效地覆盖默认实现。我会告诉你事情的进展

更新 是的,这很有效。我创建了
app/helpers/designe\u helper.rb
并对其进行了如下重写:

module DeviseHelper
  def devise_error_messages!
    'KABOOM!'
  end
end
因此,知道了这一点,我可以修改该方法,以我希望的方式显示错误消息

帮助您解决原始问题:以下是原始问题。看看错误消息是如何被遍历的:

messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
这将有助于您开始工作。:)

另一个更新
resource
对象实际上是Deviate正在使用的模型(见图)

它似乎也在更高的范围内定义(可能来自控制器),因此可以在各种地方访问它

在你的助手的任何地方

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>

我知道这个问题发布已经有一段时间了,但我只是想对我的发现发表评论。两位已经回答的人对我帮助很大,我只是想做出贡献

在整个设计中,您将看到使用
render\u和\u scope
的调用。我相信这是Desive定义的一种方法,基本上将当前范围应用于下一个呈现的视图

为什么这是相关的?Desive将您的错误包含在
资源中。错误
不是
@resource.errors
)。可以这么说,如果你想开箱即用的话,Desive很好用

如果您开始更改用户管理行为,则会出现这些错误的问题。通过添加一个
重定向到
呈现
(而不是
呈现范围
)Deave以前没有的地方,您基本上抛出了错误消息。在我看来,这使得design对修改不友好

我的解决办法是

# 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 %>

后一个代码块将designe的错误消息作为数组,并将其附加到
flash[:notice]
(作为数组)。每条信息将一次打印一行。如果我有时间的话,我想我会改变Desive处理错误消息的方式,以便在我的整个应用程序中做到这一点,因为只有一个错误消息系统而不是两个似乎要干净得多。

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

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

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

[编辑]或者您可以使您的文件从“普通”设计文件继承。。。喜欢说。。。如果只想覆盖designe/registrations\u controller.rb中的一个函数,则用户自定义注册控制器的第一行是:

class Users::RegistrationsController < Devise::RegistrationsController
在我看来,接下来的几行非常有效:

<% 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 %> 
<%= render 'layouts/error_messages', object: resource %>
<%= form_for @post do |f| %>
  <%= render 'layouts/error_messages', object: f.object %>  
  <%= f.text_field :content %>
  <%= f.submit %>
<% end %>
#假设您只希望登录属性显示第一个错误:
而且。。。每个属性只显示一个错误(第一个被捕获)的小技巧:

<% 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 %>


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

大编辑:

由于我喜欢扩展我的代码,使其更干净,并与他人共享,我最近想更改designe_error_消息!方法,以便在我的视图中使用它,并使其显示我上面解释的技巧

因此,以下是我的方法:

 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
def设计错误消息!
html=“”
如果resource.errors.empty返回html?
错误数=0

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

flash[:error] = @resource.errors.full_messages.first

诚然,有点黑客,但我正在使用这个助手(app/helpers/designe_helper.rb)抓取闪光,如果设置为默认值,则使用它们
resource.errors
。这只是基于designe库中的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
模块设备帮助器
def设计错误消息!
闪光警报=[]
error\u key='errors.messages.not\u saved'
如果!闪光,空的?
flash_警报。如果flash[:error],则推送(flash[:error])
flash_alert.push(flash[:alert]),如果flash[:alert]
flash_警报。如果flash[:notice],则推送(flash[:notice])
错误\u key='designe.failure.invalid'
结束
如果resource.errors.empty返回“”&&flash_.empty?
errors=resource.errors.empty?flash_警报:resource.errors.full_消息
messages=errors.map{| msg | content_标记(:li,msg)}.join
语句=I18n.t(error_key,:count=>errors.count,
:resource=>resource.cl
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
# 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 %>
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
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
<% devise_flash %>
<!-- then display your flash messages as before -->
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 
  # 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_message(:success, "The user XYZ has been created successfully.")
<%= resource.errors.messages[:email].join(" ") %>
module DeviseHelper
  def devise_error_messages!
    flash[:error] = resource.errors.full_messages.join('<br />')
    return ''
  end
end
<% 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 %>
<%= form_for @post do |f| %>
  <%= render 'layouts/error_messages', object: f.object %>  
  <%= f.text_field :content %>
  <%= f.submit %>
<% end %>
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
<% 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 %>
  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) %>
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
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! %>
      <%= devise_error_messages! %>
      <%= render "devise/shared/error_messages", resource: resource %>