devise
devise es una gema ruby de autentificación (¿y autorización?) – cuyo único aspecto simpático, para mí, es su origen latino.
Aparte de ésto mi prejuicio (derivado solamente de su uso) es que tiene rutas poco intuitivas (/users/sign_up, comme on!) y que qué raro que el logout se haga con el verbo DELETE… más papista que el papa.
Pero me encuentro en un estado que no me puedo permitir cambiarla por Sorcery, por ej. Así es que he aquí mi embestida.
undefined method
tengo el siguiente bug – al parecer en el siguiente action
user_registration POST /users(.:format) users/registrations#create
– porque puedo entrar a new (GET /users/sign_up), pero luego algún tipo de Ajax me deja en /users con el siguiente mensaje
NoMethodError in Users::RegistrationsController#create undefined method `active_for_authentication?' for #<Modelo:0x0000000b894c10>
que efectivamente es lo mismo que sale si intento registrarme.
log
si miramos el log/development.log notemos que justo antes del error se crea un
Modelo pero no un usuario:
Started POST "/users" for 127.0.0.1 at 2013-04-18 10:29:39 -0400 Processing by Users::RegistrationsController#create as HTML Parameters: {"utf8"=>"?", "authenticity_token"=>"SkWyyV9fJ6XoAtsR8ij9ecWof6bUGE5uNYqp1iSrXPM=", "role"=>"modelo", "user"=>{"name"=>"", "identificat ion"=>"", "email"=>"webmaster@numerica.cl", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "other_model"=>{"some_id"=>""}, "commit"=> "Regístrate"} ESC[1mESC[36m (0.2ms)ESC[0m ESC[1mBEGINESC[0m ESC[1mESC[35m (0.1ms)ESC[0m COMMIT ESC[1mESC[36m (0.1ms)ESC[0m ESC[1mBEGINESC[0m ESC[1mESC[35mSQL (0.5ms)ESC[0m INSERT INTO "modelos"("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", Thu, 18 Apr 2013 11:29:39 CLST -03:00], ["updated_at", Thu, 18 Apr 2013 11:29:39 CLST -03:00]] ESC[1mESC[36m (79.7ms)ESC[0m ESC[1mCOMMITESC[0m Completed 500 Internal Server Error in 172ms NoMethodError (undefined method `active_for_authentication?' for #<Modelo:0x0000000b894c10>)
el resto es ilegible.
Modelo?
Mirando un poco el código de devise, este método lo definen ciertos modelos, por ej. authenticatable.rb
def active_for_authentication? true end
lo cual – supondremos – va ligado a qué módulos defina uno sobre un modelo
devise :database_authenticatable, :registerable, :confirmable
etc.
Efectivamente nuestro Modelo no lleva estas declaraciones, sino que está asociado a user, el cual es el que las define.
Y, de hecho, si le agregamos :database_authenticatable, salta un nuevo error
undefined local variable or method `encrypted_password' for #<Modelo:0x0000000867b198>
lo que sugiere que el problema es de mi app, la cual está mandando este modelo en vez de user.
build_resource
Al final resultó que un desarrollador había sobrescrito el método build_resource del método create, para asociar el usuario con su rol – lo cual me parece bastante overkill…
class Users::RegistrationsController < Devise::RegistrationsController def build_resource(hash=nil) super #hace cosas... #olvidó retornar! return resource end end
y había olvidado retornar resource, por éso estaba retornando ese tal Modelo…