Reputation: 1371
I have a multistep form. It's a bit complicated, cause basically first the user gets created through registrations controller, then get's redirected to a form. Speaking precisely, it's not a multistep form, but more of a two-step registration. To do validations with those is quite triky, but I figured the way, which works. In my User.rb I defined validations as follows:
validates :first_name, presence: true, :on => :create
validates :last_name, presence: true, :on => :create
validates :street, presence: true, :on => :update
But now I am having issues, with showing the errors to a user on that update step. I have the update action in my 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
So, if the User can't be updated, cause the validations have failed, I would love to show error messages about what went wrong. For this in my address.html.erb I defined this behaviour:
<%= 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>
This won't show the errors, but throws active record error instead:
ActiveRecord::RecordInvalid in UserStepsController#update
Validation failed: Street can't be blank
Extracted source (around line #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
What am I doing wrong?
Upvotes: 0
Views: 184
Reputation: 1371
The problem was the update action. I changed it as follows.
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
I also could change my view, to lead the the shared error messages:
<%= form_for @user, url: wizard_path do |f| %>
<%= render "devise/shared/error_messages" %>
This works for both creating and updating a @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 %>
Upvotes: 0
Reputation: 1920
update vs update!
. If I remember update!
runs save!
instead of save
on model. It means that it runs exception if record is not valid. update
will try to call save
method which runs validations
Upvotes: 1