Expected to define. When calling class inside a mo

2020-02-09 01:37发布

问题:

I new to rails. I have a setup in the lib directory like so:

lib/
   blog/
     core/
        search/
            base.rb

The base.rb defines the Base class as well:

module Blog
  module Core
    module Search
      class Base

        attr_accessor :properties

        def initialize(params)
          @properties = {}
        end
      end
    end
  end
end

I have the following code in my application.rb

config.autoload_paths += Dir["#{config.root}/lib/**/"]

When I include it in posts controller I get following errors:

LoadError in PostsController#index

Expected /home/usr/code/blog/lib/blog/core/search/base.rb to define Base

Any idea? I'm using rails 3.2.5 with RVM. Thank you for every advice.

UPDATED: Added my full stack:

Started GET "/admin/posts" for 127.0.0.1 at 2012-06-08 21:06:18 +0800

LoadError (Expected /home/usr/code/blog/lib/blog/core/search/base.rb to define Base):
  app/controllers/admin/base_controller.rb:5:in `<top (required)>'
  app/controllers/admin/posts_controller.rb:6:in `<top (required)>'


  Rendered /home/usr/.rvm/gems/ruby-1.9.3-p194@rails-3.2.5/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.9ms)
  Rendered /home/usr/.rvm/gems/ruby-1.9.3-p194@rails-3.2.5/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.6ms)
  Rendered /home/usr/.rvm/gems/ruby-1.9.3-p194@rails-3.2.5/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (7.0ms)

回答1:

I had the same problem. It comes from the fact that you try to load /lib/blog/core/search/base.rb directly in application.rb with /lib/**/

Error I had:

Expected /[...]/myapp/lib/durative/base.rb to define Base (LoadError)

Directory structure:

lib/
 --durative/
   --base.rb

base.rb:

module Durative
  class Base
    def initialize(config)
       @config = {}
    end
    #...
  end
end

application.rb:

config.autoload_paths += Dir["#{config.root}/lib/**/"]

Here are the changes I made to make it work

Directory structure:

lib/
 --durative.rb **(added)**
 --durative/
   --base.rb

durative.rb:

require 'durative/base'

base.rb (no change)

application.rb (changed):

config.autoload_paths += Dir["#{config.root}/lib/"]

Tell us if it worked for you too.



回答2:

I had the same issue. The problem was because I was including subdirs without including their parent lib dir:

# did not work
config.autoload_paths += %W(#{config.root}/lib/foo)

and

# in lib/foo/my_class.rb
module Foo
  class MyClass
  end
end

Foo::MyClass would return Expected to define MyClass

adding the lib dir to config.autoload_paths fixes the problem

# worked
config.autoload_paths += %W(#{config.root}/lib #{config.root}/lib/foo)


回答3:

Just add: require base.rb in your environment.rb file.

source: http://icebergist.com/posts/expected-xrb-to-define-x-loaderror



回答4:

Also, one thing to check is that your controller is named appropriately.

For instance, make sure that your posts_controller.rb looks like this on the first line

class PostsController < ApplicationController

I have made mistakes where I copied a controller and tracked it down to not changing the controller classes name



回答5:

If you have that deeply hidden class then access it this way:

Blog::Core::Search::Base.new 'foo'


回答6:

My error with this was that I had

app/
  controllers/
      projects/
          some_controller.rb
      projects_controller.rb

I was trying to keep my app organized and, when having a namespace - was splitting up the controller. Unfortunately it looks like Rails would randomly jump between the two and there would be conflicts causing the error in OP.

Solution: Rename your sub-directory and adjust any routes.