Pergunta

I'd like to add a new column to my users table, and populate it with a random token. I've got that working, but I'm curious as to why the first method I tried didn't work.

Here's the working version of my migration:

class AddTokenToUser < ActiveRecord::Migration
  def up
    add_column :users, :secure_token, :string
    User.reset_column_information
    User.all.each do |user|
      user.secure_token = SecureRandom.urlsafe_base64(16)
      user.save!
    end
  end

  def down
    remove_column :users, :secure_token
  end
end

However, because I'm also going to want the code to generate this token on the User model, as I'd like to create a new token along with every new user, I thought I might be able to add the code as a method on the User object:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :snaps

  def generate_new_secure_token
    @secure_token = SecureRandom.urlsafe_base64(16)
  end
end

...and then call it from the migration, to avoid repeating myself:

class AddTokenToUser < ActiveRecord::Migration
  def up
    add_column :users, :secure_token, :string
    User.reset_column_information
    User.all.each do |user|
      # user.secure_token = SecureRandom.urlsafe_base64(16)
      user.generate_new_secure_token
      user.save!
    end
  end

  def down
    remove_column :users, :secure_token
  end
end

However, with this method, I get no errors, but my secure_token column values all end up as NULL in the database, rather than having the a token in them.

I'm new to both Rails and Ruby, so I figure I'm missing something obvious, but I can't see what it is. Why isn't my method working, and is there a good way to move the token generation routine to the User class, so I don't need to have it in two different places?

Foi útil?

Solução

Change your method to this

  def generate_new_secure_token
    self.secure_token = SecureRandom.urlsafe_base64(16)
  end

@secure_token is an instance variable. Setting that doesn't change the attribute secure_token on the user object

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top