哈希而不是id

时间:2011-03-31 08:14:08

标签: ruby-on-rails activerecord

我想在我的activerecords中使用自动生成的散列而不是自动递增的整数作为主键。这提出了两个问题:

  1. 如何执行这一代 最有效的方式?
  2. 如何处理可能性 生成的哈希已存在于 表?
  3. 此致 Mateusz

4 个答案:

答案 0 :(得分:8)

如果您需要此功能,因为您不想在网址中显示该ID。您可以使用像https://github.com/peterhellberg/hashids.rb

这样的宝石

它从您的数据库ID创建可逆散列,因此散列不需要存储在数据库中。

在模型to_param方法中使用它。

class MyModel < ActiveRecord::Base

  def to_param
    Hashids.new("salt").encode(id)
  end
end

在从数据库中找到记录之前解码哈希。

def show
  id = Hashids.new("salt").decode(params[:id]).try(:first)
  record = MyModel.find(id)
end

答案 1 :(得分:4)

这可能不是你要求的。但我有一个类似的问题,我想在URL中使用哈希而不是ID。我的解决方案如下

  1. 我在我的表中添加了一个名为privatelink
  2. 的列
  3. 在我的模型中,我写道:
  4.   #changes the url to use privatelink instead of the id
      def to_param
        privatelink
      end
    
      #calls the private method set_privatelink
      before_create :set_privatelink
    
      private
    
      #generates a unique hash looking something like this: c24bea1693d9e56a1878cb83f252fba05532d9d0
      def set_privatelink
        self.privatelink = Digest::SHA1.hexdigest([Time.now, rand].join)
      end
    

    来源: Railcast #63 Model Name in URL - 显示如何使用to_param方法

答案 2 :(得分:2)

这不是你的问题的重复,但我认为你想做同样的事情:

Assigning Each User a Unique 100 character Hash in Ruby on Rails

答案 3 :(得分:0)

当使用Oracle时我遇到了我想自己创建ID的情况(并没有使用序列),而在this post我提供了详细信息。简而言之,代码:

# a small patch as proposed by the author of OracleEnhancedAdapter: http://blog.rayapps.com/2008/05/13/activerecord-oracle-enhanced-adapter/#comment-240
# if a ActiveRecord model has a sequence with name "autogenerated", the id will not be filled in from any sequence
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
  alias_method :orig_next_sequence_value, :next_sequence_value

  def next_sequence_value(sequence_name)
    if sequence_name == 'autogenerated'
      # we assume id must have gotten a good value before insert!
      id
    else
      orig_next_sequence_value(sequence_name)
    end
  end
end

虽然这个解决方案特定于Oracle增强,但我假设在其他适配器中你可以否决相同的方法(next_sequence_value)。