'How can I create class “Item” before the class “Transaction” exist, with FactoryBot?
I was wondering if anyone can help. I am receiving an error message in the terminal saying Validation failed: Item must exist. I think that happens because FactoryBot is trying to create a Transaction class before the Item class, I think, I have to find a way to make the Item exist first before the Transaction, I tried many different ways, but had no success so far. optional: true is not an option, appreciate any help.
ps: this is my first time I am asking a help in StackOverflow so apologies if something is not right in my post.
Down below you can find 3 files, if you want to see other files let me know.
require "test_helper"
class PurchasesControllerTest < ActionDispatch::IntegrationTest
describe "#index" do
let(:user_id) { Faker::Internet.uuid }
let(:payload) { { user_id:, account_number: 1 } }
let(:purchase_count) { 3 }
before do
WebMock.stub_request(:get, "#{ENV['IDENTITY_SERVICE_URL']}/users/#{user_id}")
.to_return(status: 200, body: user_response(user_id:), headers: jsonapi_headers)
create(:as_asset)
purchase_count.times do
create(:purchase, user_id: 1)
end
end
it "returns successful response" do
get purchases_url, headers: authorization_header(payload)
assert_response :success
assert_match(/"total":#{purchase_count}/, response.body)
end
context "when unauthorized" do
it "returns unauthorized response" do
get purchases_url
assert_response :unauthorized
end
end
end
end
FactoryBot.define do
factory :purchase do
user_id { Faker::Internet.uuid }
for_as_asset
trait :for_gasset do
association :item, factory: :gasset
end
trait :for_as_asset do
association :item, factory: :as_asset
end
after(:create) do |object|
create(:transaction, purchase_id: object.id, purchase_type: "Purchase")
end
end
end
FactoryBot.define do
factory :transaction do
item_id { 4 }
item_type { "AsAsset" }
user_id { Faker::Internet.uuid }
purchase_ref { "Purchase reference" }
end
end
Solution 1:[1]
The answer to my question:
Added item_id: object.item_id, item_type: object.item_type inside the block statement of purchase factory.
FactoryBot.define do
factory :purchase do
for_gasset
after(:create) do |object|
create(:transaction, user_id: object.user_id, item_id: object.item_id, item_type: object.item_type, purchase_id: object.id, purchase_type: "Purchase")
end
trait :for_gasset do
association :item, factory: :gasset
end
trait :for_as_asset do
association :item, factory: :as_asset
end
user_id { Faker::Internet.uuid }
end
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Homeless Viktor |
