Search code examples
ruby-on-railsrubysqlitescaffolding

How to modify input parameters (which then get saved) on new user creation in rails?


I think this is a simple problem. So far I've ran

rails generate scaffold User username:string email:string password:string

to make a new scaffold for the User model. The following is my user.rb:

class User < ActiveRecord::Base
    validates :username, presence: true, length: { in: 2..50 }, uniqueness: true
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: true
    validates :password, presence: true, length: { in: 4..50}

    #self.password = 'abcd' #I can't even change the parameter to something hard-coded! 
end

I've written a few tests and that works great. My next step is to put the password parameter through a hashfunction (which I want to write myself for educational purposes) and save this newly modified string instead of the original string. I don't seem to understand how to do this? Do I create a method in user.rb which gets called from the users_controllers.rb under the create method?

I would like to test this by doing rails console --sandbox and writing some tests, too.


Solution

  • You can use the before_save callback

    # user.rb model
    
    before_save :hash_password
    
    def hash_password
      self.password = some_hash_function(self.password)
    end
    

    You have to be careful with this method not to hash the password multiple times. That is you must always hash the clear password and not hash the hashed version. That's why I would do it like this and call the field password_digest and only hash the password if the password attribute is set.

    # user.rb model
    
    attr_accessor :password
    before_save :hash_password
    
    def hash_password
      self.password_digest = some_hash_function(self.password) unless self.password.blank?
    end
    

    http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html