Mi rendo conto che è in ritardo, ma questo potrebbe essere utile agli altri. Ho avuto un requisito simile a te. Fondamentalmente, volevo che un utente inserisse un indirizzo email e persistesse come ospite. Una volta che l'utente viene promosso a un utente "normale", riabilitano l'autenticazione della password. In primo luogo, ho creato una strategia di custode basata sulla gemma devise-gullible. Ho fatto una modifica al metodo authenticate
:
class Guest < Authenticatable
def authenticate!
resource = mapping.to.find_for_database_authentication(authentication_hash)
if resource
if resource.respond_to?(:guest?) and resource.guest?
success!(resource)
else
fail(:regular_user)
end
else
fail(:invalid)
end
end
end
ho definire un utente ospite nel mio modello utente nel modo seguente:
def guest?
self.roles.length == 0
end
sto usando CanCan con disposizione testamentaria e un HABTM per gestire i ruoli. Attualmente, ho un utente "normale" e un utente "admin". Un utente è un ospite se non ha ancora assegnato un ruolo.
Quindi, è necessario eseguire l'override del regolatore testamentaria iscrizioni:
class Users::RegistrationsController < Devise::RegistrationsController
prepend_before_filter :allow_params_authentication!, :only => :create
def create
resource = warden.authenticate(:guest,
{ scope: resource_name,
recall: "#{controller_path}#new" })
if resource
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_sign_in_path_for(resource)
elsif warden.winning_strategy.message == :regular_user
set_flash_message :notice, :regular_user if is_navigational_format?
redirect_to new_session_path(resource_name)
else
super
end
end
end
Si noti che l'idea è che si cerca di autenticare un utente che esegue solo la strategia ospite. Se è già registrato come ospite, basta registrarlo normalmente. Se la strategia ospite fallisce perché è registrato, ma ora è un utente normale, reindirizza alla normale pagina di accesso.
Ora è possibile mantenere alcune informazioni limitate che potrei desiderare di raccogliere da un ospite e non richiedere che debba effettuare una registrazione completa. Io uso un normale modello User:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :omniauthable,
:token_authenticatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_and_belongs_to_many :roles
def self.new_with_session(params, session)
super.tap do |user|
if user.password.blank?
user.password = Devise.friendly_token[0,31]
# Also, we don't need to do email confirmation in this case.
# The user will have the guest role, and we'll do a confirmation
# when we promote him to a 'regular' user.
user.skip_confirmation!
end
end
end
def has_role?(role)
!!self.roles.find_by_name(role.to_s.camelize)
end
end
Nota che generare automaticamente una password build_with_session
. È possibile inviare un token di autenticazione al momento della scelta e richiedere all'utente di impostare una nuova password in quel momento. Dovrai anche cambiare il suo ruolo in modo che diventi un utente normale (o fai qualunque cosa tu voglia notare che non è più un ospite).
Ecco la mia parziale che appare in prima pagina:
<%= simple_form_for(resource,
as: resource_name,
url: user_registration_path,
defaults: { required: false },
html: { class: 'well' },
wrapper: :bootstrap,
validate: true) do |f| %>
<%= f.error_notification %>
<fieldset>
<legend>New here? Let's get started!</legend>
<%= f.input :email, placeholder: '[email protected]', validate: { uniqueness: false } %>
<%= f.button :submit, "Get my quote!", class: 'btn-primary' %>
</fieldset>
<% end %>
Così, questa forma funziona sia come registrazione degli ospiti e form di login.L'unica cosa che non mi interessa davvero tanto è che il controller delle registrazioni sta gestendo un'autenticazione, ma non ho visto un modo immediato attorno a questo.
Ho implementato questa strategia nella mia directory lib locale. Assicurati di impostare il percorso di caricamento in modo appropriato e aggiungi require 'devise_guest'
a config/initializers/devise.rb
.
Sì, questo è fondamentalmente quello che sto cercando di fare. Sperimenterò per vedere come funziona. – spinlock
buona fortuna - ho implementato qualcosa di simile e funziona benissimo - l'ora di andare a dormire qui, ma tornerò a controllare la mattina e cercherò di rispondere a qualsiasi domanda se nessun altro li raccoglie – chrispanda