Using Devise with Omniauth I was successfully able to allow users to login with their Facebook accounts. With the help of the Omniauth wiki I was also able to disable having to put in a password when editing their account.
The current problem I'm faced with is hiding the password fields in my registrations#edit
view if they signed up via Facebook. As a newcomer to both gems I'm still trying to adjust. So when it comes to setting up the necessary helper method(s) I'm sort've at a loss.
As instructed by the wiki here's what my Registrations controller looks like:
class RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters, if: :devise_controller?
def update
@user = User.find(current_user.id)
successfully_updated = if needs_password?(@user, params)
@user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
else
# remove the virtual current_password attribute
# update_without_password doesn't know how to ignore it
params[:user].delete(:current_password)
@user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
end
if successfully_updated
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case their password changed
sign_in @user, :bypass => true
redirect_to after_update_path_for(@user)
else
render "edit"
end
end
private
# check if we need password to update user data
# ie if password or email was changed
# extend this as needed
def needs_password?(user, params)
user.email != params[:user][:email] ||
params[:user][:password].present? ||
params[:user][:password_confirmation].present?
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
end
And here is my registrations#edit
view:
<% provide :title, 'Edit Profile' %>
<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><%= 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 :email %><br />
<%= f.email_field :email %></div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<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, autocomplete: "off" %></div>
<div><%= 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><%= f.submit "Update" %></div>
<% end %>
UPDATE
After some extensive research I was able to find a question that inderictly answered what I was looking for in terms of hiding the input fields (second to last comment in the question). The only problem is that for some reason it triggers a password validation error despite it not being there...
<div>
<%= f.label :first_name %><br />
<%= f.text_field :first_name %>
</div>
<div>
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>
<% if user_signed_in? && !current_user.provider == 'facebook' %>
<div>
<%= f.label :email %><br />
<%= f.email_field :email %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<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 :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>