Rails 2 and associations-slash-loading

Been encountering several (seemingly) related issues with Rails 2. Was
hoping someone has run into these things and found a suitable solution:

  1. instance methods disappearing in view:

a. In the index action of ArticlesController, there is: @articles =
@user.articles.find(…)…
b. with which in index.html.erb, i call render :partial =>
‘articles/article’, :collection => @articles.
c. and the _article partial calls a method such as “article.published?”
which is defined in the model file and verified by unit tests.

Yet I will consistently get a NoMethodError on that #published? method
beginning with the second request to that page. Also, the elements in
that collection don’t seem to be of the class Article as expected.
Curiously, the page works as desired if in the controller I do @article
= Article.find(…, :conditions => [“user_id = ?”, @user.id]). And
since this is a development only issue, it led to the notion that it was
load-unload-reload issue related, as described in
http://dev.rubyonrails.org/ticket/6720.

  1. At about the same time there was the issue of “[modulename] has been
    removed from the module tree but is still active!” Both of these issues
    finally went away when i explicitly required all the library files
    within development.rb (originally had them required in the initializer
    directory).

  2. Now, on a new model called “Blog”, I’m discovering that calling
    @blogs = @user.blogs.find(…) in the controller, and calling
    blog.id on an element in that collection gives me a “SystemStackError:
    stack level too deep” on second request and onward, and it also goes
    away if I set @blogs = Blog.find(… :conditions => [“user_id = ?”,
    @user.id]).

So I’m seeing different but seemingly related issues on development
environment which I can step around but would rather not because it’s
simply not working as I expect them to. Wondering if these nuances in my
app could be the issue:

  • requiring and including libraries within the lib/ directory from a
    file in initializers.rb instead of an environment file
  • having modules in lib/ that reference models in app/models
  • defining user associations in a separate file user_associations.rb
    which is called by require_dependency before the User class is opened in
    user.rb

Any thoughts would be appreciated. Thanks in advance!
(Rails 2.0.2 on Leopard, Ruby 1.8.6)

Typically this happens when you confuse the dependency system in
rails. This powers the magic reloading of classes in development mode,
but when it goes wrong you get things holding on references to the
classes before they were reloaded.

One thing that is sure to lead to chaos if is you have a file that is
not reloaded every request that holds onto a reference to a class that
is reloaded every request. I can’t remember if lib is in
Dependencies.load_once_paths, but if so having modules in lib that
reference models could easily be the cause of your pain. Removing lib
from Dependencies.load_once_paths would probably to the trick.

It’s also possible to confuse things by requiring things that rails
could have loaded automatically. using require_dependency ensures that
all of rails’ dependency stuff is kept happy (this only requires to
things in your app, not standard libraries, gems etc…)

Fred

Thanks Fred, for the speedy response.

I had tried moving all libraries into the models folder to see if it’d
help before, and it did not help then. After hearing your helpful
points, I tried many different things including renaming requires to
require_dependencies (for my custom libraries), moving lib files into
model/, (lib is in the auto-reloaded path it seems, and not in the
load_once_paths), explicitly declaring the load_once_paths to be an
empty array…

A bit resigned to turning on class caching for development to get on
with the coding instead of dwelling on this at this point. But if it’s
not ideal to have libraries in lib/ that reference models, what is
supposed to be the best practice for creating shared functionality among
models where a separate model needs to be referenced (i.e.
acts_as_taggable, where both Tag and Tagging are necessarily referenced
within the module)?