Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recipes with foreign_key and one_to_one=True breaks #204

Closed
walison17 opened this issue Jun 14, 2021 · 4 comments
Closed

Recipes with foreign_key and one_to_one=True breaks #204

walison17 opened this issue Jun 14, 2021 · 4 comments
Labels
bug Something isn't working

Comments

@walison17
Copy link

Recipes that uses reverse relationship foreign_key and one_to_one=True break when call make

profile_recipe = Recipe(Profile, phone='5581999999999')
user_recipe = Recipe(User, profile=foreign_key(profile_recipe, one_to_one=True))

user_recipe.make(_quantity=2)

What you expected.

2 users created and 2 profiles created attached to each other.

What happened instead.

ValueError: Cannot assign "<itertools.cycle object at 0x7f4f0f927080>": "User.profile" must be a "Profile" instance.

Versions

Python: 3.9.3
Django: 3.1.8
Model Bakery: 1.3.2

@walison17 walison17 changed the title Recipes with foreign_key and one_to_one=True breaks Recipes with foreign_key and one_to_one=True breaks Jun 14, 2021
@berinhard
Copy link
Member

Hi @walison17 thanks for opening this issue. Probably the fix for this should also fix #28 because, even though they differ a little bit on their contexts.

But, actually, I fell that the modeling you've used to describe your problem is not correct. Because, every time you baker.make_recipe("yourapp.profile") you'll already populate the FK to the user. So, in your test, you can do things such as:

user_with_profile = baker.make_recipe("yourapp.profile").user

Also, by using the recipes the way you've defined, you'll always end up with more users than you're probably expecting. This is because, to make a Profile instance, baker is obligated to create a user because of the FK. So, if you call the user_with_profile recipe as you're suggesting, baker will:

  • Create 2 new Profile objects and 2 new User objects one for each;
  • Create 2 new User objects and associate them with the existing profiles;
  • The 2 Users previously created will stay in the DB but as "without profiles users";

This is one of the problems of using Recipes combined with related name to create objects. I'm not so sure if it's possible to fix this though, since the usage of foreign_key method was designed to respect the foreign key direction and not be used with related names.

@berinhard
Copy link
Member

berinhard commented Jun 14, 2021

I don't know, maybe we're missing some type of dependency inversion here to make the tests easier and more semantics. I don't know, something like:

# baker_recipes.py

profile = Recipe("yourapp.profile")

user_with_profile = from_recipe_fk('profile', 'user', username='foo')

This method would output a special type of recipe that depends on a previous one to work. So it'll:

  • Create the Profile recipe and, by doing so, create the User instance;
  • It should use its kwargs to create the User instance (as the username one in the example above);
  • Instead of returning the Profile, it should return the profile.user object;

@amureki or @anapaulagomes what do you think about this?

@berinhard
Copy link
Member

I'm closing this issue since the same problem was already documented in #97.

@egorgam
Copy link

egorgam commented Sep 22, 2023

actual at version 1.15.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants