【问题标题】:How to give each user a unique number?如何给每个用户一个唯一的号码?
【发布时间】:2017-12-03 17:32:06
【问题描述】:

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

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

我的用户信息模型:

class Userinfo < ActiveRecord::Base
    belongs_to :user

      before_save :set_token

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

用户信息控制器:

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 %>

【问题讨论】:

  • 顺便说一句,您的“唯一”令牌可能只是唯一的。
  • 我知道,我怎样才能让它独一无二?
  • 如果您不介意令牌是字符串,请使用 SecureRandom.uuid。
  • SecureRandom.random_number*10000000000000000 :)

标签: ruby-on-rails ruby


【解决方案1】:

试试这样的:

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

||= 说,“将token 设置为一个随机数,除非token 已经有一个值”(大致)。

顺便说一句,针对下面的 cmets 和您的原始问题,使用:

rand(100000..999999)

不是一个好主意。发现了两个问题:

  1. 生成的数字有可能不是唯一的,并且
  2. 您尝试分配非唯一数字的概率随着用户数量的增加而增加,并且在您拥有 999,999 个用户时达到 100%。

如 cmets 中所述,如果您不介意 UUID 的格式,则使用 SecureRandom.uuid 是一件好事:

ad9ed387-ec8e-4091-84b1-fe2ce2bbfcd4

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

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

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

使用 SecureRandom.uuid,生成重复令牌的可能性非常小。但是,如果您担心这个非常小的机会,您也可以在数据库级别和模型中强制执行唯一性。如果您对答案感兴趣,可以发布这些单独的问题。

【讨论】:

  • 对于 >= 900,000 个用户,这保证会失败,并且在此之前统计上可能会失败。我认为您应该在token 上使用迁移并设置unique: true
  • @whodini9 我已经创建了一个迁移来将令牌添加到用户信息。我在哪里添加 unique:true?还是我必须创建一个新的迁移?
  • @LizzyTheLearner stackoverflow.com/questions/1449459/… 我没有阅读这篇文章中的所有 cmets,但是如果您的数据库中已经有重复项,那么简单的迁移可能会失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多