Search code examples
ruby-on-railsrubyrubygemsmixinsone-time-password

how to mixin gem-modules in ruby-on-rails model


I am building a gem in which i have a module OtpGenerator. inside this module i have methods like generate_otp, verify_otp etc. This is just a begining for me and its very simple gem only to generate and verify and save and send, nothing else. Now anyone who uses this gem will have to include this module in their model. for e.g. there is a user model. now what i want is first i will create a instance

user = User.new(params[:user])

now i need to do the operation user.generate_otp, this will assign otp related things in the activerecord instance.

after that user.save, which is also fine.

But i also want a function generate_otp!, which will do all task like generates otp, than save it and sends it. My problem is that i am not getting how to achieve this functionality.

Note: I am very new to ruby. and really getting confused with mixins.

here is my code for otp.rb file

require 'securerandom'

module OtpGenerator
  def generate_otp
    #do something here
  end

  def verify_otp(otp)
    #do something here
  end

  def regenerate_otp
    #do something here
  end

  def matches?(generated, otp)
    #do something here
  end

  def expired?(otp_expiry_time)
    #do something here
  end
end

This code is still in development, i just want to know that how to implement generate_otp! function, which will do all three operation,i.e, (1) generates otp(user.generate_otp) (2) saves otp(user.save) (3) sends otp (i have created the send function, so thats not a problem.)


Solution

  • If this is a mixin in your model, then your model should also have access to it. Here is what I mean:

    class User
      include OtpGenerator
    end
    
    module OtpGenerator
    ...
      def generate_otp!
        generate_otp
        save
        send_generated_otp
      end
    end
    

    When you call User.find(45).generate_otp!

    That would work because of the way inheritances work in Ruby. Once the module is included within a class, it inherits all the methods of the module and the module has access to the context of the included class.

    Hope that answers your question