2014-02-28 17 views
2

我想向我的用戶表中添加一個新列,並使用隨機標記填充它。我有這個工作,但我很好奇,爲什麼我嘗試的第一種方法不起作用。在遷移期間使用模型方法填充列

這裏是我的移民的工作版本:

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 

但是,因爲我也要去想要的代碼生成在用戶模式由此看來,我想創建一個新的令牌每一個新的用戶一起,我想我也許可以添加代碼作爲用戶對象的一個​​方法:

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 

...然後從遷移調用它,以避免重複自己:

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 

但是,使用此方法,我沒有收到任何錯誤,但是我的secure_token列值最終在數據庫中以NULL結尾,而不是在其中包含標記。

我是Rails和Ruby的新手,所以我想我錯過了一些明顯的東西,但我看不到它是什麼。爲什麼我的方法不能工作,並且有沒有將令牌生成例程移動到User類的好方法,所以我不需要在兩個不同的地方使用它?

回答

3

你的方法改成這樣

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

@secure_token是一個實例變量。設置不會更改用戶對象上的屬性secure_token

+0

啊,好吧,我需要重新閱讀有關實例變量和屬性的章節。但是,我剛剛嘗試了您的代碼(回滾並重新遷移),並且我的users.secure_token列仍然全部爲空。 –

+1

啊哈!明白了 - 我需要分配給'self.secure_token';我猜分配給'secure_token'只是創建並拋出一個局部變量? –

+1

@MattGibson:是的,你需要說'自我'。對不起,我錯過了 – usha