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

"Class" loaded more than once? #1639

Open
stevenou opened this issue Jul 2, 2024 · 4 comments
Open

"Class" loaded more than once? #1639

stevenou opened this issue Jul 2, 2024 · 4 comments

Comments

@stevenou
Copy link

stevenou commented Jul 2, 2024

Description

Changes introduced in #1610 are causing "the class" to load more than once. Specifically, the change to namespace.set(name, Class.new(parent)).

I encountered this because searchkick now raises RuntimeError: Only call searchkick once per model. I am running searchkick inside def inherited(subclass) and the changes are causing that to run again, thus raising an error.

Reproduction Steps

Not too sure what reproduction steps are relevant. At this point I don't understand the issue well enough to even know if it should be considered a bug or not.

Expected behavior

"The class" isn't loaded more than once during testing. This is the behavior in version <= 6.1.0.

Actual behavior

In version 6.2.0, the code inside def inherited(subclass) runs more than once for the "same" class, presumably because there is now another anonymous class that inherits from it.

System configuration

shoulda_matchers version: 6.2.0
rails version: 7.1.3.4
ruby version: 3.3.0

@myupchar
Copy link

Did you figure out a solution for this? Ran into same problem while upgrading

@stevenou
Copy link
Author

Did you figure out a solution for this? Ran into same problem while upgrading

No, I did not figure out a solution. Currently locked to version 6.1.0...

@matsales28
Copy link
Member

Hi, @stevenou and @myupchar

Apologies for the delay in responding—things have been quite busy on my end.

It seems the behaviour arises from the inherited method. While this is expected when using Class.new(parent), you can mitigate the issue by modifying the inherited method in your parent class with a guard clause. Here's an example:

def inherited(subclass)
  # Skip if the subclass is anonymous (i.e., has no name)
  return if subclass.name.nil?

  # Alternatively, prevent duplicate processing with a safeguard
  @processed_subclasses ||= Set.new
  return if @processed_subclasses.include?(subclass.object_id)

  @processed_subclasses.add(subclass.object_id)

  # Your existing inherited logic here
  super
end

Do you think that would work for your case?

@stevenou
Copy link
Author

@matsales28 thanks for the suggestion. this worked for me.

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

No branches or pull requests

3 participants