trickydiddy
trickydiddy

Reputation: 587

How can I disable pre-fill form fields in Rails?

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:

  1. How to disable the pre-fill form in Rails?
  2. What should be modified to accept blank emails in the settings form without updating the email to blank in database?

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

Answers (4)

C&#225;ssio Godinho
C&#225;ssio Godinho

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

Oleksandr Shestopal
Oleksandr Shestopal

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

akbarbin
akbarbin

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

Pavan
Pavan

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

Related Questions