0

I have a "User" model where I want to provide a unique page for email account validation. I'm constructing the unique argument for the validation route by generating a SHA ID based on the user's ID.

However, the database value and view-printed values do not match. I believe it has something to do with encoding, but I can't quite find the solution.

The "User" model contains the following code:

after_initialize :init

def init
    unique_path = Digest::SHA1.hexdigest(self.id.to_s)
    unique_path.force_encoding(Encoding::UTF_8) #didn't seem to work
    self.email_verification_path = unique_path
end

The view contains:

<p>
    <strong>Email verification url?</strong>
    <%= @user.email_verification_path %>
</p>

Any guidance would be appreciated. Thanks in advance!

Andrew Carreiro
  • 1,577
  • 13
  • 17
  • define "do not match" – Sergio Tulentsev Jul 29 '14 at 05:36
  • Value in SQLLite db (viewed in external program): da39a3ee5e6b4b0d3255bfef95601890afd80709 Value output to view: 356a192b7913b04c54574d18c28d46e6395428ab – Andrew Carreiro Jul 29 '14 at 05:37
  • What's the column type in database? – Sergio Tulentsev Jul 29 '14 at 05:38
  • Are you sure you're viewing the same record or that it's been persisted? – Sergio Tulentsev Jul 29 '14 at 05:38
  • I've dropped the entire db, re-migrated, and only created one entry, so I'm confident I'm viewing/accessing the same record. – Andrew Carreiro Jul 29 '14 at 05:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58212/discussion-between-andrew-carreiro-and-sergio-tulentsev). – Andrew Carreiro Jul 29 '14 at 05:41
  • you are calculating a new hash each time the record is instantiated. that can not work, better try that in a `before_save` callback. furthermore, using a hash based on a sequential database id is not very secure. why dont you just pick random strings? (e.g. `[*('a'..'z'),*('0'..'9')].sample(50).join` – Marian Theisen Jul 29 '14 at 05:46
  • @MarianTheisen I would want this to be a one-time shot, not after every update, and picking random strings has the (admittedly slim) chance of creating a duplicate route. Security concern noted though; I'll add a timestamp into the mix once the bigger issue is figured out. Thanks! – Andrew Carreiro Jul 29 '14 at 05:52
  • @MarianTheisen looks like "after_initialize" was a bad choice on my part. Changing it to before_save seems to work, probably because the id is not yet set. If you'd like to submit that answer, I'll accept it. Thanks for your help! – Andrew Carreiro Jul 29 '14 at 05:55

1 Answers1

0

Running this function on the after_initialize hook fails to produce the correct hash because the ID is not yet available. Setting the function to run on "before_save" or "after_create" works.

Andrew Carreiro
  • 1,577
  • 13
  • 17