我已经基于Hartl课程构建了一个应用程序 - 包括第9.2节(身份验证)。从那里我尝试通过添加组织模型来扩展功能。最初我尝试使用scaffold生成命令行函数,确定它已构建太多,将其回滚然后手动构建它。我相信这个混乱我可能搞砸了我的迁移(见下文)。我使用Rails v4.1.1,Rspec 3.0.0和Capybara 2.2.0 - 所有数据库都是postgres。
组织可以拥有多个用户,而每个用户只拥有一个组织。
我应该注意到在我自己的机器上使用开发环境,我在组织用户注册期间可以正常工作 - 它创建了一个新用户,我可以正确地查看组织和用户页面,而且没有应用程序性能中出现的错误。当我使用Rspec测试进行测试时,我的问题就开始了 - 抛出一系列错误:
ActiveModel::MissingAttributeError:
can't write unknown attribute 'organization_id'
我的模特:
class Organization < ActiveRecord::Base
validates :organization_name, presence: true, length: { maximum: 50 }
has_many :users
end
class User < ActiveRecord::Base
belongs_to :organization
accepts_nested_attributes_for :organization
before_save { self.email = email.downcase }
before_create :create_remember_token, :create_organization
validates :name, presence: true, length: {maximum: 50}
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 create_organization
self.organization = Organization.create(:organization_name => Organization.organization_name) unless self.organization.present?
end
我的工厂:
FactoryGirl.define do
factory :organization do
organization_name "Orgname"
end
factory :user do
association :organization
name "A Name"
email "name@example.com"
password "foobar"
password_confirmation "foobar"
end
end
示例Rspec测试套件:
describe "edit" do
let(:organization) { FactoryGirl.create(:organization) }
let(:login) { FactoryGirl.create(:login,
:organization => organization,
:user => FactoryGirl.create(:user)) }
before do
sign_in login
visit edit_user_path (user)
end
我的schema.rb文件:
ActiveRecord::Schema.define(version: 20140619041326) do
create_table "organizations", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.string "organization_name"
end
create_table "users", force: true do |t|
t.string "name"
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
t.string "password_digest"
t.integer "organization_id"
t.string "remember_token"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["organization_id"], name: "index_users_on_organization_id", using: :btree
add_index "users", ["remember_token"], name: "index_users_on_remember_token", using: :btree
end
这里值得注意的是,当我第一次开始运行测试时,我使用的是Hartl的书中推荐的Rspec版本 - 这意味着我必须强制使用bin从开发DB到测试DB的更改/ rake dg:migrate RAILS_ENV = test命令行函数。每次运行时,我的schema.rb文件(如上所述)都会丢失行
t.integer "organization_id"
我必须耙db才能让它再次运行。
我意识到这里有很多信息,而且我的问题可能非常愚蠢(我是语言和框架的新手,这是我的第一个应用程序)但它驱使我狂。过去一周我一直试图找出实际应用本身工作时测试被破坏的原因。
非常感谢任何帮助。
答案 0 :(得分:0)
您的before_create
方法create_organization
以下一行......
self.organization = Organization.create(:organization_name => Organization.organization_name) unless self.organization.present?
当您执行Organization.organization_name
并且不存在此类方法时,您正在引用类(非对象)方法。
您可以在Organization
模型中创建它...它可能是默认值...
def self.organization_name
"Default Organization Name"
end
答案 1 :(得分:0)
我认为:login
没有工厂......而且我认为sign_in方法想要传入用户对象。
因此,请将您的let(:login)
声明更改为...
let(:login) { FactoryGirl.create(:user, :organization => organization) }