Coder Social home page Coder Social logo

devise-guests's Introduction

Devise Guests

Gem Version Tests Ruby Style Guide

A drop-in guest user implementation for devise

(I'm using "user" to mean my devise model, but you should be able to use any model you want, just like devise)

Installation

# install devise first
# gem install devise
# rails g devise:install
# rails g devise User

gem install devise-guests
rails g devise_guests User

Usage

# Where you might use current_user; now you can use

current_or_guest_user

# which returns

current_user # (for logged in users)

=> User<id: 1, email: ...>
# or 

guest_user # ( for anonymous users)

=> User<id: 2, email: guest_RANDOMENOUGHSTRING_@example.com, guest: true>

Transferring Guest to User on Login

During the login process you may want to transfer things from your guest user to the account they logged into. To do so, add the following method to your ApplicationController:

private
def transfer_guest_to_user
  # At this point you have access to:
  #   * current_user - the user they've just logged in as
  #   * guest_user - the guest user they were previously identified by
  # 
  # After this block runs, the guest_user will be destroyed!
  
  if current_user.cart
    guest_user.cart.line_items.update_all(cart_id: current_user.cart.id)
  else
    guest_user.cart.update!(user: current_user)
  end

  # In this example we've moved `LineItem` records from the guest
  # user's cart to the logged-in user's cart.
  #
  # To prevent these being deleted when the guest user & cart are
  # destroyed, we need to reload the guest record:
  guest_user.reload
end

Custom attribute

If you have added additional authentication_keys, or have other attributes on your Devise model that you need to set when creating a guest user, you can do so by overriding the set_guest_user_params method in your ApplicationController:

private
def guest_user_params
  { site_id: current_site.id }
end

Non-standard authentication keys

By default Devise will use :email as the authentication key for your model. If for some reason you have modified your Devise config to use an alternative attribute (such as :phone_number) you will need to provide a method to generate the value of this attribute for any guest users which are created.

Sticking with the :phone_number example, you should define the following method in your application_controller.rb:

private
def guest_phone_number_authentication_key(key)
  key &&= nil unless key.to_s.match(/^guest/)
  key ||= "guest_447" + 9.times.map { SecureRandom.rand(0..9) }.join
end

Validations are skipped when creating guest users, but if you need to rely on future modifications to the guest record passing validations, then you should ensure that this default value for guests is generated in such a way as to be valid.

Prevent deletion of guest records

By default, when signing in from a guest account to an authenticated account, the guest user is destroyed. You have an opportunity through the logging_in_user callback (or logging_in_MODEL if you're not using User) to transfer data from the guest to the main account before destruction occurs.

However, for some situations such as guest-checkout, you may desire that any guest account which makes a purchase does not get destroyed. In that case you can use the skip_destroy_guest_user method to identify when to skip deleting these records. By default this method returns false, indicating that every record is acceptable for destruction, but you could use something like the following to optionally prevent it:

def skip_destroy_guest_user
  guest_user.orders.any?
end

devise-guests's People

Contributors

awead avatar cbeer avatar hackartisan avatar jcoyne avatar joshmenden avatar orangewolf avatar pacso avatar tpendragon avatar tsmmark avatar whereismyjetpack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

devise-guests's Issues

transfer_guest_to_user is not always run on signin

I noticed that transfer_guest_to_user is not always executed on signin.
Reading through the code, I noticed that the logging_in callback is triggered by the helper method current_or_guest_user.
So if you don't call this method sometimes during sign_in, transfer_guest_to_user wont be executed I guess ?

Suggestion

It would be great if this gem provide a before_filter, lets say: I want to update a visitor to be a guest user, the visitor does not have a session, the guest user will have a session. So then I can use the guest user in some places of my application instead of the whole application.

Thanks,

Victor.

Not an issue

As there is no outright manner in which to express appreciation, one must resort to polluting the 'issue' sphere. (Feel free to close it at any time)

What a highly useful tool with a focussed purpose (the joy of one-trick ponies) and resolved by a pithy single line...
and a couple of other helpers. True marvel!

imcompabilities when using omniauth-facebook

Hi, Just after I installed and configured this module I got a problem.

In my header I have this conditional

<% if current_or_guest_user.guest == false %>
show header for logged in users
<% else %>
show header for guest users (logged out users)
<% end %>

Well it worked normally before I installed this gem.

Now after I try to log in through facebook I get this error

undefined method `_logging_in_user_callbacks'

Im trying to debug the issue but still no change, any idea?

this wont work with typical action cable

env['warden'].user is not set:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    include SetCurrentRequestDetails

    identified_by :current_user, :current_account, :true_user
    impersonates :user

    delegate :params, :session, to: :request

    def connect
      self.current_user = find_verified_user
      set_request_details
      self.current_account = Current.account

      logger.add_tags "ActionCable", "User #{current_user.id}", "Account #{current_account.id}"
    end

    protected

    def find_verified_user

      if (current_user = env["warden"].user(:user))
        current_user
      else
        reject_unauthorized_connection
      end
    end

    def user_signed_in?
      !!current_user
    end

    # Used by set_request_details
    def set_current_tenant(account)
      ActsAsTenant.current_tenant = account
    end
  end
end

Non-standard authentication keys

As per #26, the documentation should be updated to provide instructions on how to handle the situation where :email isn't your first Devise::authentication_keys

License missing from gemspec

Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec
via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

There is even a License Finder to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec.
Including a license in your gemspec is a good practice, in any case.

How did I find you?

I'm using a script to collect stats on gems, originally looking for download data, but decided to collect licenses too,
and make issues for missing ones as a public service :)
https://gist.github.com/bf4/5952053#file-license_issue-rb-L13 So far it's going pretty well

Calling guest_user creates guest_user instead of checking if guest_user exists/is set

Just wanted to mention that creating a guest user just from calling guest_user is unintuitive and doesn't parallel the devise current_user. With current_user we can rely on it returning nil if the current_user isnt set. However trying the same with guest_user leads to the creation of a guest_user record instead of whether or not a guest record already exists. I encountered a bug in my code where I was checking if guest_user.

Is there an appetite for changing this?

Callbacks don't get defined

If ActionController::Base gets loaded before the routes.rb file is parsed i.e a gem touches ActionController::Base when its getting loaded, then the callbacks are never defined on ActionController::Base. I think we need to keep an array of objects that have included the Helpers module and define_concern_callback should then call define_callback on the controllers.

undefined local variable or method `current_or_guest_user'

Hello,

I don't know what I'm doing wrong but I get this error in my controllers and templates.
I just added devise-guests to my Gemfile (version 0.3.2) and ran rails g devise_guests User.

What should I do to be able to access the current_or_guest_user method in my controller?

Additional maintainers?

As the title suggests ... do you need some additional help? Happy to give you a hand with this. It could do with a little love ☺️

not thread safe

I don't actually use devise/devise-guests, but was reviewing the devise-guest code for ideas on how to upgrade to BL 3.7 in my non-devise app.

I noticed this code:

    def unique_#{mapping}_counter
      @@unique_#{mapping}_counter ||= 0
      @@unique_#{mapping}_counter += 1
    end

https://github.com/cbeer/devise-guests/blob/master/lib/devise-guests/controllers/helpers.rb#L80

I wanted to point out that is not thread safe, for a Rails running under multi-threaded request dispatch. It uses global state, shared between requests, in the @@unique_ variable, but does not synchronize access to this global state from requests, which may be running concurrently in different threads.

Many Rails apps don't do concurrent request dispatching anyway. It requires an app server that can handle concurrent requests (passenger enterprise, puma, maybe a few others in unusual configurations). In Rails3 it also requires you to set config.threadsafe!, although in Rails4 that is on by default.

So it might not matter that it's not thread-safe if hardly anyone runs Rails with concurrent request dispatch anyway, and I probably won't be using this gem myself anyway either, but thought I'd point it out since I noticed it, in case you are concerned.

Persistent engagement with guest user

I need to persistently track Guest users to do activities like comments; vote etc. Until they sign up
One way is to :
I can create/sign in the guest user using current_or_guest_user helper method and change their email when they sign up with password and show all their past activities.

Is there any other quick method to do that. Or are you planning to add same.

How to use it with --api mode?

It'd be really useful to have some guideline that takes using the gem with rails new project --api mode into consideration.

By default, the API mode disables sessions, and all that's described in How To: Create Guest User that links here is based on the session.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.