Help: rails magic fallout

Hi all,

I've just wasted a day fixing an issue that IMO shouldn't be one. I've got a workaround, but it smells as there's more, and I would greatly appreciate pointers what to watch out for.

The issue: I've got a model, and it had a method 'all_noload'. It's homebrew, i.e. doesnt' derive from ActiveRecord::Base. all_noload simply enumerated a directory and made model objects of it.

Now in production, it didn't work any more. Instead on an array, I got . But not in development or test, i.e. it worked fine in them. Even the precise code of all_noload, in the rails console, worked fine in all environments.

The 'fix' is to rename the method. Apparently it is related to ActiveRecord initialization, since production was suddenly fine when I removed the DB defintion (which of course didn't get me far).

So, I suspect some rails magic is applied here with overly optimistic assumptions.

So, is there a semi-official list of forbidden names in models or something?

Cheers,

Simon

Hi all,

I've just wasted a day fixing an issue that IMO shouldn't be one. I've got a workaround, but it smells as there's more, and I would greatly appreciate pointers what to watch out for.

The issue: I've got a model, and it had a method 'all_noload'. It's homebrew, i.e. doesnt' derive from ActiveRecord::Base. all_noload simply enumerated a directory and made model objects of it.

Now in production, it didn't work any more. Instead on an array, I got . But not in development or test, i.e. it worked fine in them. Even the precise code of all_noload, in the rails console, worked fine in all environments.

The 'fix' is to rename the method. Apparently it is related to ActiveRecord initialization,

This makes no sense since you just said your model "doesnt' derive from ActiveRecord::Base" above.

So, I suspect some rails magic is applied here with overly optimistic assumptions.

If you use Rails you have to deal with it's chosen name spaces. Why would you think it'd be any other way?

So, is there a semi-official list of forbidden names in models or something?

You can easily check what's already there before making your own class or method:

ObjectSpace.const_defined?( 'Foo' )

ActiveRecord::Base.respond_to?( 'all_noload' )

@Simon:

Hey, namespace collisions can be troubling, but I'm confused. You said you made a method on a non-activerecord model but then you said it worked once you removed the db definition.

What was the name of your model, and did you define a class method or an instance method? Did you have other plugins installed?

Before you go too much farther, make a brand new Rails app and duplicate the behavior there. If you can reproduce it, then it's either something with names or something goofy in your code. Can you write a test that reproduces that behavior?

Also can you tell us more about your production environment? You said it works in all environments through the console, so now I wonder if you're running it through apache and trying to enumerate a dir that the user has no access to on the file system.

Tell us more.

Hey, namespace collisions can be troubling, but I'm confused. You said you made a method on a non-activerecord model but then you said it worked once you removed the db definition.

Yes, exactly. That's the irony. The only way to get it working _in production_ (or test, as I discovered now) is to have no DB definition. Even though I don't derive from activerecord. That's rails 2.2.2, on 2 different machines so far. I've got a gem in, authlogic. By 'in production', I mean either: RAILS_ENV=production script/console Or the same with server (thin), getting no listing in html

What was the name of your model, and did you define a class method or an instance method? Did you have other plugins installed?

It's a class method. Named all_noload, it returns . I suspect it doesn't get called at all (I issued a print). Named 'humptydumpty', it works fine, as it does in development or test. Textually, both are the same except the name behind def.

Before you go too much farther, make a brand new Rails app and duplicate the behavior there. If you can reproduce it, then it's either something with names or something goofy in your code. Can you write a test that reproduces that behavior?

Unfortunately, no. I couldn't reproduce in a brand new app .

Also can you tell us more about your production environment? You said it works in all environments through the console, so now I wonder if

No, that's not what I meant. Console is in line with the running instance, i.e. it works or not depending on environment. I tried to see if it's a function of the DB backend (prod uses mysql, dev is sqlite), but no luck.

you're running it through apache and trying to enumerate a dir that the user has no access to on the file system.

That's what I thought too, but the humtydumpty test shows it's a names problem.

Are there known-good ways to deal with this class of problems? Greg's suggestion is fine but didn't get me far, especially since I don't derive from ActiveRecord::Base.

For now, all_kingkong works, but I'd feel safer knowing what is going on.

Clarification:

It's a class method. Named all_noload, it returns . I suspect it doesn't get called at all (I issued a print). Named 'humptydumpty', it works fine, as it does in development or test. Textually, both are the same except the name behind def.

It doesn't work in test (as all_noload), and I'm unsure it ever did. Unfortunate, but I edited all over the place, no reliable recovery since my svn wasn't available.