Rails remembering wrong fields - ruby-on-rails

I have a page which has a login form, as well as a form to register. Here is the code:
<h3>Log In</h2>
<%= form_for Spree::User.new, :as => :spree_user, :url => spree.spree_user_session_path do |f| %>
<%= devise_error_messages! %>
<%= f.email_field :email, placeholder: "Email" %>
<%= f.password_field :password, placeholder: "Password" %>
<div><%= f.submit "Log In", class: "registrationbuttons" %></div>
<% end %>
<h3>Register Now</h2>
<%= form_for Spree::User.new, :as => :spree_user, :url => spree.spree_user_registration_path do |f| %>
<%= f.email_field :email, placeholder: "Email" %>
<%= f.password_field :password, placeholder: "Password" %>
<%= f.password_field :password_confirmation, placeholder: "Confirm Password" %>
<div><%= f.submit "Register", class: "registrationbuttons" %></div>
<% end %>
If a user uses the Log In form, and is asked if they want their browser to remember the password - If they select yes the next time they see this page, fields in the Register Now form (which they may have never user) populate.
How can I ensure only the correct fields get saved?

I found the solution here: http://benjaminjshore.info/2014/05/chrome-auto-fill-honey-pot-hack.html
I added this line:
<input type="password" name="password_fake" id="password_fake" value="" style="display:none;" />
To my 2nd form_for (the fields which were being incorrectly remembered). It now looks like this:
<%= form_for Spree::User.new, :as => :spree_user, :url => spree.spree_user_registration_path do |f| %>
<!-- fake fields are a workaround for chrome autofill getting the wrong fields -->
<input type="password" name="password_fake" id="password_fake" value="" style="display:none;" />
<%= f.email_field :email, placeholder: "Email" %><br>
<%= f.password_field :password, placeholder: "Password" %><br>
<%= f.password_field :password_confirmation, placeholder: "Confirm Password" %><br>
<div><%= f.submit "Register", class: "registrationbuttons" %></div>
<% end %>
Now the field is not remembered.

Related

Custom field tag in devise registration view

I want to add custom field tag in devise registration view but that field doesn't exist in users table. I just want user select some value in that field and i get information about selected value in params at the time of sign up. Can anyone suggest me how to do this?
Devise_registration_view:
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :type, 'Role' %>
<%= f.select :type, %w{Admin Teacher Student Guardian}, :prompt => 'Select', required: true, placeholder: 'Roles' %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
You can use attr_accessor for User model which will help you to get and set value for attribute which is not there in table, Please refer this link. attr_accessor_details
updating answer for adding custom validation for attribute created by attr_accessor
attr_accessor :test_attribute
validate :check_test_attribute
def check_test_attribute
errors.add(:test_attribute, "is missing") if test_attribute.blank?
end

adding a text area field to devise edit form

I have an attribute called discount_info. I would like to create another field in the devise edit form, so user can edit this information. I would like to have the field be a text_area. I'm not sure how to do this in rails.
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :address %><br />
<%= f.email_field :address, autofocus: true %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<%= f.text_area :discount_info, :class => "", :placeholder => "if you want a placeholder" %>
Just add the attribute in the form and permit it in the configure_permitted_parameters method.
<div class="field">
<%= f.label :discount_info %><br />
<%= f.text_area :discount_info %>
</div>
And in the controller
def configure_permitted_parameters
#other code
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:other_attributes, :discount_info) }
end

form_for in devise How it works?

rails g devise:views command generated that view
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :username %><br />
<%= f.text_field :username, :autofocus => true %></div>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
My question is how does it work " form_for(resource, : as=>resource_name, ..."
resource is simple a record (or object) - with respect to Devise, it's usually something called User or similar. The rest of the parameters for form_for are options, detailed in the form_for docs.
I notice that both the :email and :username are calling for the email_field, which is a mistake.

using existing inputs to create form for user to sign in

using User model, created by devise, and Simple Form gem i want to give user ability to log in from main page. i have inputs, created just for it in haml, and want to use them for this:
.login-wrapper
.user-fields
%input{type: "text", placeholder: "username", class: "ribbon-placeholder mail"}
.slide
%input{type: "password", placeholder: "password", class: "ribbon-placeholder password"}
= link_to "#", class: "ribbon-button" do
%span register
.account-arrow
.clearfix
%input{type: "submit", value: "log in", class: "ribbon-button orange-background log-in"}
Ok you can use the form like this. This is just for reference is not exactly form like yours:-
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<div><%= f.label :email %>
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %>
<%= f.password_field :password %></div>
<% if devise_mapping.rememberable? -%>
<div>
<label class="checkbox" for="merchant_remember_me">
<%= f.check_box :remember_me %> Remember Me
</label>
</div>
<% end -%>
<br />
<div><%= f.submit "Sign in" %></div>
<% end %>

Rails nested User Profile fields with Devise not retaining input

I am trying to add forms fields to my Devise user registration view. This has been achieved and the validation runs when I submit the form. However, if I get any form errors, the input data does not re-populate the form field as per the original form although I can see the correct values in my little debugger I've added to the development views.
Here is my view:
<h2>Sign up</h2>
<% resource.build_profile %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :username %> <i>(this cannot be changed so choose wisely)</i><br />
<%= f.text_field :username %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<%= f.fields_for :profile do |profile_form| %>
<div><%= profile_form.label :full_name %><br />
<%= profile_form.text_field :full_name %></div>
<div><%= profile_form.label :birth_date %><br />
<%= profile_form.date_select :birth_date, start_year: Time.now.year, end_year: Time.now.year - 80, order: [:day, :month, :year], prompt: { day: 'Choose day', month: 'Choose month', year: 'Choose year' } %></div>
<div><%= profile_form.label :gender %><br />
<%= profile_form.select :gender, { "Male" => '0', "Female" => '1' } %></div>
<div><%= profile_form.label :postcode %><br />
<%= profile_form.text_field :postcode %></div>
<div><%= profile_form.label :description, "About you" %><br />
<%= profile_form.text_area :description %></div>
<% end %>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>
I don't have a controller code to show because it uses the Devise code inside the Gem. What am I doing wrong / not doing?
You are rebuilding the profile every time with build_profile, it means that when the form in going to be redisplayed, it's using a new instance of profile, not the one with errors. Just change that code so it only builds the profile if one does not exist:
resource.build_profile unless resource.profile
Something like that should work.
Carlos' answer helped me solve this exact issue.
resource.build_profile unless resource.profile
If your user model has a reference to the profile model, try passing
<%= f.fields_for resource.profile do |profile_form| %>
Right now, you're passing a reference to a model, but the form wants an instance.

Resources