Reputation: 241
I have a devise model called user. When a user signs up, they will be directed to fill out form called "userinfo". I have a model called userinfo. As soon as a new userinfo is created, I give each userinfo a unique token. I permit "token" in my userinfo controller. It works, but everytime I edit the form and update, the unique token changes too. I was thinking I should only show the first created token on the userinfo#show page. But if a user updates their userinfo form 5 times, 5 tokens will be created and 4 will be wasted.
So actual problem: Create unique token when userinfo#new happens and show it on the userinfo#show page. Unique token should not be updated when userinfo#edit and userinfo#update happens.
My userinfo model:
class Userinfo < ActiveRecord::Base
belongs_to :user
before_save :set_token
def set_token
self.token = rand(100000..999999)
end
end
Userinfo controller:
class UserinfosController < ApplicationController
before_action :find_userinfo, only: [:show, :edit, :update, :destroy, :log_impression]
before_action :authenticate_user!
def index
@userinfors = Userinfo.search(params[:search])
end
def show
end
def new
@userinformation = current_user.build_userinfo
end
def create
@userinformation = current_user.build_userinfo(userinfo_params)
if @userinformation.save
redirect_to userinfo_path(@userinformation)
else
render 'new'
end
end
def edit
end
def update
if @userinformation.update(userinfo_params)
redirect_to userinfo_path(@userinformation)
else
render 'edit'
end
end
def destroy
@userinformation.destroy
redirect_to root_path
end
private
def userinfo_params
params.require(:userinfo).permit(:name, :email, :college, :gpa, :major, :token, :skills, :user_img)
end
def find_userinfo
@userinformation = Userinfo.friendly.find(params[:id])
end
end
View:
<%= @userinformation.token %>
Upvotes: 0
Views: 273
Reputation: 20263
Try something like this:
def set_token
self.token ||= rand(100000..999999)
end
The ||=
says, "set token
to a random number unless token
already has a value" (roughly).
BTW, in response to the comments below and on your original question, it is true that using:
rand(100000..999999)
is not such a good idea. Two problems were identified:
As mentioned in the comments, using SecureRandom.uuid is a good thing if you don't mind the format of the UUID which is something like this:
ad9ed387-ec8e-4091-84b1-fe2ce2bbfcd4
In which case you would do something like:
def set_token
self.token ||= SecureRandom.uuid
end
This is, by the way, what I do in my code.
With SecureRandom.uuid, the probability that you will generate duplicate tokens is vanishingly small. However, if you are worried about that very small chance, you could also enforce uniqueness at the DB level and in your model. Those are separate questions that you may want to post if you are interested in the answers.
Upvotes: 3