Generando un sistema de invitaciones con la gema devise_invitable
Motivación
En rails existe una gema que nos permite enviar invitaciones por email, y ver cuando estas han sido aceptadas, esto puede servir para darle habilidades especiales a un usuario si ha invitado a 5 personas, o cuando queremos lanzar una aplicación sin registro abierto y que los usuarios deban recibir una invitación o incluso para crear una cuenta a un usuario pero que luego el deba ingresar para crear su propio password.
Setup
Para probarla crearemos un proyecto nuevo llamado invitaciones y luego agregaremos las siguientes gemas al gemfile
gem 'devise'
gem 'devise_invitable'
Después instalamos las gemas con:
bundle
La siguiente parte es muy común, tenemos que correr el generador de devise y luego crear un modelo de usuario bajo devise.
rails generate devise:install
rails generate devise user
Agregando las invitaciones
Ahora viene la parte donde agregaremos las invitaciones
rails generate devise_invitable:install
rails generate devise_invitable user
La última línea generará automáticamente una migración que nos permitirá guardar la información de la invitación en el modelo de usuario, dentro de la migración encontraremos campos como los siguientes:
add_column :users, :invitation_token, :string
add_column :users, :invitation_created_at, :datetime
add_column :users, :invitation_sent_at, :datetime
add_column :users, :invitation_accepted_at, :datetime
add_column :users, :invitation_limit, :integer
add_column :users, :invited_by_id, :integer
add_column :users, :invited_by_type, :string
add_index :users, :invitation_token, :unique => true
Corremos las migraciones con:
rake db:migrate
Luego con el servidor corriendo entraremos a:
localhost:3000/users/invitation/new
Y desde ahí mismo podemos enviar una invitación a un email a elección.
Como todavía no tenemos configurado nuestro servidor de mail probablemente obtendremos un error como:
Para solucionarlo podemos utilizar una configuración de envío de emails como la que aparece en el siguiente artículo:
http://blog.desafiolatam.com/recuperar-contrasenas-con-devise-y-gmail/
Después de eso debemos reiniciar el servidor, al intentarlo neuvamente recibiremos un correo como el siguiente:
Si entramos al link de aceptar del email desde un tab privado del navegador (o cerramos sesion primero) veremos un formulario con la opción de ingresar nuestro nuevo password.
¿Cómo podemos ver a los usuarios invitados de un usuario?
Para lograr esto tenemos que agregar al modelo de usuario
has_many :invitations, :class_name => self.to_s, :as => :invited_by
Agregando la línea anterior ahora podemos acceder a las invitaciones realizadas con current_user.invitations
y dentro de una vista podemos mostrar la cantidad de invitaciones enviadas con: <%= current_user.invitations.count %>
Ver las invitaciones que han sido aceptadas es un poco más difícil, la gema agrega scopes que nos permiten ver todos los usuarios que han aceptado las invitaciones, pero es útil agregar un método de instancia que nos permite ver directamente los usuarios que aceptaron la invitación de un usuario en específico.
def invitations_accepted
invitations.where.not("invitation_accepted_at": nil)
end
De esa forma podemos ver la cantidad de usuarios que han aceptado la invitación con:
current_user.invitations_accepted.size
Redireccionando después de enviar la invitación
Para modificar este comportamiento podemos agregar dentro del application controller (o si creaste el controller de invitable) el método after_invite_path_for
Ejemplo:
def after_invite_path_for(inviter)
"http://www.google.cl/#{inviter.id}"
end
Te invito a ver la documentación oficial de la gema
https://github.com/scambra/devise_invitable