Getting class in /lib folder to see a model (const_missing)?

Hello,

I wrote a new class that I decided to put in the /app/lib folder. Part
way through one of the methods, I call #new on the model, update some of
the fields and then call #save (on the model).

When I do this though, I get a 'const_missing' error coming from Active
Support. Here's the error:

"......./lib/active_support/dependencies.rb:105:in `const_missing':
uninitialized constant ClassA::ModelA (NameError)"

The 'ModelA' is the model I'm trying to access, and 'ClassA' is the
class in /app/lib/class_a.rb. I'm not sure why it seems to think that
ModelA is a part of ClassA, perhaps that's the problem?

I would have probably just used "require ../models/model_a.rb", but I
found the following at StackOverflow:

"One way to solve this would be to explicitly require the model file
aircraft.rb. However, you will find this approach quickly leads to
insanity as it will break the Rails auto-loader in subtle and
astonishing ways. Rails is much easier if you work with the Rails class
loader, not against it."

Source:
http://stackoverflow.com/questions/326277/rails-calling-a-model-class-in-a-library

I then found an example at
http://www.strictlyuntyped.com/2008/06/rails-where-to-put-other-files.html
that suggests adding this to the file in the /app/lib folder:

  def self.included(base)
     base.extend(ClassMethods)
  end

And then creating a file in /config/initializers with the following:

  require 'rails_extensions/user_logger'

  ActionController::Base.class_eval do
    include ActionController::UserLogger
  end

Being new to Ruby/Rails, I'm really not sure what this supposed to do,
but I'm guessing it will work. That post was written in 2008 though, so
I'm thinking there may be a better way for this.

Does anyone have a suggestion as to the best way to get a class in the
/app/lib folder to see a model?

Thank you very much,
Mike

That can indeed happen (the thing that breaks is usually the code
reloading in development mode).
Does the rest of your app pick up this model automatically. How/where
is this class in /lib being used ?

Fred

Frederick Cheung wrote:

I would have probably just used "require ../models/model_a.rb", but I
found the following at StackOverflow:

"One way to solve this would be to explicitly require the model file
aircraft.rb. However, you will find this approach quickly leads to
insanity as it will break the Rails auto-loader in subtle and
astonishing ways. Rails is much easier if you work with the Rails class
loader, not against it."

That can indeed happen (the thing that breaks is usually the code
reloading in development mode).
Does the rest of your app pick up this model automatically. How/where
is this class in /lib being used ?

Fred

Hi Fred,

Thanks for your response. The other parts of the app (i.e. the
controllers) do seem to pick up this model. The class in the /lib folder
is being used separately. I'm currently running it manually, but I'm
looking into running it automatically using a cron job or something
similar later on.

So, it's not included by another file at the moment, as it's meant to
run as a standalone script. (I'm guessing that may have fixed the
problem if that file already had access to the model.)

Thanks,
Mike

Thanks for your response. The other parts of the app (i.e. the
controllers) do seem to pick up this model. The class in the /lib folder
is being used separately. I'm currently running it manually, but I'm
looking into running it automatically using a cron job or something
similar later on.

So, it's not included by another file at the moment, as it's meant to
run as a standalone script. (I'm guessing that may have fixed the
problem if that file already had access to the model.)

What does running it manually mean - is the rails environment loaded ?
If it isn't then you have your answer (since one of the things that
gets you is rails' magic file loader)

Fred

Shouldn't it be in

{Rails.root}/lib/class_a.rb

rather than

{Rails.root}/app/lib/class_a.rb

???

Frederick Cheung wrote:

Thanks for your response. The other parts of the app (i.e. the
controllers) do seem to pick up this model. The class in the /lib folder
is being used separately. I'm currently running it manually, but I'm
looking into running it automatically using �a cron job or something
similar later on.

So, it's not included by another file at the moment, as it's meant to
run as a standalone script. (I'm guessing that may have fixed the
problem if that file already had access to the model.)

What does running it manually mean - is the rails environment loaded ?
If it isn't then you have your answer (since one of the things that
gets you is rails' magic file loader)

Fred

Ah! That was the problem, thank you! I've been running it using:

$ ruby app/lib/class_a.rb

(The file has a call to "run()" outside of the class methods, which
calls ClassA::run.)

But by running the script using the line below, the Rails environment is
loaded properly and the script works fine. :slight_smile:

$ script/runner app/lib/class_a.rb

I'm still kinda new to Rails, so I didn't know that I'd need to do that,
but it makes total sense!

Shouldn't it be in

{Rails.root}/lib/class_a.rb

rather than

{Rails.root}/app/lib/class_a.rb

???

--
Rick DeNatale

By '{Rails.root}', do you mean the app's root directory, or the Rails
root directory?

Anyway, I put it in {AppRoot}/app/lib because, for some reason, I
thought that the {AppRoot}/lib folder was for external libraries (i.e.
the ones I didn't write). I like it this way anyway because things are
separated better, in my opinion. I know that the stuff in the /app
directory are the things that I made, and I don't really need to visit
the {AppRoot}/lib folder unless there's something in there that I want
to modify.

Or is this against Rails' best practices?

Thanks again,
Mike