2015-12-02 82 views
1

我試圖找到一種方式來完成這件事:的Rails:生成哈希

- >每次當一個「銷售」被保存到DB軌道時間來生成一個散列(不超過250字符)並將值保存到列「標記」。

我搜查了很多,但沒有滿足我的要求。你有什麼想法?

在此先感謝!

+1

解釋你的要求更明確 –

+0

你看http://ruby-doc.org/stdlib-2.1.0 /libdoc/digest/rdoc/Digest.html –

+0

@RORDeveloper其餘的得到它:)對不起,如果它不夠清楚。有任何想法嗎? – CottonEyeJoe

回答

1

大廈:

class Sale < ActiveRecord::Base 
    before_save :generate_token 
    validates :token, uniqueness: true 
    def generate_token(length=50) 
    self.token = SecureRandom.urlsafe_base64(length, false) 
    end 
end 

唯一可通過validation得到保證。

編輯 上述驗證無用,並且在生成的令牌不唯一時不能解決問題。需要一個循環(比如joshua.paling提出的),或者更好地使用has_secure_token(由Mike Desjardins提出),其中implements與此類似。在上面我們鼓勵你在數據庫中添加一個唯一索引,以避免競爭條件:

class Sale < ActiveRecord::Base 
    before_create :generate_token 
    def generate_token(length=50) 
    loop do 
     token = self.token = SecureRandom.urlsafe_base64(length, false) 
     break token unless self.class.exists?(token: token) 
    end 
    end 
end 

主編的「驗證」

+0

這一個工作!大!謝謝! – CottonEyeJoe

+0

還有一個問題:如何確保該令牌只在數據庫中保存一次?因爲此時每次更新「銷售」時都會重新創建哈希。謝謝! – CottonEyeJoe

+1

只是在不做'nil'的情況下,通過這樣做:self.token || = SecureRandom.urlsafe_base64(length,false) – Mapad

3

我對這件事的態度是SecureRandom.hex。它需要一個指示長度的參數 - 例如。 SecureRandom.hex(250)你的情況。它是十六進制的 - 所以使用數字,然後是字母a-f。

我想你還希望它在數據庫中的所有記錄中都是唯一的?如果是的話,你會想這樣的事情在你的模型:

def generate_unique_token 
    loop do 
    token = SecureRandom.hex 
    break token unless self.class.exists?(token: token) 
    end 
end 
+0

Hi @ joshua.paling,我得到以下錯誤: 未定義的方法'存在?'對於SalesController:類 任何想法? – CottonEyeJoe

+0

@Harakiri:「在你的模型中」 –

+0

是的,把代碼放在你的模型中,而不是放在你的控制器中。而且,請確保在數據庫級別的令牌上添加唯一索引。 –

1
class Sale < ActiveRecord::Base 
    before_save :generate_token 
    def generate_token(length=250) 
    self.token = [*('A'..'Z'),*('a'..'z'),*('0'..'9')].sample(length).join 
    end 
end 

你可以控制的長度和字符。在richfisher答案的頂部

+0

這是一個很好的答案。它只是缺少:「驗證:令牌,唯一性:真」,以確保唯一性。而不是自定義函數來生成令牌,您可以使用SecureRandom。urlsafe_base64(長度,假) – Mapad

+0

嗨@Mapad它看起來像完整嗎? – CottonEyeJoe

2

添加到其他人的答案...導軌5具有has_secure_token方法,你可以簡單地添加到你的ActiveRecord類,例如,

class User < ActiveRecord::Base 
    has_secure_token 
end 

這種方法基本上是做其他人都暗示你做的骯髒的工作。如果on Rails的5是沒有,有一個可用的軌道4反向移植:

https://github.com/robertomiranda/has_secure_token

+0

我覺得Rails 5還沒有正式發佈,不是嗎? – CottonEyeJoe

+0

是的,Rails 5仍然有優勢,這就是爲什麼我包含Rails 4 backport的原因。我真的不知道很多人使用Rails 5。^_ ^ –