DEV Community 👩‍💻👨‍💻

n350071🇯🇵
n350071🇯🇵

Posted on • Updated on

[RSpec] Factorybot transient & trait with argument

🤔 Situation

You want to make a user with a book that title is 'Ruby'.

class User
  has_many: books
end
class Book
  belongs_to: user
end

👍 Solution

  • trait: you can run the process
  • trait with arguments: It is DEPRECATED, we should use transient instead.
  • transient: you can define and pass arguments with the block
FactoryBot.define do
  factory :user, class: User do
    trait :with_book
      transient do
        # 🦄1. default value when you use :with_book trait
        # 🦄2. Dont't assign just 'Agile'. see also: https://thoughtbot.com/blog/deprecating-static-attributes-in-factory_bot-4-11
        title { 'Agile' }
      end
      after(:build) do |user, evaluator|
        user.book = FactoryBot.create(:book, title: evaluator.title)
      end
    end
  end

  factory :book, class Book do
    sequence(:title) { |n| "book no.#{n}" } # 🦄 default value
  end

end
let!(:user) { create(:user, :with_book, title: 'Ruby') }

🔗 Parent Note

Top comments (2)

Collapse
 
samuelfaure profile image
Samuel FAURE

Thank you for this small snippet, it was quite useful!

Collapse
 
mxdavis profile image
Malki Davis

Very helpful! Small thing -- there should be a do after trait :with_book

DEV

Thank you.

 
Thanks for visiting DEV, we’ve worked really hard to cultivate this great community and would love to have you join us. If you’d like to create an account, you can sign up here.