Help: rails magic fallout


#1

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


#2

On Thu, Mar 12, 2009 at 4:28 PM, simon removed_email_address@domain.invalid wrote:

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’ )


Greg D.
http://destiney.com/


#3

@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.


#4

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.


#5

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.