【问题标题】:How to populate devise user如何填充设计用户
【发布时间】:2013-05-22 09:57:11
【问题描述】:

我想用假数据填充数据库,使用 faker 和 populator gem。 使用 Devise 生成模型 User。

这是我的 rake 文件

namespace :db do
  desc "Fill database with sample data"
  task populate: :environment do
    [User, Article].each(&:delete_all)
    password = "password"

    User.populate 20 do |user|
      user.name = Faker::Name.name
      user.email = Faker::Internet.email
      user.password = password
      user.password_confirmation = password
      Article.populate 5 do |article|
        article.user_id = user.id
        article.title = Populator.words(1..3).titleize
        article.content = Populator.sentences(2..10)
        article.created_at = 2.years.ago..Time.now
      end
    end

  end
end

当我运行 rake db:populate 时会引发以下问题

rake aborted!
undefined method `password=' for #<Populator::Record:0xa179d14>
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/record.rb:64:in `method_missing'
    /home/sunloverz/RubymineProjects/socialnews/lib/tasks/sample_date.rake:10:in `block (3 levels) in <top (required)>'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:53:in `call'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:53:in `block in build_records'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:50:in `times'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:50:in `build_records'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:43:in `block in populate'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:29:in `remember_depth'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/factory.rb:42:in `populate'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/populator-1.0.0/lib/populator/model_additions.rb:25:in `populate'
    /home/sunloverz/RubymineProjects/socialnews/lib/tasks/sample_date.rake:6:in `block (2 levels) in <top (required)>'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:246:in `call'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:246:in `block in execute'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:241:in `each'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:241:in `execute'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:184:in `block in invoke_with_call_chain'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/task.rb:170:in `invoke'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:143:in `invoke_task'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:101:in `block (2 levels) in top_level'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:101:in `each'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:101:in `block in top_level'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:110:in `run_with_threads'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:95:in `top_level'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:73:in `block in run'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:160:in `standard_exception_handling'
    /home/sunloverz/.rvm/gems/ruby-1.9.3-p385/gems/rake-10.0.4/lib/rake/application.rb:70:in `run'
    Tasks: TOP => db:populate
    (See full trace by running task with --trace)

怎么了?

【问题讨论】:

  • 尝试删除password = "password",只使用user.password = "password" user.password_confirmation = "password"
  • 我有同样的问题,虽然user.password = password 在控制台中工作!!

标签: ruby-on-rails devise


【解决方案1】:

Populator 不加载 ActiveRecord 实例;所以任何验证、回调、嵌入式方法都不起作用。相反,它会加载自己的 Record 对象,使用列属性和纯 SQL 来提高性能。

另一方面,Devise 不会创建 :password 列,它会创建 encrypted_pa​​ssword 列并执行幕后的所有逻辑,如果您想深入了解设计代码,请查看此link

解决方案:我们需要调用password_digest对给定的密码进行加密,然后直接设置encrypted_pa​​ssword,但是这个method是受保护的,不能在rake内部调用。相反,我们将使用“新”方法来触发 password_digest,因此您的代码将是这样的:

password = "password"

User.populate 20 do |user|
  user.name = Faker::Name.name
  user.email = Faker::Internet.email
  user.encrypted_password = User.new(:password => password).encrypted_password
  # rest of your code here      
end

【讨论】:

  • 感谢您的提示!我正在使用我自己的基于会话/cookie 的身份验证,使用password_digest,所以对于任何这样做的人,首先像上面一样设置password = "password",然后设置它,使用user.password_digest = User.new(:password =&gt; password).password_digest
【解决方案2】:

确保您的模型(在您的情况下为表)actually 有一个名为 "password" 的列。

如果有,那么尝试检查是否有attr_accessible :password

【讨论】:

  • 它有一个列密码和 attr_accessible :用户模型中的密码
猜你喜欢
  • 1970-01-01
  • 2012-01-12
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多