Note that there are some explanatory texts on larger screens.

plurals
  1. POEditing Users With Devise and Omniauth
    primarykey
    data
    text
    <p>I'm working through the Railscast on implementing Devise and OmniAuth (along with the Devise <a href="https://github.com/plataformatec/devise/wiki/OmniAuth%3A-Overview" rel="nofollow noreferrer">documentation</a>) -- currently, I've got a site going where visitors can sign up using their facebook accounts or by filling out a form.</p> <p>I'm running into trouble when users that sign up via OmniAuth try to edit their profiles, though. Devise looks for the user's current password when they submit changes to their profiles, but those that logged in with facebook don't know their passwords (they're set automatically in the user model):</p> <pre><code> def self.find_for_facebook_oauth(auth, signed_in_resource=nil) user = User.where(:provider =&gt; auth.provider, :uid =&gt; auth.uid).first unless user user = User.create(first_name:auth.extra.raw_info.first_name, last_name:auth.extra.raw_info.last_name, provider:auth.provider, uid:auth.uid, email:auth.info.email, password:Devise.friendly_token[0,20] ) end user end </code></pre> <p>When a user edits his information, the app should not require password confirmation if he set up his account through OmniAuth. The tutorial suggests that the handy password_required? method will help me achieve this outcome. Specifically, adding this method to the user model means that it should only return true if the user didn't sign up through OmniAuth (the provider attribute would be nil in that case):</p> <pre><code>def password_required? super &amp;&amp; provider.blank? end </code></pre> <p>Thus, a piece of code like: </p> <pre><code>&lt;%= form_for(resource, :as =&gt; resource_name, :url =&gt; registration_path(resource_name), :html =&gt; { :method =&gt; :put }) do |f| %&gt; &lt;%= devise_error_messages! %&gt; &lt;%= render :partial =&gt; "essential_user_info_inputs", :locals =&gt; { :f =&gt; f } %&gt; &lt;%= render :partial =&gt; "inessential_user_info_inputs", :locals =&gt; { :f =&gt; f } %&gt; &lt;% if f.object.password_required? %&gt; &lt;%= render :partial =&gt; "password_inputs", :locals =&gt; { :f =&gt; f } %&gt; &lt;%= f.label :current_password %&gt; &lt;i&gt;(we need your current password to confirm your changes)&lt;/i&gt;&lt;br /&gt; &lt;%= f.password_field :current_password %&gt; &lt;% end %&gt; &lt;%= f.submit "Update" %&gt; &lt;% end %&gt; </code></pre> <p>would theoretically only display password inputs when needed. It also suggests that Devise has built in logic saying that OmniAuth users don't need to use passwords to edit their accounts. I have no idea if this is true, but the tutorial kind of makes it look like that. But when an OmniAuth user tries to edit his account, I get "Current password can't be blank." Same thing with non-OmniAuth users (this makes sense, since the password fields don't show up on those users' edit pages either).</p> <p>Some poking around confirms that the password_required? method is returning false, both when the user signed up through OmniAuth and through the site's regular user signup. Even when I change it to simply run the superclass method, it returns false. </p> <p>Any ideas of what's going on with the password_required method? I can't find anything about it anywhere, but I feel like that's what's tripping things up right now.</p> <h3>Update:</h3> <p>This is now working, but not using the method outlined in the Railscast, which relies on requires_password? method, a topic that I still know nothing about. Instead, I implemented the solution outlined <a href="https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password" rel="nofollow noreferrer">here</a>, as suggested <a href="https://stackoverflow.com/questions/13436232/editing-users-with-devise-and-omniauth#comment18368874_13436232">here</a>. So I am now only requiring passwords to update non-OmniAuth accounts with the code:</p> <pre><code>class Users::RegistrationsController &lt; Devise::RegistrationsController def update @user = User.find(current_user.id) email_changed = @user.email != params[:user][:email] is_facebook_account = !@user.provider.blank? successfully_updated = if !is_facebook_account @user.update_with_password(params[:user]) else @user.update_without_password(params[:user]) end if successfully_updated # Sign in the user bypassing validation in case his password changed sign_in @user, :bypass =&gt; true redirect_to root_path else render "edit" end end end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload