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

Problem calling global methods(?) #416

Closed
joliss opened this issue Jul 26, 2012 · 3 comments
Closed

Problem calling global methods(?) #416

joliss opened this issue Jul 26, 2012 · 3 comments

Comments

@joliss
Copy link

joliss commented Jul 26, 2012

To get FG working with Spork, I added require: false in Gemfile and put

Spork.each_run do
  require 'factory_girl_rails'
end

So far so good. But now that FG is getting loaded later, the following does not work any more:

FactoryGirl.define do
  factory :foo do
    count Forgery(:basic).number
  end
end

It throws

/.../factories/foo.rb:3:in `block (2 levels) in <top (required)>': undefined method `number' for #<FactoryGirl::Declaration::Static:0x00000004687f00> (NoMethodError)

Apparently Forgery is a method and is overloaded as a class.

But the following works fine:

FactoryGirl.define do
  factory :foo do
    count Forgery::Basic.number
  end
end

So I have a workaround, and I know I'm not supposed to use Forgery with FG.

That said, I know there is some magic going on in factory definitions, and I'd be curious, is there anything going wrong that stops global methods from being called? Can I fix it somehow?

@joshuaclayton
Copy link
Contributor

Assuming Forgery (the method) is defined on object, I think you could do: Object.Forgery(:whatever).

That said, you should just be able to pass count a block and both should work:

FactoryGirl.define do
  factory :installment_billing do
    count { Forgery(:basic).number }
  end
end

Any reason for not just assigning it explicitly?

@joliss
Copy link
Author

joliss commented Jul 26, 2012

Hey, thanks for the quick reply!

The block thing crashes with the same (IIRC) "undefined method" error as above, though at run-time, not at load-time.

Object.Forgery doesn't work either, it says private method called.

[3] pry(main)> method :Forgery
=> #<Method: Object#Forgery>
[4] pry(main)> Forgery
=> Forgery
[6] pry(main)> Object.Forgery
NoMethodError: private method `Forgery' called for Object:Class
from (pry):6:in `<main>'
[5] pry(main)> Object.new.Forgery
NoMethodError: private method `Forgery' called for #<Object:0x00000005246918>
from (pry):5:in `<main>'

Any reason for not just assigning it explicitly?

Yes, I just ended up yanking all the forgery calls from the factories, as they had to go anyway. The reason I posted this is more that I'm worried that something's fundamentally going wrong with the delayed loading, since it worked fine before (without require: false). Any ideas at all?

@joshuaclayton
Copy link
Contributor

@joliss nothing jumps out at me, to be honest. In FactoryGirl::DefinitionProxy (the class that handles processing of all the attributes as they're declared in a factory :whatever block), we undefine a bunch of methods in order to avoid having attribute names collide with methods on Object and Kernel. This tends to cause the most surprises, so it's weird that require: false would be doing so much. I'm going to close the ticket for now, since you're not using Forgery anymore, but reopen it if you're dead set on using it again and want to try to get it working!

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

2 participants