Factorybot - How to set Nested attributes

有些话、适合烂在心里 提交于 2019-12-23 17:00:16

问题


I beleive it's better to create a new question... It follows my previous question my model product has many sizes (nested attributes)

I want to create Factories but I can't make it work...

A product is valid if it has at least one size (size_nameand quantity)

FactoryBot.define do
  factory :product do
    title { Faker::Artist.name}
    ref   { Faker::Number.number(10)}
    price { Faker::Number.number(2) }
    color { Faker::Color.color_name }
    brand { Faker::TvShows::BreakingBad }
    description { Faker::Lorem.sentence(3) }
    attachments { [
      File.open(File.join(Rails.root,"app/assets/images/seeds/image.jpg")),

    ] }
    user { User.first || association(:user, admin: true)}
    category { Category.first }


    # SOLUTION 1
    factory :size do 
       transient do 
         size_name {["S", "M", "L", "XL"].sample}
          quantity  { Faker::Number.number(2) }
        end
     end
   # SOLUTION 2 
    after(:create) do |product|
       create(:size, product: product)
     end

  # SOLUTION 3 
    initialize_with { attributes }
   # Failure/Error: @product = create(:product, category_id: category.id)
   # NoMethodError:
   # undefined method `save!' for #<Hash:0x007ff12f0d9378>
  end
end

In the controller spec

  before(:each) do 
    sign_in FactoryBot.create(:user, admin: true)
    category = create(:category)
    @product = create(:product, category_id: category.id)
  end

I don't know how to write the size attribute, my produt is still not valid (missing the size)

The error I get is validation failed,Product must exist...


回答1:


Create a factory for sizes

FactoryBot.define do
  factory :size do
    size_name {["S", "M", "L", "XL"].sample}
    quantity  { Faker::Number.number(2) }
    product
  end
end

and one for products

 FactoryBot.define do
   factory :product do
    title { Faker::Artist.name}
    ref   { Faker::Number.number(10)}
    price { Faker::Number.number(2) }
    color { Faker::Color.color_name }
    brand { Faker::TvShows::BreakingBad }
    description { Faker::Lorem.sentence(3) }
    attachments { [
      File.open(File.join(Rails.root,"app/assets/images/seeds/image.jpg")),
    ] }
    user { User.first || association(:user, admin: true)}
    category 
  end
end



回答2:


You have to define a factory for size

FactoryBot.define do
  factory :size do 
    size_name { ["S", "M", "L", "XL"].sample }
    quantity  { Faker::Number.number(2) }
  end
end

and the product

FactoryBot.define do
  factory :product do
    association :size
    title { Faker::Artist.name}
    ...
  end
end

or add the build callback in the :product factory

after :build do |product|
  product.sizes << create(:size)
end


来源:https://stackoverflow.com/questions/54633125/factorybot-how-to-set-nested-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!