Assign random password.

Hello

I have a user table in my database and what I wish to do is have a
random password generated for each user on create which is then sent to
their email address. I was wondering how I would assign the random
password.

I have the following in my view:

    <p>
    <div id="p1"><%= t('.username')%></div>
    <%= f.text_field :username %>
  </p>

  <p>
    <div id="p1"><%= t('.email')%></div>
    <%= f.text_field :email %>
  </p>

  <p class="button"><%= f.submit 'Create Account' %></p>

The following in my controller:

  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        Notifier.user_created(@user).deliver
        session[:user_id] = @user.id
        format.html { redirect_to @user, notice: 'User was successfully
created.' }
        format.json { render json: @user, status: :created, location:
@user }
      else
        format.html { render action: "new" }
        format.json { render json: @user.errors, status:
:unprocessable_entity }
      end
    end
  end

And I have the following in my user model:

  attr_accessor :password
  before_save :encrypt_password

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password,
password_salt)
    end
  end

    def self.random_string(len)
    #generate a random password consisting of strings and digits
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
    newpass = ""
    1.upto(len) { |i| newpass << chars[rand(chars.size-1)]}
    return newpass
  end

  def self.authenticate(email, password)
    user = find_by_email(email)
    if user && user.password_hash ==
BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

I will have to remove my if password.present? line because it won't be
present but I have the random string code, I just need to assign it to
the hash/salt.

The easiest way to make this work with your current code is to just add

@user.password = User.random_string(8)

In the create method of your model after

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

A couple of other quick things you might want to consider,
1.) Don’t allow the ‘password’ attribute to be mass assigned.
2.) The random string method probably doesn’t belong in the User class and could be refactored

Hope that helps