【问题标题】:Rails 4 - getting ActiveRecord::UnkknownAttributeError: unknown attribute: checker_idRails 4 - 获取 ActiveRecord::UnkknownAttributeError:未知属性:checker_id
【发布时间】:2014-08-24 16:55:10
【问题描述】:

这里是 Rails 初学者。 运行 rspec 测试时出现以下错误:

1) User checking 
     Failure/Error: @user.check!(other_user)
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./app/models/user.rb:33:in `check!'
     # ./spec/models/user_spec.rb:87:in `block (3 levels) in <top (required)>'

  2) User checking checked user checkers 
     Failure/Error: @user.check!(other_user)
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./app/models/user.rb:33:in `check!'
     # ./spec/models/user_spec.rb:87:in `block (3 levels) in <top (required)>'

  3) User checking checked_users 
     Failure/Error: @user.check!(other_user)
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./app/models/user.rb:33:in `check!'
     # ./spec/models/user_spec.rb:87:in `block (3 levels) in <top (required)>'

  4) User checking and unchecking 
     Failure/Error: @user.check!(other_user)
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./app/models/user.rb:33:in `check!'
     # ./spec/models/user_spec.rb:87:in `block (3 levels) in <top (required)>'

  5) User checking and unchecking checked_users 
     Failure/Error: @user.check!(other_user)
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./app/models/user.rb:33:in `check!'
     # ./spec/models/user_spec.rb:87:in `block (3 levels) in <top (required)>'

  6) Relationship 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:9:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:11:in `block (2 levels) in <top (required)>'

  7) Relationship when checked id is not present 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:21:in `block (3 levels) in <top (required)>'

  8) Relationship checker methods 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:9:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:15:in `block (3 levels) in <top (required)>'

  9) Relationship checker methods 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:9:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:14:in `block (3 levels) in <top (required)>'

  10) Relationship checker methods checked 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:9:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:17:in `block (3 levels) in <top (required)>'

  11) Relationship checker methods checker 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:9:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:16:in `block (3 levels) in <top (required)>'

  12) Relationship when checker id is not present 
     Failure/Error: let(:relationship) { checker.relationships.build(checked_id: checked.id) }
     ActiveRecord::UnknownAttributeError:
       unknown attribute: checker_id
     # ./spec/models/relationship_spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/models/relationship_spec.rb:26:in `block (3 levels) in <top (required)>'

这一切都归结为“未知属性:checker_id”。

我已经试过了

  • 运行rake db:reset -> rake db:migrate-> rake test:prepare
  • 重启服务器
  • 检查pgAdmin3中的表;该表以及 checker_id 列确实存在
  • 将所有文件与 github 上的 Railstutorial 示例应用进行比较

我在更改示例应用程序的某些部分时遵循 Michael Hartl 的教程。我这里的实现应该与chapter 11.1 中的几乎相同,除了我将所有follower、follower、followed_id 等更改为checker、checking、checked_id 等。

我已将相关文件粘贴在下面:

user.rb

class User < ActiveRecord::Base
    has_many :relationships, foreign_key: "checker_id", dependent: :destroy
  has_many :checked_users, through: :relationships, source: :checked
  has_many :reverse_relationships, foreign_key: "checked_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :checkers, through: :reverse_relationships, source: :checker

    before_save { self.email = email.downcase }
    before_create :create_remember_token

    validates :name, presence: true
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
    validates :email,   presence:   true,
                        format:     { with: VALID_EMAIL_REGEX },
                        uniqueness: { case_sensitive: false }
    has_secure_password
    validates :password, length: { minimum: 6 }

    def User.new_remember_token
    SecureRandom.urlsafe_base64
  end

  def User.digest(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

  def checking?(other_user)
    relationships.find_by(checked_id: other_user.id)
  end

  def check!(other_user)
    relationships.create!(checked_id: other_user.id)
  end

  def uncheck!(other_user)
    relationships.find_by(checked_id: other_user.id).destroy
  end

  private

    def create_remember_token
      self.remember_token = User.digest(User.new_remember_token)
    end
end

user_spec.rb

require 'spec_helper'

describe User do

  before do
    @user = User.new(name: "Test User", email: "test@example.com", 
                        verified:true, about_text:"About Text", 
                        success_text:"Success Text", password: "foobar",
              password_confirmation: "foobar")
  end

  subject { @user }

  it { should respond_to(:name) }
  it { should respond_to(:email) }
  it { should respond_to(:verified) }
  it { should respond_to(:about_text) }
  it { should respond_to(:success_text) }
  it { should respond_to(:password_digest) }
  it { should respond_to(:password_confirmation) }
  it { should respond_to(:remember_token) }
  it { should respond_to(:authenticate) }
  it { should respond_to(:admin) }
  it { should respond_to(:relationships) }
  it { should respond_to(:checked_users) }
  it { should respond_to(:checking?) }
  it { should respond_to(:check!) }
  it { should respond_to(:reverse_relationships) }
  it { should respond_to(:checkers) }

  it { should be_valid }
  it { should_not be_admin }

  describe "with admin attribute set to 'true'" do
    before do
      @user.save!
      @user.toggle!(:admin)
    end

    it { should be_admin }
  end

  describe "when name is not present" do
    before { @user.name = " " }
    it { should_not be_valid }
  end

  describe "whenn password is not present" do
    before do
      @user = User.new(name: "Example User", email: "example@example.com",
                        password: " ", password_confirmation: " ")
    end
    it { should_not be_valid }
  end

  describe "when password doesn't match confirmation" do
    before { @user.password_confirmation = "mismatch" }
    it { should_not be_valid }
  end

  describe "with a password that is too short" do
    before { @user.password = @user.password_confirmation = "a" * 5 }
    it { should be_invalid }
  end

  describe "return value of authenticate method" do
    before { @user.save }
    let(:found_user) { User.find_by(email: @user.email) }

    describe "with valid password" do
      it { should eq found_user.authenticate(@user.password) }
    end

    describe "with invalid password" do
      let(:user_for_invalid_password) {
        found_user.authenticate("invalid") }

      it { should_not eq user_for_invalid_password }
      specify { expect(user_for_invalid_password).to be_false }
    end
  end

  describe "checking" do
    let(:other_user) { FactoryGirl.create(:user) }
    before do
      @user.save
      @user.check!(other_user)
    end

    it { should be_checking(other_user) }
    its(:checked_users) { should include(other_user) }

    describe "checked user" do
      subject { other_user }
      its(:checkers) { should include(@user) }
    end

    describe "and unchecking" do
      before { @user.uncheck!(other_user) }

      it { should_not be_checking(other_user) }
      its(:checked_users) { should_not include(other_user) }
    end
  end
end

relationship.rb

class Relationship < ActiveRecord::Base
  belongs_to :checker, class_name: "User"
  belongs_to :checked, class_name: "User"
  validates :checker_id, presence: true
  validates :checked_id, presence: true
end

relationship_spec.rb

require 'spec_helper'

describe Relationship do

  let(:checker) { FactoryGirl.create(:user) }
  let(:checked) { FactoryGirl.create(:user) }
  let(:relationship) { checker.relationships.build(checked_id: checked.id) }

  subject { relationship }

  it { should be_valid }

  describe "checker methods" do
    it { should respond_to(:checker) }
    it { should respond_to(:checked) }
    its(:checker) { should eq checker }
    its(:checked) { should eq checked }
  end

  describe "when checked id is not present" do
    before { relationship.checked_id = nil }
    it { should_not be_valid }
  end

  describe "when checker id is not present" do
    before { relationship.checker_id = nil }
    it { should_not be_valid }
  end
end

20140818183201_create_relationships.rb

class CreateRelationships < ActiveRecord::Migration
  def change
    create_table :relationships do |t|
      t.integer :checker_id
      t.integer :checked_id

      t.timestamps
    end
    add_index :relationships, :checker_id
    add_index :relationships, :checked_id
    add_index :relationships, [:checker_id, :checked_id], unique: true
  end
end

我非常感谢任何能让我在这方面取得进展的想法!谢谢!

EDIT/UPDDATE: 在执行rake db:reset -> rake db:migrate-> rake test:prepare 时,我在每一步都检查了开发数据库。在rake db:migrate 之后,用户表中填充了示例用户,但rake test:prepare 删除了所有这些用户,使表为空。 也许这里有联系。 checker_id可能因为rake test:prepare删除而无法使用吗?

【问题讨论】:

  • 您是否也在测试模式下运行了迁移? bundle exec rake db:migrate RAILS_ENV=test
  • 是的。它没有解决问题

标签: ruby-on-rails ruby activerecord rspec railstutorial.org


【解决方案1】:

您发布的错误, unknown attribute: checker_id

指的是一个属性 checker_id,它在第 33 行的代码中不存在:

 relationships.create!(checked_id: other_user.id)

所以要么您发布了错误的代码,要么您需要重新启动测试服务器,或者还有其他问题。但基本上,您的测试套件并没有测试您认为它正在测试的内容。

【讨论】:

    【解决方案2】:

    我最终删除了自第 10 章开始以来我所做的所有文件和更改,然后复制粘贴了教程中的所有更改。我不知道我到底做错了什么,但这解决了问题。

    【讨论】:

      猜你喜欢
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      相关资源
      最近更新 更多