【问题标题】:Handling PostgreSQL Creating Tables, Associations, and Rails处理 PostgreSQL 创建表、关联和 Rails
【发布时间】:2013-01-25 19:12:52
【问题描述】:

长话短说,我决定清除本地主机上的数据库,并在我的 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 =&gt; :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

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

【问题讨论】:

  • 应用程序是否正常工作,还是崩溃了?
  • 应用程序运行良好。但是,每当我创建用户时,都会收到与我的 rspec 测试返回的错误类似的错误。
  • 您已经检查过您的用户表中有password_reset_sent_at 列?这是现在唯一想到的事情。
  • 正确。我同时运行了 annotate 一个 gem 并通过 rails db 检查了数据库,它显示 password_reset_sent_at 在表中。
  • 您可以发布您的schema.rb 文件吗?

标签: ruby-on-rails ruby-on-rails-3 postgresql associations pgadmin


【解决方案1】:

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

【讨论】:

  • 我用schema.rb 更新了我的问题。因为我的用户和我的password_reset_sent_at 之间有关联,所以从技术上讲,用户表没有它,但与之关联的表却有。
【解决方案2】:

由于您在用户模式下使用的列在另一个模型中,因此您必须先调用该模型,您必须将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

【讨论】:

  • 你能进一步解释你的代码发生了什么吗?如果密码摘要更改,该方法如何知道要删除哪个用户password_resent_sent_at
【解决方案3】:

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

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

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

因此 Ruby 可能会尝试执行

`password_reset_sent_at' 

作为系统命令

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

如果不是,请忽略,只是想帮忙:)

【讨论】:

  • 感谢您的尝试和信息。不幸的是,这不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 2019-09-23
  • 2011-04-19
相关资源
最近更新 更多