I'm using Rails 5. I have a form with fields like the below
<%= form_for(@user) do |f| %>
...
<div class="profileField">
<%= f.label :first_name %><br/>
<div class="field"><%= f.text_field :first_name, :size => 20, :class => 'textField', :tabIndex => '1' %></div>
</div>
...
<div class="profileField">
Birthday <% if !@user.errors[:dob].empty? %><span class="profileError"> <%= @user.errors[:dob].join(', ') %></span><% end %> <br/>
<div class="field">
<%= f.text_field :dob_string, :value => f.object.dob_string , :size => "20", :class => 'textField', placeholder: 'MM/DD/YYYY', :tabIndex => 1 %>
</div>
</div>
When the form submits, it invokes this logic in my controller
def update
@user = current_user
@user.dob_string = user_params[:dob_string]
if !@user.errors.any? && @user.update_attributes(user_params)
last_page_visited = session[:last_page_visited]
if !last_page_visited.nil?
session.delete(:last_page_visited)
else
flash[:success] = "Profile updated"
end
redirect_to !last_page_visited.nil? ? last_page_visited : url_for(:controller => 'races', :action => 'index') and return
end
@country_selected = !@user.address.nil? && !@user.address.country.nil? ? @user.address.country : Country.cached_find_by_iso('US')
@states = @country_selected.states.sort_by {|obj| obj.name}
render 'edit'
end
My question is, if there is an error in my form, how do I get the original values that someone entered before submitting the form to remain instead of the values that were previuosly saved? Right now, if an error occurs, all the values the user previously entered are replaced by what was saved before.
The solution didn't work. I have a "dob" field (which is a PostGres DATE column), and hwen I entered an invalid value (eg "1234") and clicked "Save", everything saved without an error being thrown. Below is my user model. I also added the definition of my date field in my view.
class User < ActiveRecord::Base
has_many :assignments
has_many :roles, through: :assignments
belongs_to :address, :autosave => true #, dependent: :destroy
accepts_nested_attributes_for :address
attr_accessor :dob_string
def dob_string
@dob_string || (self.dob ? self.dob.strftime('%m/%d/%Y') : "")
end
def dob_string=(dob_s)
date = dob_s && !dob_s.empty? ? Date.strptime(dob_s, '%m/%d/%Y') : nil
self.dob = date
rescue ArgumentError
errors.add(:dob, 'The birth date is not in the correct format (MM/DD/YYYY)')
@dob_string = dob_s
end
def role?(role)
roles.any? { |r| r.name.underscore.to_sym == role.to_s.underscore.to_sym }
end
def admin?
role? "Admin"
end
def name
name = first_name
if !first_name.nil?
name = "#{name} "
end
"#{name}#{last_name}"
end
This will happen automatically if you load the attributes into the user slightly differently. the usual way to do it is something more like this:
def update
@user = User.new(user_params)
if @user.save
# do stuff for when it saves correctly
else
# re-display the edit page with render :edit
Note: saving returns false if there are errors, so you don't need to check errors separately from this
But I see you're only letting them update the current user... (which is good). in which case you'll want:
def update
@user = current_user
# applies the attributes without saving to db
@user.assign_attributes(user_params)
if @user.save
# do stuff for when it saves correctly
else
# re-display the edit page with render :edit
Doing either of these will allow the @user
object to receive the attributes entered by the user - and that will then be passed to the form
and be displayed.
Note: this assumes you are using something like form_for @user
in your view (you didn't include that snippet)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.