Follow Along as I Stumble on the Path to Learning RoR

Posts tagged “devise

Removing Requirement for “Current Password” in Devise

I’m using the Devise gem and I wanted to only require the “Current Password” field for account updates when the password was being changed.  For other changes, I didn’t want to require the field.  This requirement was also important for me because some of my Users sign-up using Facebook.  In these cases, they might not have a password and would not be able to make any account changes.

I found my answer in this SO question and this Devise article.

First, you need a Registrations controller for your resource (in my case, the resource being used with Devise is my User model), if you don’t have one already:

in controllers:

  1. Create users/registrations_controller.rb
    Users::RegistrationsController < Devise::RegistrationsController
    
    def update
    
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    
       if resource.update_with_password(params[resource_name])
         set_flash_message :notice, :updated if is_navigational_format?
         sign_in resource_name, resource, :bypass => true
         respond_with resource, :location => after_update_path_for(resource)
       else
         clean_up_passwords(resource)
         respond_with_navigational(resource){ render_with_scope :edit }
       end
    
    end
  2. Add this to routes.rb
    devise_for :users, controllers: {registrations: 'registrations'}

Next, add new methods to your model (user.rb in my case):

#to remove the current password check if updating a profile originally gotten via oauth (fb, twitter)


  def update_with_password(params={})
    if params[:password].blank?
      params.delete(:current_password)
      self.update_without_password(params)
    else
      self.verify_password_and_update(params)
    end
  end

  def update_without_password(params={})

    params.delete(:password)
    params.delete(:password_confirmation)
    result = update_attributes(params)
    clean_up_passwords
    result
  end
  def verify_password_and_update(params)
    #devises' update_with_password 
    # https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb
    current_password = params.delete(:current_password)

    if params[:password].blank?
      params.delete(:password)
      params.delete(:password_confirmation) if params[:password_confirmation].blank?
    end

    result = if valid_password?(current_password)
      update_attributes(params)
    else
      self.attributes = params
      self.valid?
      self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
      false
    end

    clean_up_passwords
    result
  end
Advertisements

Fixing “SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed” Error on Windows

When I tried to implement OmniAuth, I received this error “SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed”.  Essentially, I was getting this error because the code was searching for an SSL certificate on my PC.

I didn’t have a SSL certificate for my PC, fortunately I found a work around to fix this.


Tracking Conversions in Google Analytics for Devise User Sign-Ups

I wanted to track user sign-ups as a goal, while using the Devise gem.  The Devise gem redirects users to the root path as a default, which I wanted to keep.  The problem with that is that I didn’t want to every visit to the root page as a conversion, only the ones that were a redirect after the user registered.

Here’s what I ended up doing:

In the users#registrations_controller.rb, I added this flash:

flash[:user_signup] = true

then in the root path view, I added:

<% if flash[:user_signup] == true %>
<%= render :partial => “shared/google_analytics_user_sign_up” %>  # edited google analytics code
<% else %>
<%= render :partial => “shared/google_analytics” %> # regular google analytics code
<% end %>

In the google_analytics_user_sign_up partial, I have this:

<script>
(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’//www.google-analytics.com/analytics.js’,’ga’);

ga(‘create’, ‘UA-99999999-1’, ‘foo.com’);
ga(‘send’, ‘pageview’, ‘/special/path’);
</script>
<!– Google Analytics end –>

In Google Analytics, add it as a goal, in the destination add:

/special/path

You can name the path whatever you want, as long as they match in the code and in Google Analytics.  Just make sure that it’s unique, it’s not the path of another url someone might go to.


Making Devise Views Use SSL

I had trouble figuring out the best way to make Devise views secure.  Devise recommends making all pages secure since they use cookies, but I had some views that I could not make secure, so I needed to figure out how to make some views, including the Devise ones, secure.  Normally I would indicate force_ssl in the controller, but Devise is an installed gem that I didn’t want to mess with.

I found the answer after digging awhile, here.

#for Rails 3.1 and above, in config/environments/production.rb
config.to_prepare { Devise::SessionsController.force_ssl }
config.to_prepare { Devise::RegistrationsController.force_ssl }
config.to_prepare { Devise::PasswordsController.force_ssl }

Welcome Email After Devise Confirmation

After getting :confirmable working for the Rails Devise gem, I wanted to create a welcome email that would tell the user that they successfully confirmed their account and welcoming them to the site.

Here are the steps I took:

  1. Create the email views and placed them in my mailer directory
  2. I use User.rb as my model, so I created an observer to watch changes to the models.  In that app/models/user_observer.rb, I put this code:

def after_save(user)
# Send Welcome Mail after confirmation
if user.confirmed_at_changed?
Mailer.welcome_mail(user).deliver!
end
end

This watches for the change in confirmed_at, then sends my email (welcome_mail).

3.  In application.rb, added this:

config.active_record.observers = :user_observer


Sign Out Wasn’t Working with Devise for Me

Devise’s Sign Out wasn’t working for me. I’ve seen other solutions, but they didn’t worked for me. However, I found an answer that worked for me on Devise’s wiki.

Previously, I used this link:

<%= link_to "Logout", destroy_user_session_path, method: :delete %>

However, that wasn’t working, so I changed (in config/initializers/devise.rb in ):

config.sign_out_via = :delete

to:

config.sign_out_via = :get

and revised the link to (removed “method: :delete”):

<%= link_to "Logout", destroy_user_session_path %>