1

我有一个模型与另一个模型has_one关联。through

class Publisher
  has_many :books
end

class Book
  belongs_to :publisher
  has_one :author
end

class Author
  belongs_to :book
  has_one :publisher, :through => :book
end

在我的 Rails 代码中,我可以author.publisher毫无问题地调用,所以一切正常。但是在我的规范中(使用 Rspec 和 FactoryGirl,该关联似乎不起作用。这是我的 FactoryGirl 定义:

Factory.define :author do |a|
  a.association :book
end

Factory.define :book do |b|
  b.association :publisher
end

Factory.define :publisher
end

(省略了工厂的大部分属性)。

现在在我的规格中,我可以执行以下操作

pub = Factory(:publisher)
book = Factory(:book, :publisher => pub)
author = Factory(:author, :book => book)

author.book # => Returns book
author.book.publisher # => Returns publisher 
author.publisher # => nil

那么为什么我的through协会不起作用?

4

1 回答 1

2

factory_girl/ factory_girl_rails4.1.0 中,以下内容对我有用:

factories.rb

FactoryGirl.define do

  factory :author do
    book
  end

  factory :book do
    publisher
  end

  factory :publisher do
  end

end

在导轨控制台中:

pub = FactoryGirl.create(:publisher)
#=> #<Publisher id: 1, created_at: "2013-01-30 13:35:26", updated_at: "2013-01-30 13:35:26">
book = FactoryGirl.create(:book, :publisher => pub)
#=> #<Book id: 1, publisher_id: 1, created_at: "2013-01-30 13:36:23", updated_at: "2013-01-30 13:36:23">
author = FactoryGirl.create(:author, :book => book)
#=> #<Author id: 1, book_id: 1, created_at: "2013-01-30 13:36:57", updated_at: "2013-01-30 13:36:57">
author.book
#=> #<Book id: 1, publisher_id: 1, created_at: "2013-01-30 13:36:23", updated_at: "2013-01-30 13:36:23">
author.book.publisher
#=> #<Publisher id: 1, created_at: "2013-01-30 13:35:26", updated_at: "2013-01-30 13:35:26">
author.publisher
#=> #<Publisher id: 1, created_at: "2013-01-30 13:35:26", updated_at: "2013-01-30 13:35:26">

奇怪的是,最后一个author.publisher需要额外的 SELECT 操作,author.book.publisher而不需要(可能与nil您观察到的有关):

Publisher Load (0.2ms)  SELECT "publishers".* FROM "publishers"
  INNER JOIN "books" ON "publishers"."id" = "books"."publisher_id"
  WHERE "books"."id" = 1 LIMIT 1

Publisher.create如果你使用, Book.create,Author.create而不是 ,也会发生同样的事情FactoryGirl.create,所以这不是工厂女孩行为而是 rails 行为,这与如何through缓存关联有关。

于 2013-01-30T13:43:01.127 回答