Solved

`load_missing_constant': uninitialized constant Rails::Generator (NameError)

Posted on 2009-05-15
8
1,262 Views
Last Modified: 2013-11-13
Hello,
    I'm probably missing something pretty basic here as a rails newbie but I'm trying to write a plugin and I am trying to get my generator to work.

I am trying to call the manifest method in my vendor/plugins/media_module/generators/media_module_generator.rb from my vendor/plugins/media_module/init.rb.

here's the code in vendor/plugins/media_module/init.rb:
[code]
require File.join(File.dirname(__FILE__), '/generators/media_module_generator')
media_mod_generatore = MediaModuleGenerator.new
media_mod_generatore::manifest()
[/code]

and here's my code in vendor/plugins/media_module/generators/media_module_generator.rb:
[code]
class MediaModuleGenerator < Rails::Generator::NamedBase
  def manifest
    record do |m|
      m.file "media_controller.rb", "app/controllers/media_controller.rb"
      m.file "media.rb", "app/models/media.rb"
    end
  end
end
[/code]

When I restart my server I get this:
`load_missing_constant': uninitialized constant Rails::Generator (NameError)

Thanks,
Clem C
0
Comment
Question by:clemcrock
  • 4
  • 3
8 Comments
 
LVL 12

Expert Comment

by:cminear
ID: 24442753
I have never created a Rails plugin myself, but looking at the error, the obvious thought that comes to me is that nothing has imported 'rails_generator', so the ruby environment does not know about the Rails::Generator class (much less Rails::Generator::NamedBase).  

If you look at the 'script/generate' script, it requires 'commands/generate'.  You then look at lib/commands/generate.rb (wherever your rails gem is installed) and it requires 'rails_generator'.

Try adding the line:
  require 'rails_generator'
at the top of vendor/plugins/media_module/generators/media_module_generator.rb.  I would put it in that file because that is where it is needed.

The next issue may be whether you really want the generator to run _every_ time you start your server.  That may not be the behavior you want, or you've already considered that and your generator accounts for it.  (As I said, I've never created a plugin, so I'm not an expert on that.)
0
 

Author Comment

by:clemcrock
ID: 24456679
Thanks a lot for the help.    For development purposes, I wanted the generator to run everytime I restarted the server.   I realize this is not very necessary but I am more interested in making this work just for pure knowledge sake.     I required the rails_generator a the top of media_module_generator.rb and now when I restart the server, I get this:

media_module/init.rb:35:in `initialize': wrong number of arguments (0 for 1) (ArgumentError)

I'm not understanding this too well as I didn't think a class of Rails::Generator::Base took arguments.

Thanks again.
0
 
LVL 12

Expert Comment

by:cminear
ID: 24473590
It's not that Rails::Generator::Base takes arguments (it's a class), but that the 'new' class method does.  So does Rails:::Generator::NamedBase's 'new' class method.  Both of them accept 'runtime_args' and 'runtime_options'; the 'runtime_options' defaults to an empty hash.  But it would appear the 'runtime_args' variable needs to be specified.  

When you run the Rails-provied 'script/generate', it ultimately passes in ARGV to the invocation of the 'new' method.  However, when you have this statement in 'init.rb':
   media_mod_generatore = MediaModuleGenerator.new
You aren't passing in anything.  Thus, you get the error about the "wrong number of arguments".

You have two options.  Pass in an array of arguments that you'd like your generator to be able to handle, or create your own 'new' class method for MediaModuleGenerator which will override the 'new' method provided by the parent.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:clemcrock
ID: 24507745
I got past that point by doing exactly like you expected as you can see here:

[code]
media_module = MediaModuleGenerator.new({})
media_module.manifest
[/code]

I got past this sticking point and now I'm getting this problem:

When I run my generator, I get this error:

You have a nil object when you didn't expect it! (NoMethodError) The error occurred while evaluating nil.path

Here's my code:
class Base
  include Options
  class_inheritable_accessor :spec

  def initialize(runtime_args, runtime_options = {})
    @args = runtime_args
    parse!(@args, runtime_options)
 
    # Derive source and destination paths.
    @source_root = options[:source] || File.join(spec.path, 'templates')
  end
end

class MediaModuleGenerator < Rails::Generator::Base
  def initialize(runtime_args, runtime_options = {})
     self.spec.path = File.dirname(__FILE__) + '/generators/media_module'    
     super
  end
end
[/code]

So when I set the self.spec.path var to  File.dirname(__FILE__) + '/generators/media_module', it's not registering in the base class.

Thanks again for your help
0
 
LVL 12

Accepted Solution

by:
cminear earned 500 total points
ID: 24518020
I think I see the problem, but it would be nice if you also said which specific line the error occurred on.  I believe it's hiccupping on:
   self.spec.path = File.dirname(__FILE__) + '/generators/media_module'    
but I could also see it having a problem with:
   @source_root = options[:source] || File.join(spec.path, 'templates')

Just to be clear, is the 'class Base' your code or are you just copying that above from the 'rails_generator/base.rb' file from the Rails gem code?  (If it's your code, then that could be the problem, but I'll assume you copied it into your response.)

With the first possible issue, the problem is likely just as it said: self.spec has not been defined yet, so it considers it to be nil.  Nil does not understand the 'path' method, and thus you get the NoMethodError.  However, even if 'self.spec' were set to be a Rails::Generator::Spec, looking at that code, the 'path' variable is only set to be a reader, so any attempt to set it would probably throw a different error.

To be honest, I am not immediately discerning how the Spec is created for the Rails::Generator::Base object.  But my guess is that it gets set as part of being called as a command.

Do you have a 'media_module_generator' script, yet, similar to what Rails provides in the 'script' directory?  If you do not, I'd recommend creating it.  Then, instead of trying to deal with the MediaModuleGenerator from within a Ruby/Rails program file, start it similar to how a user would.  
   system("location/to/script/media_module_generator")
You could probably put this line somewhere in config/boot.rb file so that it would be run every time you start the Rails application (which is what you said you want).
0
 

Author Comment

by:clemcrock
ID: 24523523
Thanks for your help.   You are correct that the base class is coming from the rails_generator/base.rb module.  I do like the idea of putting the code in the config/boot file but I really would like to learn if it's possible to set a base class attribute from an overridden function in a subclass?    I can't seem to find any information or examples on how to do this.

I do have a media_module_generator.rb set and I can call it from the command line and it works perfectly.   This problem has turned into a lesson in ruby class inheritance.

Again - very grateful for your help



0
 

Author Comment

by:clemcrock
ID: 24563596
Thanks for your help.   You are correct that the base class is coming from the rails_generator/base.rb module.  I do like the idea of putting the code in the config/boot file but I really would like to learn if it's possible to set a base class attribute from an overridden function in a subclass?    I can't seem to find any information or examples on how to do this.

I do have a media_module_generator.rb set and I can call it from the command line and it works perfectly.   This problem has turned into a lesson in ruby class inheritance.

Again - very grateful for your help
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

In Ruby, Call or invoke a API DLL library is easily via Win32API class, win32-api gem or other gems. For general DLL API call, there are quite a few references, some good tips list below: http://www.rubytips.org/2008/05/13/accessing-windows-api-fro…
Recently I spent hours debugging an issue in a Rails project where ActiveRecord was causing MySQL errors trying to create a User object of a class at the top level of a Single Table Inheritance model structure.  It turns out `.create` behaves differ…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now