2014-06-24 97 views
2

我已经构建了一个基于Hartl课程的应用程序 - 直到并包括第9.2节(认证)。从那里我试图通过添加组织模型来扩展功能。最初,我尝试使用脚手架生成命令行功能,决定它已经建立了太多,将其翻转并手动构建。我相信我可能搞砸了我的迁移(见下文)。我使用Rails v4.1.1,Rspec 3.0.0和Capybara 2.2.0 - 所有数据库都是postgres。Rspec在尝试测试嵌套属性时抛出的未知属性错误

一个组织可以拥有多个用户,而每个用户只属于一个组织。

我应该注意到,在我自己的机器上使用开发环境,我有组织在用户注册过程中正常工作的领域 - 它创建一个新用户,我可以正确查看组织和用户页面,并且有应用程序的性能没有出现任何错误。我的问题,当我使用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+\-.][email protected][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 "[email protected]" 
    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 

这可能是值得一提的是在这里当我第一次开始运行我使用哈特尔的书推荐Rspec的版本测试 - 这意味着我必须通过从开发DB的变化给力使用bin/rake dg:migrate RAILS_ENV = test命令行函数来测试数据库。每次我跑了这一点,我schema.rb文件(如上面贴)就失去了行

t.integer "organization_id"

,我不得不耙分贝得到它的再次合作。

我意识到这里有很多信息,而且我的问题可能很愚蠢(我对语言和框架很陌生,这是我的第一个应用程序),但它让我生气。过去一周,我花了很多时间试图找出当实际的应用程序本身工作时为什么测试会被破坏。

任何帮助将不胜感激。

+0

我已经找到了问题 - 显然轨道4不会自动更新spec_helper使用'的ActiveRecord :: Migration.maintain_test_schema'的模式 - 而不是你仍然需要使用“rake db:test:prepare”。 不过虽然这已摆脱了我一些错误,我仍然得到3个主要错误: 1)它不喜欢我厂“登陆”(我是复制这似乎暗示这会工作其他代码) 2.)在用户页面rspec测试它找不到字段“机构名称” 3.)它说上述“create_organization”功能未定义方法“organization_name” 任何想法? – Zoinks10

回答

0

我觉得没有工厂:login ......我觉得sign_in方法要传入用户对象。

因此改变你的let(:login)语句...

let(:login) { FactoryGirl.create(:user, :organization => organization) } 
+0

谢谢。我实际上是通过给用户工厂添加一个特征来解决这个问题,并且传递一个新用户和特征。您的方法会更好吗?或者我应该保留现有的代码? – Zoinks10

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 
+0

谢谢。我使用create_organization代码的目的是为了确保任何注册拥有现有组织的帐户的人都属于该组织(而不是复制它)。设置默认值会有什么负面影响?还是有没有更好的方式来实现我的目标没有这个create_organization代码? – Zoinks10

+0

事实上,如果组织在调用create之前已被分配给用户,它将按预期行事。您是否在说,如果没有组织分配但组织表中至少有一个组织,您想要使用什么是组织表中的第一个记录? – SteveTurczyn

+0

不,我只是担心这会让人们注册,而不包含组织名称,然后使用“默认组织名称”作为组的一部分卡住。目前没有任何影响,但最终我希望第一个用户注册任何组织作为管理员用户,并且能够在整个用户群中运行报告。如果忽略组织名称的人仍然可以注册,则会产生问题。 – Zoinks10

相关问题