Reputation: 2224
I have a method that is repeated in multiple models. Should I just repeat this code in multiple models or is there a way to include the method in 1 place and make it available to multiple models?
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
Upvotes: 3
Views: 189
Reputation: 76774
You'll be best using a concern
, although in theory you could also use a superclass
:
This is standard Rails functionality:
#app/models/concerns/auth.rb
module Auth
extend ActiveSupport::Concern
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
end
Then you just have to include auth
in your model:
#app/models/your_model.rb
class YourModel < ActiveRecord::Base
include Auth
end
Superclass
Another way would be to create a "superclass".
This will be hacky (because it's populating the ActiveRecord method chain with another model), but could be interesting to try.
#app/models/auth.rb
class Auth < ActiveRecord::Base
def authenticate?
....
end
end
#app/models/user.rb
class User < Auth
self.table_name = self.model_name.plural
end
Being honest, this method seems hacky, although it will allow you to extend model functionality much more than a concern
would.
Refs:
Upvotes: 4