FactoryGirl association with reference
Asked Answered
S

2

10

I have four models: User, Product, Ownership and Location. Userand Product have one Location, and Location belongs to User and to Product (Polymorphic model).

I want to use FactoryGirl to create products that have the same location as their owner.

factory :location do
  sequence(:address) { |n| "#{n}, street, city" }
end

factory :user do
  sequence(:name)  { |n| "Robot #{n}" }
  sequence(:email) { |n| "numero#{n}@robots.com"}
  association :location, factory: :location
end

factory :product do
  sequence(:name) { |n| "Objet #{n}" }
  association :location, factory: :location
end

factory :ownership do
  association :user, factory: :user
  association :product, factory: :product
end

I created a method in the product model file to retrieve the product's owner just by doing product.owner.

I want to adapt the product factory in order to replace the factoried location by product.owner.location. How can I do that?

EDIT 1

I want to use it like that:

First I create a user

FactoryGirl.create(:user)

Later I create a product

FactoryGirl.create(:product)

When I associate both of them

FactoryGirl.create(:current_ownership, product: product, user: user)

I want that the location of my product becomes the one of his owner.

Sinh answered 26/8, 2013 at 7:9 Comment(1)
So Product model has a belongs_to association to Owner?Com
D
11

use the following code.

factory :user do
  sequence(:name)  { |n| "Robot #{n}" }
  sequence(:email) { |n| "numero#{n}@robots.com"}
  association :location, factory: :location

  factory :user_with_product do
    after(:create) do |user|
      create(:product, location: user.location)
    end
  end
end

To create the records, just use the user_with_product factory.

UPDATE:

In response to your question update, you can add an after(:create) callback to the ownership factory

factory :ownership do
  association :user, factory: :user
  association :product, factory: :product

  after(:create) do |ownership|
    # update ownership.user.location here with ownership.user.product
  end
end

The problem with this is your current association setup. Since location belongs to user or product, the foreign key is in location. so a location can't both belong to a user and a product at the same time.

Dished answered 26/8, 2013 at 7:27 Comment(1)
Thanks, but I want to do the opposite. When I create a product, I want to be able to associate him with a user through the Ownership model, and in doing so, affect the user.location to my product.location... I updated my question accordingly.Sinh
M
2

using an after_create callback should do the trick

factory :ownership do
  user # BONUS - as association and factory have the same name, save typing =)
  product
  after(:create) { |ownership| ownership.product.location = ownership.user.location }
end
Moire answered 1/4, 2016 at 18:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.