测试 FactoryGirl 创建 has_one 关系!

chuanjiabao · 2013年04月09日 · 最后由 chuanjiabao 回复于 2013年04月10日 · 2663 次阅读
#issue.rb
class Issue < ActiveRecord::Base
    has_one  :resolve,:dependent => :destroy,:inverse_of => :issue
#resolve.rb
class Resolve < ActiveRecord::Base
    belongs_to :issue,:inverse_of => :resolve
end

#Factories.rb
FactoryGirl.define do
  factory :issue do
    factory :issue_with_resolve do
        after(:create) do |issue|
            FactoryGirl.create(:resolve,issue: issue)
        end 
    end
  end

我发现如果在 model 中不加:inverse_of 那么FactoryGirl.create(:issue_with_resolve).resolve返回值总是 nil。

不知道大家遇到过这样的问题么?也是通过添加 inverse_of 解决的么?还是我是用 FactoryGril 的方式有问题?

FactoryGirl.define do
  factory :issue do
    factory :issue_with_resolve do
        assocation :issue, factory: :issue, strategy: :create
    end
  end

问题的原因是由于 activerecord 的 cache 导致的。 我把出问题相关的代码都贴出来:

#issue.rb
class Issue < ActiveRecord::Base
    has_one  :resolve,:dependent => :destroy
    before_create :issue_opened_action

    def issue_opened_action
        self.resolve.destroy unless self.resolve.nil?
    end
#resolve.rb
class Resolve < ActiveRecord::Base
    belongs_to :issue
end
#Factories.rb
FactoryGirl.define do
  factory :issue do
    factory :issue_with_resolve do
        after(:create) do |issue|
            FactoryGirl.create(:resolve,issue: issue)
        end 
    end
  end

罪魁祸首就是 issue_opened_action。 由于 issue 创建完成前调用了 issue_opened_action,此时并没有 resovle 和 issue 关联,所以 issue.resolve 一定为 nil,activerecord 把此值加入 cache,后续即便是创建关联的 resolve,issue.resolve 返回的还是 cache 中的 nil,除非 reload 或者通过 inverse_of.

需要 登录 后方可回复, 如果你还没有账号请 注册新账号