Search code examples
ruby-on-railsparameter-passingmodels

passing a model to a method in rails


In refactoring, I need to move a generate_token method out of my user model so that it can be called by other models.

This is the method code:

def generate_token(column)
  begin
    self[column] = SecureRandom.urlsafe_base64
  end while User.exists?(column => self[column])
end

Where the column is passed in allowing the user model to generate many different tokens as needed. The method is called like:

def some_other_method
  generate_token(:token_column_name)
  ...
end

My user model currently passes in two different token columns to the method: auth_token and pw_reset_token.

My first thought is to put it in the /lib/generate_token.rb and call it from the model with include generate_token. I shouldn't have to pass in the column param on the include, since it is just including the method, not calling it.

The challenge for me is the end while User.exists?(column => self[column]). This prevents the method from generating a new token if one already exists. However, this is assuming the User Model; instead I need to refactor it to take the model that is calling the method, and passing that in as a variable to the method, like:

include generate_token(model_name)

so that the code can now read

end while [Model].exists?(column => self[column])

Is this possible? How would I do this?


Solution

  • Definitely a library class is the way to go here, or more specifically, a Rails Concern (same diff in this context).

    That said, you can call self.class to get the class, then do things like self.class.exists?