devise: sign up with username - ruby-on-rails

I create a username column in database. now I want remove email and then user sign up just by username. For this, I can create username field in sign up page, but again I have to complete email field that server create new user, if else, I get validation error of email field. How can I remove email validation and replace it with personal validation of username? and then user just can sign up with enter username and password?
I have below code to:
users_controller.rb:
def user_params
params.require(:user).permit(:username, :email, :password, :password_confirmation, :remember_me)
end
views/devise/registrations/new.html.erb:
<h2>Sign up</h2>
<%= 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, autofocus: true %></div>
<div><%= f.label :username %><br />
<%= f.email_field :username %></div>
<div><%= f.label :password %> <% if #validatable %><i>(<%= #minimum_password_length %> characters minimum)</i><% end %><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "user/shared/links" %>

If you check the documentation you have a section explaining how to do it here.
Personally I wouldn't remove the email from user settings and stick with the suggested on documentation to create a virtual attribute called login.
If you want to remove completely the email, you'll need to remove it with a migration in order to remove the field from the database table and remove it from the model validation.
Also you need to update your views or partials by replacing email with username. Beware you need to update authentication_keys like it's mentioned on docs (use username instead of login)

Related

Rails form_for password_field helper doesn't populate current password

<%= form_for #user, url: user_path do |f| %>
<p>
<%= f.label :password, 'Password:' %><br>
<%= f.password_field :password %>
</p>
I would like the current password to be populated in the password field automatically so that when the #user's information is edited, the request will not fail due to having an empty password.
When using 'text_field', this field does get populated automagically, but password_field seems to disable this ability.
You have to set the value of the password field manually. Rails hides the value for security reasons.
<%= f.password_field :password, value: f.object.password %>

Custom sign-up form in Devise not working

I have looked at other answers on here and have yet to find one. I am creating a Rails 4 app that allows users to sign in and create a profile. I am using Devise gem for user authentication.
What I want to do is have the user also type in their name and a description of themselves during the signup process. When submit the form the database will be updated with this info as well. Here is what I have done:
1) I ran a migration to create the new columns, "name" and "description", in the users table
2) I ran rails generate devise:views. This allows me to access devise>views>registrations>new.html.erb where I included the "name" label and field. I just used the other labels and fields as a guide. I now get an error saying name_field method is undefined. Where are the other ones like email_field and password_field defined?
<h2>Sign up</h2>
<%= 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, :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.label :name %><br />
<%= f.name_field :name %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "devise/shared/links" %>
Any help in getting this working I would greatly appreciate.
There's no method on the Rails form object that says name_field. name_field is not a valid HTML form input type. Did you do find and replace? You should change
<%= f.name_field :name %>
to
<%= f.text_field :name %>
UPDATE
Overriding configure_permitted_parameters in app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, rest_of_user_attrs) }
# you control which attributes can be updated or used for sign in here
end
end
Here's more information for your perusal https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address
#user2623706 have you configured devise for strong parameters. That may be the problem.

Rails registration on landing page to complete registration

I have a home-landing-page that is my root url. I want users to begin the sign up process here where they input only their email, click signup, and continue the registration on a separate page.
This is the part of the form I want on the home-root-landing-page
<div>
<%= f.label :email %><br />
<%= f.email_field :email %>
</div>
This is what the full (separate) signup page looks like. I would like the email address the users entered on the home-root-landing-page to auto populate on this page (after they hit signup and are redirected to this page.)
<h2>Sign up</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :first_name %><br />
<%= f.text_field :first_name %></div>
<div><%= f.label :last_name %><br />
<%= f.text_field :last_name %></div>
<div><%= f.label :profile_name %><br />
<%= f.text_field :profile_name %></div>
<div><%= f.label :email %><br />
<%= f.email_field :email %></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" %>
I'm using devise and I'm having trouble on how I would simply approach this. Thanks for taking a look.
In your view that you are rendering in homepage, set the form action to the signup page /user/signup.
In the signup controller, initialize the #user with the params that you've received from the homepage.
#UsersController
def signup
#user = User.new(params[:user]
end
The above action will render signup view. Now use #user in the form_for. Like:
form_for(#user)
This will auto populate the first name and email.
However, it is apparent that you're using Devise. I'm not sure it will work for its default controllers as it is initilizing the resource from empty hash (i see the following code in source)
def new
resource = build_resource({})
respond_with resource
end
So, you may have to override the registration controller.

update a table which in not devise model on sign up using devise?

How to add value from devise registration form to another table that is not devise table
this is sample code
<div class="signin">
<h2>Register</h2>
<%= 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 :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :full_name %><br />
<%= f.text_field :full_name %></div>
<div><%= f.submit "Register" %></div>
<% end %>
<%= render :partial => "devise/shared/links" %>
</div>
full name is field of profile table and i set device on user table,
and if user enter name i want name full name store in profile table
i dont have any idea how can i do this?
you can use one of the many hooks that are provided by active record models:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-an-object
ie. you could retrieve the profile object of the user, update the record and save it back in an before_save hook.
I got the answer
Put a def in devise model def name same as field name then devise allow you to pass the that field to model, in model/controller you can insert value through params in any table.

Devise edit account information

When I go to the edit_user_registration_path provided by Devise I have fields such as email and username pre-filled.
I want to create custom user profile page with the similar form for edit user information containing additional fields of dependent model. And I want fields be pre-filled.
How should I do it properly?
The default form provided by Devise:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :username %><br />
<%= f.text_field :username %></div>
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, :autocomplete => "off" %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %></div>
<div><%= f.submit "Update" %></div>
<% end %>
Use nested attributes
In your devise user model, if you have other dependent models, you can add a relationship between those models, like has_many and belongs_to. The do this:
Devise user model:
accepts_nested_attributes_for :name_of_other_model
Then in your form you can use fields_for. fields_for docs
Here's also a great railscast of this here

Resources