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

[WIP] Adding a new belongs_to association [for factories. #950

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jwoertink
Copy link
Member

Fixes #385

This PR adds in a new belongs_to association macro for Factory that allows you to association another model and build on demand.

class ProductFactory < Avram::Factory
  belongs_to store : StoreFactory

  def initialize
    title "Cool Thing"
    create_store(&.name("Example Store"))
  end
end

# You can use it many different ways

product = ProductFactory.create
product.store.name == "Example Store"

product = ProductFactory.create(&.create_store(&.name("Different Store")))
product.store.name == "Different Store"

store = StoreFactory.create(&.name("Evil Store"))
product = ProductFactory.create &.store(store)
product.store_id == store.id

One weird thing I ran in to is naming order with requires, but I think that's just a Crystal thing...

For example, with a require "./factories/**", doing this will throw a undefined constant PostFactory because in alphabetical order, "PostFactory" comes after "CommentFactory", so the file hasn't been loaded. You'd just need to do an extra require "./post_factory" at the top if that's the case...

class CommentFactory < BaseFactory
  belongs_to post : PostFactory
end

def {{ type_declaration.var }}(%m : {{ type_declaration.type.stringify.gsub(/Factory$/, "").id }})
{{ type_declaration.var }}_id(%m.id)
end
def create_{{ type_declaration.var }}(&blk : {{ type_declaration.type }} ->)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this allow calling the method without a block? I'm not sure it does

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooo, good call. I'll add that in.

@jwoertink jwoertink changed the title Adding a new belongs_to association for factories. [WIP] Adding a new belongs_to association [for factories. Jun 28, 2023
@jwoertink
Copy link
Member Author

Putting this in WIP... Just ran in to an issue that I'm not sure how to handle yet.. If your Factory has create_thing(&.some_default) set in the initializer, and you want to override that, it's currently not working.

class CommentFactory < Avram::Factory
  belongs_to post : PostFactory

  def initialize
    body("Test Comment")
    create_post(&.title("Test Post"))
  end
end

# the post title will be "Test Post" here...
TempCommentFactory.create(&.create_post(&.title("A new post")))

This is because it chains the before_saves, and runs the first one, then doesn't run the second because the value has already been set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make it easier to set default associations in a Factory
2 participants