哈希而不是id

发布于 2024-10-29 16:16:16 字数 143 浏览 1 评论 0原文

我想在我的活动记录中使用自动生成的哈希值而不是自动递增的整数作为主键。这就提出了两个问题:

  1. 如何在这一代中执行 最有效的方法?
  2. 如何处理这种可能性 生成的哈希值已存在于 桌子?

问候, 马特乌什

I want to use auto-generated hash'es instead of auto-incremented integers in my activerecords as primary keys. This raises two questions:

  1. how to perform this generation in
    most efficient way?
  2. how to handle possibility that
    generated hash exists already in
    table?

Regards,
Mateusz

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等待我真够勒 2024-11-05 16:16:16

如果您因为不想在网址中显示 id 而需要这样做。您可以使用像 https://github.com/peterhellberg/hashids.rb 这样的 gem

它会创建来自数据库 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

If you want this because you don't want to show the id in the web url. You can use a gem like https://github.com/peterhellberg/hashids.rb

It creates a reversible hash from your database id so the hash does not need to be stored in the database.

Use it in your models to_param method.

class MyModel < ActiveRecord::Base

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

And decode the hash before finding the record from the database.

def show
  id = Hashids.new("salt").decode(params[:id]).try(:first)
  record = MyModel.find(id)
end
老旧海报 2024-11-05 16:16:16

这可能不完全是您所要求的。但我遇到了类似的问题,我想在 URL 中使用哈希而不是 ID。我的解决方案如下,

  1. 我在表中添加了一个名为 privatelink 的列
  2. 在我的模型中我写道:
  #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

来源:
URL 中的 Railcast #63 模型名称 - 展示如何使用 to_param 方法

It might not be exactly what you asked for. But I had a similar problem where I wanted to use a hash instead of the ID in the URL. My solution follows

  1. I added a column in my table called privatelink
  2. In my model i wrote:
  #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

Source:
Railcast #63 Model Name in URL - shows how to use the to_param method

葬﹪忆之殇 2024-11-05 16:16:16

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

在 Ruby on Rails 中为每个用户分配一个唯一的 100 个字符哈希

It's not a duplicate of your question, but i think you want to do the same thing :

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

讽刺将军 2024-11-05 16:16:16

使用 Oracle 时,我遇到了这样的情况:我想自己创建 ID(而不是使用序列),并且在 这篇文章我提供了我是如何做到这一点的详细信息。简而言之,代码:

# 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)。

When using Oracle i had the case where I wanted to create the ID ourselves (and not use a sequence), and in this post i provide the details how i did that. In short the code:

# 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

while this solution is specific to Oracle-enhanced, i am assuming inside the other adapters you can overrule the same method (next_sequence_value).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文