Reputation: 587
I'm making a to-do list with Rails. Therefore I made a user-model(email and password). I want that the user will be able to edit there account so I made a edit and update action on the user controller I also have a user model. Everything works great but my issue is that on the settings view the text_field for updating the email is already prefilled with their current email adress in the model. I want to disable the prefilling because of design aspects (content of the placeholder should be readable right away). I know that when I will solve this problem, there will be another issue with the user model. For example if a user only wants to change the password the user will get an error message such as: "Email can't be blank" and "Email is Invalid"... I was able to modify the minimum length validation for the password if the password is blank because I knew that "has_secure_password" enforces presence validations upon object creation. So I knew new users won't be able to sign up with blank passwords. But how can I create the same effect for the email validation? I haven't found a solution yet, I would really appreciate if someone could help me. Thanks in advance!
Questions:
users_controller.rb (controller)
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:success] = "Profile updated!"
redirect_to @user
else
render 'edit'
end
end
edit.html.erb (view)
<% provide(:title, "Settings") %>
<h4>SETTINGS</h4>
<h5>User Edit</h5>
<%= @user.email %>
<div class="settings">
<%= form_for(@user) do |f| %>
<%= render 'layouts/error_messages' %>
<p>Change Email:</p>
<%= f.text_field :email, placeholder: "New Email", class: "formfield" %>
<p>Change Password:</p>
<%= f.password_field :password, placeholder: "New Password", class: "formfield" %>
<%= f.password_field :password_confirmation, placeholder: "New Password Confirmation", class: "formfield" %>
<%= f.submit "Save Changes", class: "form_button" %>
<% end %>
<%= link_to "Delete my Account", '#' %>
</div>
user.rb (model)
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
end
Upvotes: 1
Views: 2830
Reputation: 596
1 - Maybe not the solution you are looking for but you could clear the field with javascript.
2 - You can use conditional validations, from the rails docs:
class Order < ActiveRecord::Base
validates :email, presence: true, unless: :email_present?
def email_present?
self.email.blank?
end
end
Code not tested, but must be close to a working solution.
Upvotes: 0
Reputation: 1
Just use form_tag, instead of form_for
like so <%= form_tag '/some_url' do %> http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html
To allow blank emails in your validation add allow_blank: true
validates :email, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false },
allow_blank: true
http://edgeguides.rubyonrails.org/active_record_validations.html#allow-blank Validating both presence and allow_blank does not make sense.
Upvotes: 0
Reputation: 5105
UPDATE
You have to add attribute with value=nil
for the first time in your edit form to keep your placeholder show up.
<%= f.text_field :email, value: nil, placeholder: "New Email", class: "formfield" %>
Then, to avoid a validation in your model you can add value email in your controller before validation. For instance:
def update
@user = User.find(params[:id])
user_params[:email] = @user.email if params[:user][:email].nil?
if @user.update_attributes(user_params)
flash[:success] = "Profile updated!"
redirect_to @user
else
render 'edit'
end
end
I hope it can help you
Upvotes: 0
Reputation: 33542
How to disable the pre-fill form in Rails?
Adding value: nil
for the field
you want to disable pre-fill will do.
For example,
<%= f.text_field :email, value: nil, placeholder: "New Email", class: "formfield" %>
What should be modified to accept blank emails in the settings form without updating the email to blank in database?
Erase presence: true
in the email validation.
validates :email, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
Upvotes: 3