如何给每个用户一个唯一的号码?

时间:2017-06-29 20:58:18

标签: ruby-on-rails ruby

我有一个名为user的设计模型。当用户注册时,他们将被指示填写名为“userinfo”的表单。我有一个名为userinfo的模型。一旦创建了新的userinfo,我就为每个userinfo提供一个唯一的令牌。我允许在userinfo控制器中使用“token”。它有效,但每次我编辑表单并更新时,唯一令牌也会发生变化。我以为我应该只在userinfo#show页面上显示第一个创建的令牌。但是如果用户5次更新其userinfo表单,将创建5个令牌,浪费4个令牌。

实际问题:当userinfo #new发生时创建唯一令牌并在userinfo #show页面上显示。当userinfo#edit和userinfo#update发生时,不应更新唯一令牌。

我的userinfo模型:

class Userinfo < ActiveRecord::Base
    belongs_to :user

      before_save :set_token

      def set_token
        self.token = rand(100000..999999)
      end
end

Userinfo控制器:

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

查看:

<%= @userinformation.token %>

1 个答案:

答案 0 :(得分:3)

尝试这样的事情:

def set_token
  self.token ||= rand(100000..999999)
end

||=说,“将token设为随机数,除非token已经有值”(粗略地)。

顺便说一句,在回答下面的评论和原始问题时,确实使用:

rand(100000..999999)

不是一个好主意。确定了两个问题:

  1. 生成的数字可能不是唯一的,
  2. 您尝试分配非唯一号码的概率会随着用户数量的增加而增加,一旦您拥有999,999位用户,则会增加到100%。
  3. 如评论中所述,如果您不介意UUID的格式,使用SecureRandom.uuid是一件好事:

    ad9ed387-ec8e-4091-84b1-fe2ce2bbfcd4
    

    在这种情况下,您可以执行以下操作:

    def set_token
      self.token ||= SecureRandom.uuid
    end
    

    顺便说一下,这是我在代码中所做的。

    使用SecureRandom.uuid,您生成重复令牌的可能性非常小。但是,如果您担心这种可能性很小,您还可以在数据库级别和模型中强制实施唯一性。如果您对答案感兴趣,那么这些是您可能想要发布的单独问题。