user929062
user929062

Reputation: 817

FactoryGirl with has_many :through associations with capybara

I have the following models:

class Productmainclass < ActiveRecord::Base
  attr_accessible :name, :id, :maintext
  has_many :producttaggings, :dependent => :destroy
  has_many :products, :through => :producttaggings
  has_many :productsubclasses
end

class Productsubclass < ActiveRecord::Base
  attr_accessible :name, :id, :maintext
  has_many :producttaggings, :dependent => :destroy
  has_many :products, :through => :producttaggings
  belongs_to :productmainclass
end

class Product < ActiveRecord::Base
  attr_accessible :name, :productimage, :size, :description, :price
  has_many :producttaggings, :dependent => :destroy
  has_many :productsubclasses, :through => :meteoritetaggings
  has_many :productmainclasses, :through => :meteoritetaggings
  mount_uploader :productimage, ProductimageUploader
end

class Producttagging < ActiveRecord::Base
  belongs_to :product
  belongs_to :productsubclass
  belongs_to :productmainclass

  attr_accessible :product_id, :productsubclass_id, :productmainclass_id
end

I now want to create a Product with FactoryGirl and Capybara. In the spec I simply have:

product = FactoryGirl.create(:product)

In my factories.rb I have:

factory :product do
  name        "Blue glass"
  description "Description text of product"
  productimage File.new(File.join(::Rails.root.to_s, "spec/factories/", "testimage.jpg"), 'rb')
  productsubclass
  productmainclass
end

factory :productsubclass do
  name            "Colored glasses"
  productmainclass
end

factory :productmainclass do
  name "Glasses"
end

Running the test I get:

Failure/Error: product = FactoryGirl.create(:product)
 NoMethodError:
  undefined method `productsubclass=' for #<Product:0xcd42090>

Upvotes: 0

Views: 615

Answers (1)

Neil Billingham
Neil Billingham

Reputation: 2295

I think the way you have it setup would work if you were dealing with a situation where :product belonged to productsubclass, then the product and the productsubclass would be created with the product.productsubclass_id nicely inserted and all would be fine, but that's clearly not your structure, so we'd have to use another way. I think the link that @depa noted is the right way to go, specifically the 'Basic has many associations' section in this document: http://robots.thoughtbot.com/aint-no-calla-back-girl although you have the added complexity of a has_many through. But essentially your looking at a situation where you create an object and then after that you trigger another create to make the many's. Hope this makes sense :)

** Update **

Here's another approach which might be a little limited but you could just create the records from the other direction. So, if you just want one record in each object/table how about this:

FactoryGirl.define do
  factory :producttagging do
    product
    productsubclass
    productmainclass
  end
end

Upvotes: 1

Related Questions