1

长话短说,我决定在我的本地主机上清除我的数据库,并在我的 Rails 应用程序中试验 posgreSQL 和 pgAdmin。我首先通过 pgAdmin 删除了我拥有的所有服务器。然后我跑了db:create:alldb:migrate最后db:test:prepare。现在,每当我在进行所有这些数据库实验之前运行我以前的规范测试时,我的大多数测试都失败了,给了我这个错误..

 Failure/Error: @user = FactoryGirl.create(:user)
 NoMethodError:
   undefined method `password_reset_sent_at' for #<User:0xb48a55c>

或者

 Failure/Error: @user.save
 NoMethodError:
   undefined method `password_reset_sent_at' for #<User:0xaa9c040>

我以为我可能不允许password_reset_sent_at作为不可访问属性,但它是可访问的,并且我的用户模型具有has_one :user_reset_password, :dependent => :destroy.

我的 database.yml 看起来像...

development:
  adapter: postgresql
  encoding: unicode
  database: template_development
  host: localhost
  pool: 5
  username: jason
  password: password

test:
  adapter: postgresql
  encoding: unicode
  database: template_test
  host: localhost
  pool: 5
  username: jason
  password: password

当我运行应用程序并创建新用户时,我收到此错误。

undefined method `password_reset_sent_at' for #<User:0xa6fb184>

app/models/user.rb:78:in `empty_password_reset_token'
app/controllers/users_controller.rb:25:in `create'

empty_password_reset_token方法是

def empty_password_reset_token
  if self.password_digest_changed?
    if self.password_reset_sent_at && self.password_reset_sent_at < 2.hours.ago
      false
    else
      self.password_reset_token = ""
      self.password_reset_sent_at = ""
    end
  end
end

我的架构文件

ActiveRecord::Schema.define(:version => 20130124193639) do

  create_table "user_login_failures", :force => true do |t|
    t.integer  "user_id"
    t.integer  "login_failure_attempts"
    t.datetime "created_at",             :null => false
    t.datetime "updated_at",             :null => false
  end

  create_table "user_reset_passwords", :force => true do |t|
    t.integer  "user_id"
    t.string   "password_reset_token"
    t.datetime "password_reset_sent_at"
    t.datetime "created_at",             :null => false
    t.datetime "updated_at",             :null => false
  end

  create_table "users", :force => true do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at",      :null => false
    t.datetime "updated_at",      :null => false
    t.string   "password_digest"
  end

  add_index "users", ["email"], :name => "index_users_on_email", :unique => true

end

我真的不知道为什么这不起作用。这些表都有适当的列,没有任何遗漏。任何帮助,将不胜感激。

4

3 回答 3

1

我会看看 db/schema.rb。每次运行测试时,数据库都会根据该文件的内容被拆除和重建。我怀疑根据 db/schema.rb,您的“users”表没有“password_reset_sent_at”列

于 2013-02-02T07:48:52.783 回答
0

这可能完全不相关(我没有 Ruby 经验),但我在您的问题中看到了很多“反引号”(`)。

在各种语言中,反勾号运算符将尝试在命令行上执行可执行文件。

MySQL 使用反引号来引用列名,因此如果您从 MySQL 迁移,它们可能是 MySQL SQL 语句的剩余部分

因此 Ruby 可能会尝试执行

`password_reset_sent_at' 

作为系统命令

[更新]根据这个答案,Ruby on Rails 似乎也使用反引号进行系统访问: Getting output of system() calls in Ruby

如果不是这种情况请忽略,只是想帮忙:)

于 2013-02-03T16:45:01.553 回答
0

由于您在用户模式下使用的列在另一个模型中,因此您必须先调用该模型,您必须更改password_reset_token

def empty_password_reset_token
  if self.password_digest_changed?
    build_user_reset_password unless user_reset_password
    if user_reset_password.password_reset_sent_at && user_reset_password.password_reset_sent_at < 2.hours.ago
      false
    else
      user_reset_password.password_reset_token = ""
      user_reset_password.password_reset_sent_at = ""
    end
  end
end

或者您可以使用委托并保持方法不变

delegate :password_reset_sent_at, :password_reset_token, to: :user_reset_password
于 2013-02-03T00:30:09.480 回答