Многоступенчатые проверки с Wicked: проверка не пройдена: улица не может быть пустой - PullRequest
0 голосов
/ 21 января 2020

У меня многоэтапная форма. Это немного сложно, потому что сначала пользователь создается через контроллер регистрации, а затем перенаправляется в форму. Точнее говоря, это не многошаговая форма, а скорее двухступенчатая регистрация. Провести валидацию с ними довольно сложно, но я понял, как это работает. В моем User.rb я определил проверки следующим образом:

validates :first_name, presence: true, :on => :create
validates :last_name, presence: true, :on => :create
validates :street, presence: true, :on => :update

Но теперь у меня возникают проблемы с отображением ошибок пользователю на этом этапе обновления. У меня есть действие по обновлению в моем UserStepsController:

class UserStepsController < ApplicationController
    include Wicked::Wizard
    steps :address
    #respond_to :html, :js

    def show
      @user = current_user || User.from_omniauth(request.env["omniauth.auth"])
      render_wizard
    end


    def update
      @user = current_user || User.from_omniauth(request.env["omniauth.auth"])
        if @user.update!(user_params)
            render_wizard @user
        else
            render :show
        end
    end


    private

    def user_params
        params.require(:user).permit(:email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :street, :house_number, :city, :zip_code)
    end

    def redirect_to_finish_wizard(options = nil, params = nil)
        redirect_to new_user_profile_path(current_user)
    end

end

Итак, если пользователь не может быть обновлен, потому что проверки не пройдены, я хотел бы показать сообщения об ошибках о том, что пошло не так. Для этого в моем адресе. html .erb Я определил это поведение:

<%= form_for @user, url: wizard_path do |f| %>
    <% if @user.errors.any? %>
        <div class="error_explanation">
            <h2><%= pluralize(@user.errors.count, "error") %> prevented this record from being saved:</h2>
                <ul>
                    <% @user.errors.full_messages.each do |message| %>
                        <li><%= message %></li>
                    <% end %>
                </ul>
        </div>
    <% end %>

        <div class="row second 1">
            <div class="column">
              <div class="field wizard">
                <%= f.label :street %><br />
                <%= f.text_field :street, class: 'form-control' %>
              </div>
            </div>

Это не будет отображать ошибки, но вместо этого выдает ошибку активной записи:

ActiveRecord::RecordInvalid in UserStepsController#update
Validation failed: Street can't be blank

Извлечено источник (около строки # 14):

12 def update
13 @user = current_user || User.from_omniauth(request.env["omniauth.auth"])
14 if @user.update!(user_params)
15 render_wizard @user
16 else
17 render :show

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 21 января 2020

update vs update!. Если я помню, update! работает save! вместо save на модели. Это означает, что запускается исключение, если запись недействительна. update попытается вызвать save метод, который запускает проверки

0 голосов
/ 21 января 2020

Проблема заключалась в действии обновления. Я изменил это следующим образом.

def update
      @user = current_user || User.from_omniauth(request.env["omniauth.auth"])
        if @user.update_attributes(user_params)
            render_wizard @user
        else
            render :address
        end
    end

Я также мог бы изменить свое представление, чтобы оно выводило общие сообщения об ошибках:

<%= form_for @user, url: wizard_path do |f| %>
<%= render "devise/shared/error_messages" %>

Это работает как для создания, так и для обновления @user:

<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-error">
      <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
    <% @user.errors.full_messages.each do |message| %>
      <li>* <%= message %></li>
    <% end %>
    </ul>
  </div>
<% end %>
...