【问题标题】:Custom error message for invalid confirmation token in Devise for RailsDevise for Rails 中无效确认令牌的自定义错误消息
【发布时间】:2014-11-26 10:13:20
【问题描述】:

tl;博士:

是否有一种简单的方法来获取单个模型(在这种情况下为用户)上的一个属性 (confirmation_token) 和错误 (:invalid) 组合的自定义完整错误消息?或者使用设计配置覆盖消息?

上下文

我正在使用 Rails 4 开发一个项目,我被要求更改 Devise 用来告诉用户注册确认令牌(注册确认电子邮件中包含的链接的一部分)无效的错误消息。

Devise 有一个不错的 Yaml 配置文件来编辑错误消息,但该错误似乎没有出现在那里。查看 Devise 的代码,它只是在用户模型的 Confirmation_token 字段上创建了一个标准的“:invalid”错误,呈现为正常的活动记录错误(使用errors.full_messages)。

https://github.com/plataformatec/devise/blob/8e5c098e3aa53d6a72faadd8b929abaf2bb6d496/lib/devise/models/authenticatable.rb

(方法调用解析为find_or_initialize_with_errors,默认设置为':invalid'。)

我可以对项目进行猴子补丁设计或分叉,但这应该是最后的手段。特别是对于基本上是副本更改的内容。

我研究在config/locales 文件夹中使用en.yml 来设置自定义消息。不幸的是,根据 Rails 文档,错误消息格式似乎是全局设置的:

https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml#L4

所以除非我弄错了,如果我想避免使用“确认令牌”开始错误消息,那么我必须找到所有可能由任何表单提交返回的完整错误消息,并确保它们仍然有意义。然后大多数人会说“无效”或“不能为空白”之类的无用的话。

不用说这个项目中有很多表格,所以这个解决方案超出了这个错误修复的范围。

我可以给属性一个人名 """The" 或者我想的,但这可能会在其他地方产生连锁反应,所以最好避免。

我徒劳地寻找一种方法来将错误消息格式字符串的范围限制为单个属性或模型。

大概“Rails 方式”是覆盖验证器中的完整消息,但在这种情况下,该代码隐藏在 gem 中。我能想到的解决这个问题的唯一方法是老套或脆弱。

【问题讨论】:

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


    【解决方案1】:

    好的——这就是我现在所做的,除了在设计本身上创建一个 PR:

    config/locales/en.yml

      devise:
        confirmations:
          header: 'Resend confirmation instructions'
        failure:
          confirmation_token_invalid: 'The confirmation link is no longer valid.  Please try sending a new confirmation email below.'
    

    app/views/devise/confirmations/new.html.erb

    <div id="confirmations-screen">
      <div class="dialog-head">
        <p><%= t('devise.confirmations.header') %></p>
      </div>
    
      <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
        <% unless resource.errors.empty? %>
          <% resource.errors.full_messages.each do |msg| %>
              <% if msg == 'Confirmation token is invalid' %>
                <%= t('devise.failure.confirmation_token_invalid') %>
              <% else %>
                <%= msg %>
              <% end %>
          <% end %>
        <% end %>
    
        <label for="email"><%= t('account.email.labels.email') %></label>
        <input type="email" id="user_email" name="user[email]" class="form-control">
        <button><%= t('devise.confirmations.resend_button') %></button>
      <% end %>
    </div>
    

    【讨论】:

    • 这是一个不错的(仍然很老套,但可行)的解决方案。我对视图中的错误显示进行了一些类似的破解,但更多的是在语言环境文件的错误消息中使用前缀来告诉视图不要首先显示字段名称的一般情况。公平地说,这似乎是 Rails 和 i18n 的问题,而不是 Devise。
    • 但是看起来它应该可以工作并且你是唯一的响应,所以有一个绿色的勾号。
    • 再看一遍,虽然可以使用以下行:if msg == 'Confirmation token is invalid' 在其他国家/地区对于多语言网站会失败。
    • 好点。困难的部分是错误实际上来自 ActiveModel - github.com/rails/rails/blob/… 。我不确定的部分是消息的“确认令牌”部分如何/是否/在哪里本地化。值得测试,但如果它没有本地化,那么可以使用if msg == "Confirmation token #{t('errors.messages.invalid')}"
    • 您必须自己翻译“确认令牌”,但是可以。我不记得 Rails 是否考虑了不同语言的词序。这也可能使问题复杂化。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多