Rails 4:以自定义形式呈现设计错误消息

时间:2016-02-01 20:55:18

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

我有2个不同的设计注册表单,一个用于普通用户,另一个用于供应商,我创建了一个自定义注册控制器,它正常工作:

class RegistrationsController < Devise::RegistrationsController
    def create
        super
        if resource.save
            if params[:role] == 'vendedor'
                resource.add_role :vendedor
            end
        end
    end

    #In this action I render the custom form for vendors registration
    def new_with_role
        build_resource({})
        case params[:role]
        when 'proveedor'

        else
            redirect_to root_path, alert: 'Unexpected error'
        end
    end
end

我为供应商的自定义表单创建了这条路线:

devise_scope :user do
    get "/sign_up/:role" => 'registrations#new_with_role', as: 'new_user_with_role'
  end

这是views/devise/registrations/new_with_role.html.erb

形式
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), builder: FoundationFormBuilder) do |f| %>
        <%= f.text_field :name, label: "Company name", autofocus: true %>
        <%= f.email_field :email, label: "Correo electrónico(ideal: Gmail, Hotmail, Outlook, Yahoo)" %>
        <%if @validatable %>
          <%= f.password_field :password, autocomplete: "off", hint: "#{@minimum_password_length} caracteres como mínimo" %>
        <% else %>
          <%= f.password_field :password, autocomplete: "off" %>
        <% end %>
        <%= f.password_field :password_confirmation, label: "Confirmar contraseña", autocomplete: "off" %>
        <%= hidden_field_tag :role, 'vendedor' %> #With this custom param I can set the role of the user in the create action of the custom registrations controller
        <%= f.submit "Enviar", data: { disable_with: "Wait please..." } %>
    <% end %>

表单效果很好,但我无法弄清楚如何在此自定义表单中呈现错误。当我发送有意错误的表单时,我会得到以下内容:

undefined method `errors' for nil:NilClass

检查日志我发现当出现错误时,我create的{​​{1}}操作正在呈现Devise的RegistrationsController操作,我认为这会导致错误,我如果填写表单时出错,则要呈现new操作。

当我向供应商发送故意错误的表单时,这些是日志:

new_with_role

正如您所看到的,当表单上存在错误时,呈现的操作是:

Started POST "/users" for ::1 at 2016-02-01 15:33:36 -0500
Processing by RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"kwiV0+GwiGTYVQf0iFE19YoZqZKnAgqzGkTr3D9OCYy03ZPy7xC4ZjFSlnfItE4fuofRAg9jMJ3wIN+si8oR+w==", "user"=>{"last_name"=>"", "phone1"=>"", "first_name"=>"", "email"=>"", "preference_details"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "business_line"=>"2", "role"=>"vendedor", "commit"=>"Enviar"}
   (0.4ms)  BEGIN
  User Exists (1.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY '' LIMIT 1
   (0.3ms)  ROLLBACK
  Rendered devise/registrations/new.html.erb within layouts/application (84.1ms)
Completed 500 Internal Server Error in 224ms (ActiveRecord: 2.1ms)

ActionView::Template::Error (undefined method `errors' for nil:NilClass):
    11:     <% end %>
    12:     <h5 class="subtitle">O regístrate de la forma tradicional</h5>
    13:     <%= form_for(:user, as: resource_name, url: registration_path(resource_name), builder: FoundationFormBuilder) do |f| %>
    14:         <%= f.text_field :first_name, label: "Nombre", autofocus: true %>
    15:         <%= f.text_field :last_name, label: "Apellido" %>
    16:         <%= f.email_field :email, label: "Correo electrónico" %>
    17:         <div class="row collapse">
  lib/foundation_form_builder.rb:75:in `errors_on?'
  lib/foundation_form_builder.rb:21:in `block (2 levels) in <class:FoundationFormBuilder>'
  app/views/devise/registrations/new.html.erb:14:in `block in _app_views_devise_registrations_new_html_erb__4160932045667554001_70342326706100'
  app/views/devise/registrations/new.html.erb:13:in `_app_views_devise_registrations_new_html_erb__4160932045667554001_70342326706100'
  app/controllers/registrations_controller.rb:3:in `create'


  Rendered /Users/sebastianvelandiagiraldo/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_source.erb (9.4ms)
  Rendered /Users/sebastianvelandiagiraldo/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (4.2ms)
  Rendered /Users/sebastianvelandiagiraldo/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
  Rendered /Users/sebastianvelandiagiraldo/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (43.8ms)

它应该是:

Rendered devise/registrations/new.html.erb

我猜这导致了这个问题。任何帮助将非常感激

更新1

我发现this问题类似,但提供的答案毫无用处。

更新2

我当前的Devise版本3.5.2的创建操作代码

Rendered devise/registrations/new_with_role.html.erb

1 个答案:

答案 0 :(得分:1)

自定义视图的表单提交操作是create action:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), builder: FoundationFormBuilder) do |f| %>

并且操作不会告诉在出现错误时呈现新视图。没有任何代码可以提及。因此,要么调用自定义提交操作以在出现错误时呈现自定义视图,要么调用super,而不是调用super,根据某个参数更改操作代码以呈现不同的模板。

如果您想要更清洁的方法,请通过ajax调用从自定义视图中使用devise json API。以下是有关如何使用API​​的链接: http://blog.andrewray.me/how-to-set-up-devise-ajax-authentication-with-rails-4-0/