Accessing ActiveSupport::Concern class methods from within instance methods
-
20-12-2019 - |
Pregunta
I'm working my way through Michael Hartl's tutorial, but was finding the User class getting a bit cluttered. I wanted to clean it up a bit by pulling chunks of functionality into separate mixins (using the new-ish ActiveSupport::Concern
, vs the older self.included(klass)
pattern).
I'm having a bit of trouble with the Session section of things.
From 'models/user/session_management.rb':
require 'active_support/concern'
module SessionManagement
extend ActiveSupport::Concern
included do
before_create :create_remember_token
end
private
def create_remember_token
self.remember_token = self.encrypt(self.new_remember_token)
end
module ClassMethods
def new_remember_token
SecureRandom.urlsafe_base64
end
def encrypt(token)
Digest::SHA1.hexdigest(token.to_s)
end
end
end
Which I include in 'models/user.rb':
require 'user/authentication'
require 'user/session_management'
class User < ActiveRecord::Base
...
include Authentication
include SessionManagement
...
end
This works fine for the authentication module (which is really just validations and has_secure_password
). However, the create_remember_token
instance method is throwing up trying to access the encrypt
and new_remember_token
class methods.
NoMethodError:
undefined method `new_remember_token' for #<User:0x007f8e17e338f0>
# ./app/models/user/session_management.rb:13:in 'create_remember_token'
# ./spec/models/user_spec.rb:152:in `block (4 levels) in <top (required)>
I feel like I'm missing something obvious. Any insight would be greatly appreciated. Thanks in advance!
Solución
Those two methods are class methods, and you are calling them on the instance. Try:
def create_remember_token
self.remember_token = self.class.encrypt(self.class.new_remember_token)
end
or (prefered) move them out of ClassMethods
module.
require 'active_support/concern'
module SessionManagement
extend ActiveSupport::Concern
included do
before_create :create_remember_token
end
private
def create_remember_token
self.remember_token = encrypt(new_remember_token)
end
def new_remember_token
SecureRandom.urlsafe_base64
end
def encrypt(token)
Digest::SHA1.hexdigest(token.to_s)
end
end