2012-04-08 7 views
3

Ich habe 2 HABTM Modelle:Wie fabrizieren und testen Sie has_and_belongs_to_many (HABTM) Assoziationen mit Fabrication und RSpec?

class Article < ActiveRecord::Base 
    attr_accessible :title, :content 
    belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' 
    has_and_belongs_to_many :categories 

    validates :title, :presence => true 
    validates :content, :presence => true 
    validates :author_id, :presence => true 

    default_scope :order => 'articles.created_at DESC' 
end 

class Category < ActiveRecord::Base 
    attr_accessible :description, :name 
    has_and_belongs_to_many :articles 

    validates :name, :presence => true 
end 

Article gehört zu einem Autor (Benutzer)

class User < ActiveRecord::Base 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    attr_accessible :email, :password, :password_confirmation, :remember_me 
    attr_accessible :name 

    has_many :articles, :foreign_key => 'author_id', :dependent => :destroy 
end 

Zusammen mit ihren Verarbeitern:

Fabricator(:user) do 
    email { sequence(:email) { |i| "user#{i}@example.com" } } 
    name { sequence(:name) { |i| "Example User-#{i}" } } 
    password 'foobar' 
end 

Fabricator(:article) do 
    title 'This is a title' 
    content 'This is the content' 
    author { Fabricate(:user) } 
    categories { Fabricate.sequence(:category) } 
end 

Fabricator(:category) do 
    name "Best Category" 
    description "This is the best category evar! Nevar forget." 
    articles { Fabricate.sequence(:article) } 
end 

Ich versuche, ein zu schreiben Test, um das Vorhandensein der Artikelobjekte innerhalb der Kategorie # in RSpec

zu überprüfen
before do 
    @category = Fabricate(:category) 
    visit category_path(@category) 
end 

# it { should have_link(@category.articles.find(1).title :href => article_path(@category.articles.find(1))) } 
@category.articles.each do |article| 
    it { should have_link(article.title, :href => article_path(article)) } 
end 

Sowohl die kommentiert und unkommentiert Tests erzeugen diesen Fehler:

undefined method 'find' for nil:NilClass (NoMethodError) undefined

method 'articles' for nil:NilClass (NoMethodError)

Was soll ich tun, um die erste Art Objekt in der Kategorie Objekt zugreifen zu können, ich fabriziert und umgekehrt?

Antwort

6

Jedes Mal, wenn Sie Fabricate.sequence aufrufen, wird eine Ganzzahl zurückgegeben, sofern Sie keinen Block übergeben. Sie müssen stattdessen die eigentlichen verwandten Objekte generieren. Sie sollten Ihre Assoziationen so erzeugen:

Fabricator(:article) do 
    title 'This is a title' 
    content 'This is the content' 
    author { Fabricate(:user) } 
    categories(count: 1) 
end 

Fabricator(:category) do 
    name "Best Category" 
    description "This is the best category evar! Nevar forget." 
    articles(count: 1) 
end 
+1

Und wenn ich Artikel/Kategorien von einem anderen Fabricator erstellen möchte? – Luccas